diff -dcr metacity/src/keybindings.c metacity-work/src/keybindings.c
*** metacity/src/keybindings.c	2004-08-25 20:59:12.000000000 -0400
--- metacity-work/src/keybindings.c	2004-09-12 00:03:16.065037088 -0400
***************
*** 184,189 ****
--- 184,204 ----
                                         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 void handle_spew_mark          (MetaDisplay *display,
***************
*** 410,415 ****
--- 425,433 ----
    { 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 }
  };
  
***************
*** 2627,2633 ****
    if (window)
      {
        if (window->has_resize_func)
!         meta_window_fill_vertical (window);
      }
  }
  
--- 2645,2651 ----
    if (window)
      {
        if (window->has_resize_func)
!         meta_window_maximize_vertical (window);
      }
  }
  
***************
*** 2641,2646 ****
--- 2659,2707 ----
    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 -dcr metacity/src/metacity.schemas.in metacity-work/src/metacity.schemas.in
*** metacity/src/metacity.schemas.in	2004-07-22 19:27:51.000000000 -0400
--- metacity-work/src/metacity.schemas.in	2004-09-11 21:11:49.151469977 -0400
***************
*** 1026,1031 ****
--- 1026,1100 ----
           </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 -dcr metacity/src/place.c metacity-work/src/place.c
*** metacity/src/place.c	2004-09-11 23:51:16.565951879 -0400
--- metacity-work/src/place.c	2004-09-12 00:02:23.402552629 -0400
***************
*** 924,931 ****
  static void
  get_vertical_edges (MetaWindow *window,
                      int       **edges_p,
!                     int        *n_edges_p)
  {
    GSList *windows;
    GSList *tmp;
    int n_windows;
--- 924,933 ----
  static void
  get_vertical_edges (MetaWindow *window,
                      int       **edges_p,
!                     int        *n_edges_p,
!                     int				lefts_only)
  {
+ 	/* 1, top edges only, -1 bottom edges only, 0 all edges */
    GSList *windows;
    GSList *tmp;
    int n_windows;
***************
*** 939,945 ****
  
    i = 0;
    /* 4 = workspace/screen edges */
!   n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; 
  
    edges = g_new (int, n_edges);
  
--- 941,951 ----
  
    i = 0;
    /* 4 = workspace/screen edges */
!   if (lefts_only == 0)
!   	n_edges = n_windows * 2;
!   else
!   	n_edges = n_windows;
!   n_edges += 4 + window->screen->n_xinerama_infos - 1; 
  
    edges = g_new (int, n_edges);
  
***************
*** 977,984 ****
        
        if (rects_overlap_vertically (&rect, &w_rect))
          {
!           window_get_edges (w, &edges[i], &edges[i+1], NULL, NULL);
!           i += 2;
          }
  
        tmp = tmp->next;
--- 983,998 ----
        
        if (rects_overlap_vertically (&rect, &w_rect))
          {
!         	if (lefts_only > -1)
!         		{
! 	        		window_get_edges (w, &edges[i], NULL, NULL, NULL);
! 	        		i++;
! 	        	}
! 	        if (lefts_only < 1)
! 	        	{
! 	        		window_get_edges (w, NULL, &edges[i], NULL, NULL);
!   		        i++;
!   		      }
          }
  
        tmp = tmp->next;
***************
*** 997,1003 ****
  static void
  get_horizontal_edges (MetaWindow *window,
                        int       **edges_p,
!                       int        *n_edges_p)
  {
    GSList *windows;
    GSList *tmp;
--- 1011,1018 ----
  static void
  get_horizontal_edges (MetaWindow *window,
                        int       **edges_p,
!                       int        *n_edges_p,
!                       int				tops_only)
  {
    GSList *windows;
    GSList *tmp;
***************
*** 1011,1017 ****
    windows = get_windows_on_same_workspace (window, &n_windows);
  
    i = 0;
!   n_edges = n_windows * 2 + 4 + window->screen->n_xinerama_infos - 1; /* 4 = workspace/screen edges */
    edges = g_new (int, n_edges);
  
    /* workspace/screen edges */
--- 1026,1036 ----
    windows = get_windows_on_same_workspace (window, &n_windows);
  
    i = 0;
!   if (tops_only == 0)
!   	n_edges = n_windows*2;
!  	else
!  		n_edges = n_windows;
!   n_edges += 4 + window->screen->n_xinerama_infos - 1; /* 4 = workspace/screen edges */
    edges = g_new (int, n_edges);
  
    /* workspace/screen edges */
***************
*** 1048,1055 ****
        
        if (rects_overlap_horizontally (&rect, &w_rect))
          {
!           window_get_edges (w, NULL, NULL, &edges[i], &edges[i+1]);
!           i += 2;
          }
  
        tmp = tmp->next;
--- 1067,1082 ----
        
        if (rects_overlap_horizontally (&rect, &w_rect))
          {
!   	    	if (tops_only > -1)
!          		{
!         			window_get_edges (w, NULL, NULL, &edges[i], NULL);
!         			i++;
!         		}
!         	if (tops_only < 1)
!         		{
!         			window_get_edges (w, NULL, NULL, NULL, &edges[i]);
!         			i++;
!         		}
          }
  
        tmp = tmp->next;
***************
*** 1075,1081 ****
    int n_edges;
    int retval;
  
!   get_vertical_edges (window, &edges, &n_edges);
    
    /* Find next */
    meta_window_get_position (window, &retval, NULL);
--- 1102,1111 ----
    int n_edges;
    int retval;
  
!   if (right)
! 	  get_vertical_edges (window, &edges, &n_edges, 1);
! 	else
! 		get_vertical_edges (window, &edges, &n_edges, -1);
    
    /* Find next */
    meta_window_get_position (window, &retval, NULL);
***************
*** 1087,1107 ****
        i = 0;
        while (i < n_edges)
          {
!           if (edges[i] > right_edge)
              {
                /* This is the one we want, snap right
                 * edge of window to edges[i]
                 */
                retval = edges[i];
                if (window->frame)
!                 {
!                   retval -= window->frame->rect.width;
!                   retval += window->frame->child_x;
!                 }
!               else
!                 {
!                   retval -= window->rect.width;
!                 }
                break;
              }
            
--- 1117,1131 ----
        i = 0;
        while (i < n_edges)
          {
!           if (edges[i] >= right_edge)
              {
                /* This is the one we want, snap right
                 * edge of window to edges[i]
                 */
                retval = edges[i];
                if (window->frame)
!                  retval += window->frame->child_x;
! 
                break;
              }
            
***************
*** 1115,1121 ****
          {
            --i;
            
!           if (edges[i] < left_edge)
              {
                /* This is the one we want */
                retval = edges[i];
--- 1139,1145 ----
          {
            --i;
            
!           if (edges[i] <= left_edge)
              {
                /* This is the one we want */
                retval = edges[i];
***************
*** 1143,1149 ****
    int n_edges;
    int retval;
  
!   get_horizontal_edges (window, &edges, &n_edges);
    
    /* Find next */
    meta_window_get_position (window, NULL, &retval);
--- 1167,1176 ----
    int n_edges;
    int retval;
  
! 	if (down)
! 		get_horizontal_edges (window, &edges, &n_edges, 1);
! 	else
! 		get_horizontal_edges (window, &edges, &n_edges, -1);
    
    /* Find next */
    meta_window_get_position (window, NULL, &retval);
***************
*** 1155,1175 ****
        i = 0;
        while (i < n_edges)
          {
!           if (edges[i] > bottom_edge)
              {
                /* This is the one we want, snap right
                 * edge of window to edges[i]
                 */
                retval = edges[i];
                if (window->frame)
!                 {
!                   retval -= window->frame->rect.height;
!                   retval += window->frame->child_y;
!                 }
!               else
!                 {
!                   retval -= window->rect.height;
!                 }
                break;
              }
            
--- 1182,1196 ----
        i = 0;
        while (i < n_edges)
          {
!           if (edges[i] >= bottom_edge)
              {
                /* This is the one we want, snap right
                 * edge of window to edges[i]
                 */
                retval = edges[i];
                if (window->frame)
!                 retval += window->frame->child_y;
! 
                break;
              }
            
***************
*** 1183,1189 ****
          {
            --i;
            
!           if (edges[i] < top_edge)
              {
                /* This is the one we want */
                retval = edges[i];
--- 1204,1210 ----
          {
            --i;
            
!           if (edges[i] <= top_edge)
              {
                /* This is the one we want */
                retval = edges[i];
***************
*** 1212,1218 ****
    int n_positions;
    int retval;
    
!   get_vertical_edges (window, &edges, &n_edges);
  
    /* Create an array of all snapped positions our window could have */
    n_positions = n_edges * 2;
--- 1233,1239 ----
    int n_positions;
    int retval;
    
!   get_vertical_edges (window, &edges, &n_edges, 0);
  
    /* Create an array of all snapped positions our window could have */
    n_positions = n_edges * 2;
***************
*** 1283,1289 ****
    int n_positions;
    int retval;
    
!   get_horizontal_edges (window, &edges, &n_edges);
  
    /* Create an array of all snapped positions our window could have */
    n_positions = n_edges * 2;
--- 1304,1310 ----
    int n_positions;
    int retval;
    
!   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 -dcr metacity/src/prefs.c metacity-work/src/prefs.c
*** metacity/src/prefs.c	2004-04-29 20:26:48.000000000 -0400
--- metacity-work/src/prefs.c	2004-09-11 21:11:49.156469672 -0400
***************
*** 1494,1499 ****
--- 1494,1502 ----
    { 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 -dcr metacity/src/prefs.h metacity-work/src/prefs.h
*** metacity/src/prefs.h	2004-02-19 13:36:14.000000000 -0500
--- metacity-work/src/prefs.h	2004-09-11 21:11:49.157469611 -0400
***************
*** 182,187 ****
--- 182,190 ----
  #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 -dcr metacity/src/window.c metacity-work/src/window.c
*** metacity/src/window.c	2004-08-30 00:56:07.000000000 -0400
--- metacity-work/src/window.c	2004-09-11 22:14:37.817591361 -0400
***************
*** 2938,2944 ****
  }
  
  void
! meta_window_fill_horizontal (MetaWindow  *window)
  {
    MetaRectangle work_area;
    int x, y, w, h;
--- 2938,2944 ----
  }
  
  void
! meta_window_maximize_horizontal (MetaWindow  *window)
  {
    MetaRectangle work_area;
    int x, y, w, h;
***************
*** 2966,2972 ****
  }
  
  void
! meta_window_fill_vertical (MetaWindow  *window)
  {
    MetaRectangle work_area;
    int x, y, w, h;
--- 2966,2972 ----
  }
  
  void
! meta_window_maximize_vertical (MetaWindow  *window)
  {
    MetaRectangle work_area;
    int x, y, w, h;
***************
*** 2993,2998 ****
--- 2993,3049 ----
    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, FALSE);
+   w = meta_window_find_next_vertical_edge(window, TRUE) - x;
+   
+   if (window->frame != NULL)
+     	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, FALSE);
+   h = meta_window_find_next_horizontal_edge(window, TRUE) - y;
+  
+   if (window->frame != NULL)
+     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;
  
***************
*** 6268,6273 ****
--- 6319,6330 ----
            /* snap to edges */
            new_x = meta_window_find_nearest_vertical_edge (window, new_x);
            new_y = meta_window_find_nearest_horizontal_edge (window, new_y);
+           
+           if (window->frame)
+             {
+           	  new_y -= window->frame->rect.height;
+           	  new_x -= window->frame->rect.width;
+           	}
          }
        
        meta_window_move (window, TRUE, new_x, new_y);
diff -dcr metacity/src/window.h metacity-work/src/window.h
*** metacity/src/window.h	2004-08-18 22:05:24.000000000 -0400
--- metacity-work/src/window.h	2004-09-11 21:44:48.008358404 -0400
***************
*** 382,387 ****
--- 382,389 ----
                                               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);
  
