diff -uNr metacity-2.5.2/src/window.c metacity-2.5.2-multimonitor/src/window.c
--- metacity-2.5.2/src/window.c	2003-05-20 18:27:15.000000000 +0200
+++ metacity-2.5.2-multimonitor/src/window.c	2003-06-11 10:22:26.000000000 +0200
@@ -490,6 +490,8 @@
   window->top_strut = 0;
   window->bottom_strut = 0;
 
+  window->shaken_loose = FALSE;
+
   window->cached_group = NULL;
 
   window->using_net_wm_name = FALSE;
@@ -5679,6 +5681,77 @@
   new_x = window->display->grab_current_window_pos.x + dx;
   new_y = window->display->grab_current_window_pos.y + dy;
 
+#define SHAKE_LOOSE_THRESHOLD 50
+
+  /* shake loose (unmaximize) maximized window if dragged beyond the threshold */
+  if (window->maximized)
+    {
+      if (ABS (dy) >= SHAKE_LOOSE_THRESHOLD)
+        {
+          /* we must know that the window has been shaken loose
+           * to be able to remaximize it on an other xinerama head */
+          window->shaken_loose = TRUE;
+
+          /* move the unmaximized window to the cursor */
+          window->display->grab_current_window_pos.x = window->display->grab_current_root_x - window->saved_rect.width / 2; 
+          window->display->grab_current_window_pos.y = window->display->grab_current_root_y; 
+          window->saved_rect.x = window->display->grab_current_window_pos.x + dx;
+          window->saved_rect.y = window->display->grab_current_window_pos.y + dy;
+
+          meta_window_unmaximize (window);
+
+          return;
+        }
+    }
+
+  /* remaximize window on an other xinerama monitor if window has
+   * been shaken loose or it is still maximized (then move straight) */
+  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++)
+        {
+          /* check if cursor is near the top of a xinerama 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)
+            {
+              /* move the saved rect if window will become maximized on an
+               * other monitor so user isn't surprised on a later unmaximize */
+              if (wxinerama->number != monitor)
+                {
+                  window->saved_rect.x = window->screen->xinerama_infos[monitor].x_origin;
+                  window->saved_rect.y = window->screen->xinerama_infos[monitor].y_origin;
+
+                  if (window->frame) 
+                    {
+                      window->saved_rect.x += window->frame->child_x;
+                      window->saved_rect.y += window->frame->child_y;
+                    } 
+
+                  meta_window_unmaximize (window);
+                }
+
+              window->shaken_loose = FALSE;
+
+              meta_window_maximize (window);
+
+              return;
+            }
+        }
+
+      /* don't allow a maximized window a normal movement */
+      if (window->maximized)
+        return;
+    }
+
   if (mask & ShiftMask)
     {
       /* snap to edges */
@@ -5914,6 +5987,9 @@
             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;    
 
diff -uNr metacity-2.5.2/src/window.h metacity-2.5.2-multimonitor/src/window.h
--- metacity-2.5.2/src/window.h	2003-03-17 07:36:39.000000000 +0100
+++ metacity-2.5.2-multimonitor/src/window.h	2003-06-11 10:22:26.000000000 +0200
@@ -228,6 +228,8 @@
   /* icon props have changed */
   guint need_reread_icon : 1;
   
+  /* Whether we've been shaken loose */
+  unsigned int shaken_loose : 1;
 #ifdef HAVE_XSYNC
   /* XSync update counter */
   XSyncCounter update_counter;
@@ -287,7 +289,7 @@
   MetaGroup *cached_group;
 };
 
-#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) ||  \
