diff -u -r metacity/src/keybindings.c metacity-work-051004/src/keybindings.c
--- metacity/src/keybindings.c	2005-10-03 16:05:44.000000000 -0400
+++ metacity-work-051004/src/keybindings.c	2005-10-04 09:44:33.000000000 -0400
@@ -193,6 +193,21 @@
                                        MetaWindow     *window,
                                        XEvent         *event,
                                        MetaKeyBinding *binding);
+static void handle_maximize_fill       (MetaDisplay    *display,
+                                       MetaScreen     *screen,
+                                       MetaWindow     *window,
+                                       XEvent         *event,
+                                       MetaKeyBinding *binding);
+static void handle_maximize_vert_fill  (MetaDisplay    *display,
+                                       MetaScreen     *screen,
+                                       MetaWindow     *window,
+                                       XEvent         *event,
+                                       MetaKeyBinding *binding);
+static void handle_maximize_horiz_fill (MetaDisplay    *display,
+                                       MetaScreen     *screen,
+                                       MetaWindow     *window,
+                                       XEvent         *event,
+                                       MetaKeyBinding *binding);
 
 /* debug */
 static gboolean process_keyboard_move_grab (MetaDisplay *display,
@@ -415,6 +430,9 @@
   { META_KEYBINDING_LOWER, handle_lower, NULL},
   { META_KEYBINDING_MAXIMIZE_VERTICALLY, handle_maximize_vert, NULL },
   { META_KEYBINDING_MAXIMIZE_HORIZONTALLY, handle_maximize_horiz, NULL },
+  { META_KEYBINDING_MAXIMIZE_FILL, handle_maximize_fill, NULL },
+  { META_KEYBINDING_MAXIMIZE_VERTICALLY_FILL, handle_maximize_vert_fill, NULL },
+  { META_KEYBINDING_MAXIMIZE_HORIZONTALLY_FILL, handle_maximize_horiz_fill, NULL },
   { NULL, NULL, NULL }
 };
 
@@ -2784,7 +2802,7 @@
   if (window)
     {
       if (window->has_resize_func)
-        meta_window_fill_vertical (window);
+        meta_window_maximize_vertical (window);
     }
 }
 
@@ -2798,6 +2816,49 @@
   if (window)
     {
       if (window->has_resize_func)
+        meta_window_maximize_horizontal (window);
+    }
+}
+
+static void
+handle_maximize_fill (MetaDisplay    *display,
+                       MetaScreen     *screen,
+                       MetaWindow     *window,
+                       XEvent         *event,
+                       MetaKeyBinding *binding)
+{
+  if (window)
+    {
+      if (window->has_resize_func)
+      	{
+	        meta_window_fill_horizontal (window);
+	        meta_window_fill_vertical (window);
+	      }
+    }
+}
+static void
+handle_maximize_vert_fill (MetaDisplay    *display,
+                       MetaScreen     *screen,
+                       MetaWindow     *window,
+                       XEvent         *event,
+                       MetaKeyBinding *binding)
+{
+  if (window)
+    {
+      if (window->has_resize_func)
+        meta_window_fill_vertical (window);
+    }
+}
+static void
+handle_maximize_horiz_fill (MetaDisplay    *display,
+                       MetaScreen     *screen,
+                       MetaWindow     *window,
+                       XEvent         *event,
+                       MetaKeyBinding *binding)
+{
+  if (window)
+    {
+      if (window->has_resize_func)
         meta_window_fill_horizontal (window);
     }
 }
diff -u -r metacity/src/metacity.schemas.in metacity-work-051004/src/metacity.schemas.in
--- metacity/src/metacity.schemas.in	2005-10-03 16:10:56.000000000 -0400
+++ metacity-work-051004/src/metacity.schemas.in	2005-10-04 09:44:33.000000000 -0400
@@ -1038,6 +1038,75 @@
          </long>
       </locale>
     </schema>
+    
+    <schema>
+      <key>/schemas/apps/metacity/window_keybindings/maximize_fill</key>
+      <applyto>/apps/metacity/window_keybindings/maximize_fill</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <!-- no default for this one -->
+      <locale name="C">
+         <short>Maximize window to fill</short>
+         <long>
+            This keybinding resizes a window to fill, avoiding other windows.
+
+            The format looks like "&lt;Control&gt;a" or
+            "&lt;Shift&gt;&lt;Alt&gt;F1".
+
+            The parser is fairly liberal and allows lower or upper case,
+            and also abbreviations such as "&lt;Ctl&gt;" and
+            "&lt;Ctrl&gt;". If you set the option to the special string
+            "disabled", then there will be no keybinding for this
+            action.
+         </long>
+      </locale>
+    </schema>
+    
+    <schema>
+      <key>/schemas/apps/metacity/window_keybindings/maximize_vertically_fill</key>
+      <applyto>/apps/metacity/window_keybindings/maximize_vertically_fill</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <!-- no default for this one -->
+      <locale name="C">
+         <short>Maximize window vertically to fill</short>
+         <long>
+            This keybinding resizes a window to fill available vertical space, avoiding other windows.
+
+            The format looks like "&lt;Control&gt;a" or
+            "&lt;Shift&gt;&lt;Alt&gt;F1".
+
+            The parser is fairly liberal and allows lower or upper case,
+            and also abbreviations such as "&lt;Ctl&gt;" and
+            "&lt;Ctrl&gt;". If you set the option to the special string
+            "disabled", then there will be no keybinding for this
+            action.
+         </long>
+      </locale>
+    </schema>
+    
+    <schema>
+      <key>/schemas/apps/metacity/window_keybindings/maximize_horizontally_fill</key>
+      <applyto>/apps/metacity/window_keybindings/maximize_horizontally_fill</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <!-- no default for this one -->
+      <locale name="C">
+         <short>Maximize window horizontally to fill</short>
+         <long>
+            This keybinding resizes a window to fill available horizontal space, avoiding other windows.
+
+            The format looks like "&lt;Control&gt;a" or
+            "&lt;Shift&gt;&lt;Alt&gt;F1".
+
+            The parser is fairly liberal and allows lower or upper case,
+            and also abbreviations such as "&lt;Ctl&gt;" and
+            "&lt;Ctrl&gt;". If you set the option to the special string
+            "disabled", then there will be no keybinding for this
+            action.
+         </long>
+      </locale>
+    </schema>
 
     <!-- Global Keybindings -->
 
diff -u -r metacity/src/place.c metacity-work-051004/src/place.c
--- metacity/src/place.c	2005-09-02 11:54:34.000000000 -0400
+++ metacity-work-051004/src/place.c	2005-10-04 10:07:21.000000000 -0400
@@ -1121,20 +1121,24 @@
 static void
 get_vertical_edges (MetaWindow *window,
                     int       **edges_p,
-                    int        *n_edges_p)
+                    int        *n_edges_p,
+                    int		tops_only)
 {
   GSList *windows;
   GSList *tmp;
   int n_windows;
   GArray *edges;
-  int edge, i;
+  int edge, i, n_edges;
   MetaRectangle rect;
   MetaRectangle work_area;
   
   windows = get_windows_on_same_workspace (window, &n_windows);
-
-  edges = g_array_sized_new (FALSE, FALSE, sizeof (int), 
-                             n_windows * 2 + 4 /* 4 = workspace/screen edges */
+	if (tops_only == 0)
+		n_edges = n_windows * 2;
+	else
+		n_edges = n_windows;
+  edges = g_array_sized_new (FALSE, FALSE, sizeof (int), n_edges
+                              + 4 /* 4 = workspace/screen edges */
                              + window->screen->n_xinerama_infos - 1
                              + 2 /* active window edges when in wireframe mode */); 
 
@@ -1184,9 +1188,13 @@
       
       if (rects_overlap_vertically (&rect, &w_rect))
         {
-          g_array_append_val (edges, w_rect.x);
-          edge = w_rect.x + w_rect.width;
-          g_array_append_val (edges, edge);
+        	if (tops_only > -1)
+        		g_array_append_val (edges, w_rect.x);
+        	if (tops_only < 1)
+        	{
+	          edge = w_rect.x + w_rect.width;
+	          g_array_append_val (edges, edge);
+	        }
         }
 
       tmp = tmp->next;
@@ -1203,20 +1211,24 @@
 static void
 get_horizontal_edges (MetaWindow *window,
                       int       **edges_p,
-                      int        *n_edges_p)
+                      int        *n_edges_p,
+                      int					rights_only)
 {
   GSList *windows;
   GSList *tmp;
   int n_windows;
   GArray *edges;
-  int edge, i;
+  int edge, i, n_edges;
   MetaRectangle rect;
   MetaRectangle work_area;
   
   windows = get_windows_on_same_workspace (window, &n_windows);
-
+	if (rights_only == 0)
+		n_edges = n_windows * 2;
+	else
+		n_edges = n_windows;
   edges = g_array_sized_new (FALSE, FALSE, sizeof (int), 
-                             n_windows * 2 + 4 /* 4 = workspace/screen edges */
+                             n_edges + 4 /* 4 = workspace/screen edges */
                              + window->screen->n_xinerama_infos - 1
                              + 2 /* active window edges when in wireframe mode */); 
 
@@ -1265,9 +1277,13 @@
       
       if (rects_overlap_horizontally (&rect, &w_rect))
         {
-          g_array_append_val (edges, w_rect.y);
-          edge = w_rect.y + w_rect.height;
-          g_array_append_val (edges, edge);
+        	if (rights_only > -1)
+        		g_array_append_val (edges, w_rect.y);
+        	if (rights_only < 1)
+        	{
+	          edge = w_rect.y + w_rect.height;
+	          g_array_append_val (edges, edge);
+	        }
         }
 
       tmp = tmp->next;
@@ -1292,7 +1308,10 @@
   int n_edges;
   int retval;
 
-  get_vertical_edges (window, &edges, &n_edges);
+	if (right)
+	  get_vertical_edges (window, &edges, &n_edges, 1);
+	else
+		get_vertical_edges (window, &edges, &n_edges, -1);
 
   /* Find next */
   if (window->display->grab_wireframe_active)
@@ -1371,8 +1390,11 @@
   int i;
   int n_edges;
   int retval;
-
-  get_horizontal_edges (window, &edges, &n_edges);
+	
+	if (down)
+  	get_horizontal_edges (window, &edges, &n_edges, 1);
+  else
+  	get_horizontal_edges (window, &edges, &n_edges, -1);
   
   /* Find next */
   if (window->display->grab_wireframe_active)
@@ -1452,7 +1474,7 @@
   int n_positions;
   int retval;
   
-  get_vertical_edges (window, &edges, &n_edges);
+  get_vertical_edges (window, &edges, &n_edges, 0);
 
   /* Create an array of all snapped positions our window could have */
   n_positions = n_edges * 2;
@@ -1522,7 +1544,7 @@
   int n_positions;
   int retval;
   
-  get_horizontal_edges (window, &edges, &n_edges);
+  get_horizontal_edges (window, &edges, &n_edges, 0);
 
   /* Create an array of all snapped positions our window could have */
   n_positions = n_edges * 2;
diff -u -r metacity/src/prefs.c metacity-work-051004/src/prefs.c
--- metacity/src/prefs.c	2005-07-11 09:25:08.000000000 -0400
+++ metacity-work-051004/src/prefs.c	2005-10-04 09:44:33.000000000 -0400
@@ -1695,6 +1695,9 @@
   { META_KEYBINDING_LOWER, 0, 0, FALSE },
   { META_KEYBINDING_MAXIMIZE_VERTICALLY, 0, 0, FALSE },
   { META_KEYBINDING_MAXIMIZE_HORIZONTALLY, 0, 0, FALSE },
+  { META_KEYBINDING_MAXIMIZE_FILL, 0, 0, FALSE },
+  { META_KEYBINDING_MAXIMIZE_VERTICALLY_FILL, 0, 0, FALSE },
+  { META_KEYBINDING_MAXIMIZE_HORIZONTALLY_FILL, 0, 0, FALSE },
   { NULL, 0, 0, FALSE }
 };
 
diff -u -r metacity/src/prefs.h metacity-work-051004/src/prefs.h
--- metacity/src/prefs.h	2005-07-11 09:25:08.000000000 -0400
+++ metacity-work-051004/src/prefs.h	2005-10-04 09:44:33.000000000 -0400
@@ -194,6 +194,9 @@
 #define META_KEYBINDING_LOWER                    "lower"
 #define META_KEYBINDING_MAXIMIZE_VERTICALLY      "maximize_vertically"
 #define META_KEYBINDING_MAXIMIZE_HORIZONTALLY    "maximize_horizontally"
+#define META_KEYBINDING_MAXIMIZE_FILL      "maximize_fill"
+#define META_KEYBINDING_MAXIMIZE_HORIZONTALLY_FILL    "maximize_horizontally_fill"
+#define META_KEYBINDING_MAXIMIZE_VERTICALLY_FILL      "maximize_vertically_fill"
 
 typedef enum _MetaKeyBindingAction
 {
diff -u -r metacity/src/window.c metacity-work-051004/src/window.c
--- metacity/src/window.c	2005-10-03 16:02:31.000000000 -0400
+++ metacity-work-051004/src/window.c	2005-10-04 09:59:41.000000000 -0400
@@ -3013,7 +3013,7 @@
 }
 
 void
-meta_window_fill_horizontal (MetaWindow  *window)
+meta_window_maximize_horizontal (MetaWindow  *window)
 {
   MetaRectangle work_area;
   int x, y, w, h;
@@ -3041,7 +3041,7 @@
 }
 
 void
-meta_window_fill_vertical (MetaWindow  *window)
+meta_window_maximize_vertical (MetaWindow  *window)
 {
   MetaRectangle work_area;
   int x, y, w, h;
@@ -3068,6 +3068,63 @@
   check_maximize_to_work_area (window, &work_area);
 }
 
+void
+meta_window_fill_horizontal (MetaWindow  *window)
+{
+	/* Maximizes horizontally but avoids windows */
+  MetaRectangle work_area;
+  int x, y, w, h;
+  
+  meta_window_get_user_position (window, &x, &y);
+
+  h = window->rect.height;
+    
+  meta_window_get_work_area_current_xinerama (window, &work_area);    
+    
+  x = meta_window_find_next_vertical_edge(window, META_WINDOW_EDGE_LEFT, FALSE);
+  w = meta_window_find_next_vertical_edge(window, META_WINDOW_EDGE_RIGHT, TRUE) - x;
+  
+  if (window->frame != NULL)
+  {
+  	x += window->frame->child_x;
+    	w -= (window->frame->child_x + window->frame->right_width);
+  }
+    
+  meta_window_move_resize (window, TRUE,
+                           x, y, w, h);
+                           
+  check_maximize_to_work_area (window, &work_area);
+}
+
+void
+meta_window_fill_vertical (MetaWindow  *window)
+{
+	/* Maximizes vertically but avoids windows */
+  MetaRectangle work_area;
+  int x, y, w, h;
+  
+  meta_window_get_user_position (window, &x, &y);
+
+  w = window->rect.width;
+  h = window->rect.height;
+
+  meta_window_get_work_area_current_xinerama (window, &work_area);    
+  
+  y = meta_window_find_next_horizontal_edge(window, META_WINDOW_EDGE_TOP, FALSE);
+  h = meta_window_find_next_horizontal_edge(window, META_WINDOW_EDGE_BOTTOM, TRUE) - y;
+ 
+  if (window->frame != NULL)
+  {
+	y += window->frame->child_y;
+    h -= (window->frame->child_y + window->frame->bottom_height);
+  }
+
+  meta_window_move_resize (window, TRUE,
+                           x, y, w, h);
+
+  check_maximize_to_work_area (window, &work_area);
+}
+
 static guint move_resize_idle = 0;
 static GSList *move_resize_pending = NULL;
 
diff -u -r metacity/src/window.h metacity-work-051004/src/window.h
--- metacity/src/window.h	2005-10-03 16:02:31.000000000 -0400
+++ metacity-work-051004/src/window.h	2005-10-04 09:44:33.000000000 -0400
@@ -389,6 +389,8 @@
                                              int          gravity);
 
 
+void        meta_window_maximize_horizontal     (MetaWindow  *window);
+void        meta_window_maximize_vertical       (MetaWindow  *window);
 void        meta_window_fill_horizontal     (MetaWindow  *window);
 void        meta_window_fill_vertical       (MetaWindow  *window);
 
