--- src/window.h	2005-03-11 13:31:01.000000000 -0800
+++ src/window.h	2005-03-11 13:46:19.000000000 -0800
@@ -109,6 +109,8 @@
   /* Whether we're maximized */
   guint maximized : 1;
   guint maximize_after_placement : 1;
+  guint maximize_horizontally : 1;
+  guint maximize_vertically : 1;
 
   /* Whether we're shaded */
   guint shaded : 1;

--- src/window.c	2005-02-28 13:29:26.000000000 -0800
+++ src/window.c	2005-03-11 13:52:13.000000000 -0800
@@ -429,6 +429,8 @@
   
   window->maximized = FALSE;
   window->maximize_after_placement = FALSE;
+  window->maximize_horizontally = FALSE;
+  window->maximize_vertically = FALSE;
   window->fullscreen = FALSE;
   window->on_all_workspaces = FALSE;
   window->shaded = FALSE;
@@ -2884,6 +2886,10 @@
     }
   
   meta_window_refresh_resize_popup (window);
+  if ( window->maximize_vertically )
+		  window->maximize_vertically = FALSE;
+  if ( window->maximize_horizontally )
+		  window->maximize_horizontally = FALSE;
   
   /* Invariants leaving this function are:
    *   a) window->rect and frame->rect reflect the actual
@@ -3001,6 +3007,7 @@
 void
 meta_window_fill_horizontal (MetaWindow  *window)
 {
+  if (!window->maximize_horizontally) {		
   MetaRectangle work_area;
   int x, y, w, h;
   
@@ -3009,6 +3016,7 @@
   w = window->rect.width;
   h = window->rect.height;
   
+  meta_window_save_rect (window);
   meta_window_get_work_area_current_xinerama (window, &work_area);
   
   x = work_area.x;
@@ -3024,19 +3032,52 @@
                            x, y, w, h);
 
   check_maximize_to_work_area (window, &work_area);
+  window->maximize_horizontally = TRUE;
+  }
+  else{
+      window->maximize_horizontally = FALSE;
+
+      /* When we unmaximize, if we're doing a mouse move also we could
+       * get the window suddenly jumping to the upper left corner of
+       * the workspace, since that's where it was when the grab op
+       * started.  So we need to update the grab state.
+       */
+      if (meta_grab_op_is_moving (window->display->grab_op) &&
+          window->display->grab_window == window)
+        {
+          window->display->grab_anchor_window_pos = window->saved_rect;
+        }
+
+      meta_window_move_resize (window,
+                               TRUE,
+                               window->saved_rect.x,
+                               window->saved_rect.y,
+                               window->saved_rect.width,
+                               window->saved_rect.height);
+
+      if (window->display->grab_wireframe_active)
+        {
+          window->display->grab_wireframe_rect = window->saved_rect;
+        }
+
+      recalc_window_features (window);
+      set_net_wm_state (window);
+    }
 }
 
 void
 meta_window_fill_vertical (MetaWindow  *window)
 {
+  if (!window->maximize_vertically) {		
   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_save_rect (window);
   meta_window_get_work_area_current_xinerama (window, &work_area);
 
   y = work_area.y;
@@ -3052,6 +3093,39 @@
                            x, y, w, h);
 
   check_maximize_to_work_area (window, &work_area);
+  window->maximize_vertically = TRUE;
+  
+  }
+  else
+  {
+      window->maximize_vertically = FALSE;
+
+      /* When we unmaximize, if we're doing a mouse move also we could
+       * get the window suddenly jumping to the upper left corner of
+       * the workspace, since that's where it was when the grab op
+       * started.  So we need to update the grab state.
+       */
+      if (meta_grab_op_is_moving (window->display->grab_op) &&
+          window->display->grab_window == window)
+        {
+          window->display->grab_anchor_window_pos = window->saved_rect;
+        }
+
+      meta_window_move_resize (window,
+                               TRUE,
+                               window->saved_rect.x,
+                               window->saved_rect.y,
+                               window->saved_rect.width,
+                               window->saved_rect.height);
+
+      if (window->display->grab_wireframe_active)
+        {
+          window->display->grab_wireframe_rect = window->saved_rect;
+        }
+
+      recalc_window_features (window);
+      set_net_wm_state (window);
+  }
 }
 
 static guint move_resize_idle = 0;
