--- metacity/src/window.c	2003-02-21 18:11:05.000000000 -0800
+++ metacity-ra/src/window.c	2003-02-20 10:29:13.000000000 -0800
@@ -462,6 +462,8 @@ meta_window_new (MetaDisplay *display,
 
   window->cached_group = NULL;
 
+  window->shaken_loose = FALSE;
+
   window->using_net_wm_name = FALSE;
   window->using_net_wm_icon_name = FALSE;
   
@@ -6241,6 +6243,7 @@ update_move (MetaWindow  *window,
   int dx, dy;
   int new_x, new_y;
   int move_threshold;
+  int shake_loose_threshold;
 
   window->display->grab_latest_motion_x = x;
   window->display->grab_latest_motion_y = y;
@@ -6251,13 +6254,84 @@ update_move (MetaWindow  *window,
   new_x = window->display->grab_current_window_pos.x + dx;
   new_y = window->display->grab_current_window_pos.y + dy;
 
+  shake_loose_threshold = 50;
+
+  if (window->maximized)
+  {
+  	if (ABS (dy) >= shake_loose_threshold)
+  	{
+          meta_topic (META_DEBUG_WINDOW_OPS,
+                      "Unmaximizing %s (shake loose)\n", window->desc);
+          window->shaken_loose = TRUE;
+
+	  if (window->frame)
+	    {
+	      window->saved_rect.x = x - (window->frame->child_x + 
+					  window->frame->right_width +
+					  window->saved_rect.width)/2;
+	      window->saved_rect.y = y - window->frame->child_y/2;
+	    }
+
+	  meta_window_unmaximize(window);
+
+	  return;
+  	}
+  }
+
+  if (window->shaken_loose || window->maximized)
+  {
+    const MetaXineramaScreenInfo* wxinerama;
+    int monitor;
+    
+    wxinerama = meta_screen_get_xinerama_for_window(window->screen,
+						    window);
+
+    for (monitor = 0; monitor < window->screen->n_xinerama_infos; monitor++)
+    {
+      if (x >= window->screen->xinerama_infos[monitor].x_origin
+        && x < window->screen->xinerama_infos[monitor].x_origin + 
+	  window->screen->xinerama_infos[monitor].width
+        && y >= window->screen->xinerama_infos[monitor].y_origin
+        && y < window->screen->xinerama_infos[monitor].y_origin + shake_loose_threshold)
+      {
+	if (window->frame) 
+	  {
+	    new_x = window->screen->xinerama_infos[monitor].x_origin +
+	      window->frame->child_x;
+	    new_y = window->screen->xinerama_infos[monitor].y_origin +
+	      window->frame->child_y;
+	  } 
+	else
+	  {
+	    new_x = window->screen->xinerama_infos[monitor].x_origin;
+	    new_y = window->screen->xinerama_infos[monitor].y_origin;
+	  }
+
+	if (wxinerama->number != monitor)
+	  {
+	    window->maximized = FALSE;
+	    meta_window_move(window, TRUE, new_x, new_y);
+	  }	  
+
+	meta_topic (META_DEBUG_WINDOW_OPS,
+		    "Maximizing %s (snap in)\n", window->desc);
+	window->shaken_loose = FALSE;
+	meta_window_maximize(window);
+
+        return;
+      }
+    }
+    if (window->maximized)
+      return;
+  }
+
   if (mask & ShiftMask)
     {
       /* 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);
     }
-
+    
   /* Force a move regardless of time if a certain delta is exceeded,
    * so we don't get too out of sync with reality when dropping frames
    */
@@ -6514,6 +6588,9 @@ meta_window_handle_mouse_grab_op_event (
             update_resize (window, event->xbutton.x_root, event->xbutton.y_root);
         }
 
+      // reset shaken_loose state on end grab op
+      window->shaken_loose = FALSE;
+
      meta_display_end_grab_op (window->display, event->xbutton.time);
       break;    
 
--- metacity/src/window.h	2003-02-21 18:11:05.000000000 -0800
+++ metacity-ra/src/window.h	2003-02-15 10:34:29.000000000 -0800
@@ -279,9 +279,12 @@ struct _MetaWindow
 
   /* maintained by group.c */
   MetaGroup *cached_group;
+
+  /* Whether we've been shaken loose */
+  guint shaken_loose : 1;
 };
 
-#define META_WINDOW_ALLOWS_MOVE(w)     ((w)->has_move_func && !(w)->maximized && !(w)->fullscreen)
+#define META_WINDOW_ALLOWS_MOVE(w)     ((w)->has_move_func && !(w)->fullscreen)
 #define META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS(w)   ((w)->has_resize_func && !(w)->maximized && !(w)->fullscreen && !(w)->shaded)
 #define META_WINDOW_ALLOWS_RESIZE(w)   (META_WINDOW_ALLOWS_RESIZE_EXCEPT_HINTS (w) &&                \
                                         (((w)->size_hints.min_width < (w)->size_hints.max_width) ||  \
