--- metacity-2.8.6/src/common.h	2004-06-21 17:47:27.000000000 +0100
+++ metacity-2.8.6.rmy/src/common.h	2004-10-31 20:48:29.000000000 +0000
@@ -86,6 +86,7 @@
 
   /* Mouse ops */
   META_GRAB_OP_MOVING,
+  META_GRAB_OP_PLACING,
   META_GRAB_OP_RESIZING_SE,
   META_GRAB_OP_RESIZING_S,
   META_GRAB_OP_RESIZING_SW,
@@ -151,6 +152,12 @@
 
 typedef enum
 {
+  META_PLACEMENT_MODE_AUTOMATIC,
+  META_PLACEMENT_MODE_MANUAL
+} MetaPlacementMode;
+
+typedef enum
+{
   META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_SHADE,
   META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_MAXIMIZE,
   META_ACTION_DOUBLE_CLICK_TITLEBAR_LAST
--- metacity-2.8.6/src/display.c	2004-10-11 16:42:37.000000000 +0100
+++ metacity-2.8.6.rmy/src/display.c	2004-11-02 21:18:15.000000000 +0000
@@ -990,6 +990,7 @@
   switch (op)
     {
     case META_GRAB_OP_MOVING:
+    case META_GRAB_OP_PLACING:
     case META_GRAB_OP_RESIZING_SE:
     case META_GRAB_OP_RESIZING_S:      
     case META_GRAB_OP_RESIZING_SW:      
@@ -1080,6 +1081,7 @@
   switch (op)
     {
     case META_GRAB_OP_MOVING:
+    case META_GRAB_OP_PLACING:
     case META_GRAB_OP_KEYBOARD_MOVING:
       return TRUE;
       break;
@@ -2995,6 +2997,7 @@
       cursor = META_CURSOR_EAST_RESIZE;
       break;
     case META_GRAB_OP_MOVING:
+    case META_GRAB_OP_PLACING:
     case META_GRAB_OP_KEYBOARD_MOVING:
       cursor = META_CURSOR_MOVE_WINDOW;
       break;
@@ -3081,6 +3084,148 @@
 }
 
 gboolean
+meta_manual_placement (MetaWindow *window, int *x, int *y)
+{
+  Window grab_xwindow;
+  MetaGrabOp   op = META_GRAB_OP_PLACING;
+  int          button = 0;
+  gulong       modmask = 0;
+  Window root, win;
+  int root_x, root_y, wx, wy, key;
+  MetaDisplay *display = window->display;
+  MetaScreen  *screen = window->screen;
+  
+  *x = *y = 0 ;
+
+  meta_topic (META_DEBUG_WINDOW_OPS,
+              "Doing grab op %d on window %s button %d pointer pos %d,%d\n",
+              op, window ? window->desc : "none", button,
+              root_x, root_y);
+  
+  if (display->grab_op != META_GRAB_OP_NONE)
+    {
+      meta_warning ("Attempt to perform window operation %d on window %s when operation %d on %s already in effect\n",
+                    op, window ? window->desc : "none", display->grab_op,
+                    display->grab_window ? display->grab_window->desc : "none");
+      return FALSE;
+    }
+
+  /* We'll ignore any events < this serial. */
+  display->grab_start_serial = XNextRequest (display->xdisplay);
+  
+  grab_xwindow = screen->xroot;
+
+  display->grab_have_pointer = FALSE;
+  
+  meta_display_set_grab_op_cursor (display, screen, op, FALSE, grab_xwindow,
+                                   meta_display_get_current_time (display));
+
+  if (!display->grab_have_pointer)
+    {
+      meta_topic (META_DEBUG_WINDOW_OPS,
+                  "XGrabPointer() failed\n");
+      return FALSE;
+    }
+
+  XQueryPointer(display->xdisplay, screen->xroot,
+                &root, &win, &root_x, &root_y, &wx, &wy, &key) ;
+  
+  display->grab_op = op;
+  display->grab_window = window;
+  display->grab_screen = screen;
+  display->grab_xwindow = grab_xwindow;
+  display->grab_button = button;
+  display->grab_mask = modmask;
+  display->grab_anchor_root_x = root_x;
+  display->grab_anchor_root_y = root_y;
+  display->grab_latest_motion_x = root_x;
+  display->grab_latest_motion_y = root_y;
+  display->grab_last_moveresize_time.tv_sec = 0;
+  display->grab_last_moveresize_time.tv_usec = 0;
+  display->grab_motion_notify_time = 0;
+#ifdef HAVE_XSYNC
+  display->grab_sync_request_alarm = None;
+#endif
+  display->grab_was_cancelled = FALSE;
+  
+  if (display->grab_resize_timeout_id)
+    {
+      g_source_remove (display->grab_resize_timeout_id);
+      display->grab_resize_timeout_id = 0;
+    }
+	
+  if (display->grab_window)
+    {
+      MetaRectangle xor_rect;
+
+      if (window->frame)
+        {
+          window->frame->rect.x = root_x ;
+          window->frame->rect.y = root_y ;
+        }
+
+      display->grab_window->rect.x = root_x;
+      display->grab_window->rect.y = root_y;
+
+      display->grab_initial_window_pos = display->grab_window->rect;
+      meta_window_get_position (display->grab_window,
+                                &display->grab_initial_window_pos.x,
+                                &display->grab_initial_window_pos.y);
+      display->grab_anchor_window_pos = display->grab_initial_window_pos;
+
+      display->grab_wireframe_active = TRUE;
+
+      display->grab_wireframe_rect = window->rect;
+      if (window->frame)
+        {
+          display->grab_wireframe_rect.x += window->frame->child_x;
+          display->grab_wireframe_rect.y += window->frame->child_y;
+        }
+          
+      meta_window_get_xor_rect (window, &display->grab_wireframe_rect,
+                                &xor_rect);
+      meta_effects_begin_wireframe (display->grab_window->screen,
+                                    &xor_rect);
+      display->grab_wireframe_last_xor_rect = xor_rect;
+    }
+  
+  meta_topic (META_DEBUG_WINDOW_OPS,
+              "Grab op %d on window %s successful\n",
+              display->grab_op, window ? window->desc : "(null)");
+
+  g_assert (display->grab_window != NULL || display->grab_screen != NULL);
+  g_assert (display->grab_op != META_GRAB_OP_NONE);
+
+  while ( display->grab_op != META_GRAB_OP_NONE )
+    {
+      XEvent event;
+
+      XWindowEvent(display->xdisplay, grab_xwindow,
+                   PointerMotionMask|ButtonPressMask, &event) ;
+
+      if ( event.xany.type == MotionNotify &&
+           event.xany.serial >= display->grab_start_serial)
+        meta_window_handle_mouse_grab_op_event (window, &event);
+      else if ( event.xany.type == ButtonPress &&
+                event.xany.serial >= display->grab_start_serial)
+        meta_display_end_grab_op (display, event.xbutton.time);
+      else
+        event_callback (&event, display);
+    }
+
+  *x = window->display->grab_wireframe_rect.x;
+  *y = window->display->grab_wireframe_rect.y;
+
+  if (window->frame)
+    {
+      window->frame->rect.x = *x;
+      window->frame->rect.y = *y;
+    }
+  
+  return TRUE;
+}
+
+gboolean
 meta_display_begin_grab_op (MetaDisplay *display,
 			    MetaScreen  *screen,
                             MetaWindow  *window,
@@ -3352,14 +3497,17 @@
       display->grab_wireframe_active = FALSE;
       meta_effects_end_wireframe (display->grab_window->screen,
                                   &display->grab_wireframe_last_xor_rect);
-      if (!display->grab_was_cancelled)
-        meta_window_move_resize (display->grab_window,
-                                 TRUE,
-                                 display->grab_wireframe_rect.x,
-                                 display->grab_wireframe_rect.y,
-                                 display->grab_wireframe_rect.width,
-                                 display->grab_wireframe_rect.height);
-      meta_window_calc_showing (display->grab_window);
+	  if (display->grab_op != META_GRAB_OP_PLACING)
+	    {
+          if (!display->grab_was_cancelled)
+            meta_window_move_resize (display->grab_window,
+                                     TRUE,
+                                     display->grab_wireframe_rect.x,
+                                     display->grab_wireframe_rect.y,
+                                     display->grab_wireframe_rect.width,
+                                     display->grab_wireframe_rect.height);
+          meta_window_calc_showing (display->grab_window);
+        }
     }
 
   if (display->grab_have_pointer)
--- metacity-2.8.6/src/display.h	2004-10-11 16:42:37.000000000 +0100
+++ metacity-2.8.6.rmy/src/display.h	2004-11-02 21:07:38.000000000 +0000
@@ -394,6 +394,10 @@
                                           Window       grab_xwindow,
                                           Time         timestamp);
 
+gboolean meta_manual_placement (MetaWindow *window,
+                                int  *x,
+                                int  *y);
+
 gboolean meta_display_begin_grab_op (MetaDisplay *display,
                                      MetaScreen  *screen,
                                      MetaWindow  *window,
--- metacity-2.8.6/src/metacity.schemas.in	2004-07-24 17:28:14.000000000 +0100
+++ metacity-2.8.6.rmy/src/metacity.schemas.in	2004-11-01 20:37:44.000000000 +0000
@@ -62,6 +62,24 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/general/placement_mode</key>
+      <applyto>/apps/metacity/general/placement_mode</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>automatic</default>
+      <locale name="C">
+         <short>Window placement mode</short>
+         <long>
+          The window placement mode indicates how windows are positioned. 
+          It has two possible values; "automatic" means window positions
+		  are determined by metacity based on the space available on the
+		  desktop, "manual" means windows have to be positioned by the
+		  user moving a wireframe outline into the required position.
+         </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/metacity/general/action_double_click_titlebar</key>
       <applyto>/apps/metacity/general/action_double_click_titlebar</applyto>
       <owner>metacity</owner>
--- metacity-2.8.6/src/place.c	2003-11-08 05:47:37.000000000 +0000
+++ metacity-2.8.6.rmy/src/place.c	2004-11-06 21:38:31.349166368 +0000
@@ -732,7 +732,16 @@
 
       goto done;
     }
-  
+
+  /* Let the user position the window manually, if that's what they
+   * want to do.
+   */
+  if (meta_prefs_get_placement_mode() == META_PLACEMENT_MODE_MANUAL)
+    {
+      if (meta_manual_placement(window, &x, &y))
+        goto done_no_constraints;
+    }
+
   /* Find windows that matter (not minimized, on same workspace
    * as placed window, may be shaded - if shaded we pretend it isn't
    * for placement purposes)
--- metacity-2.8.6/src/prefs.c	2004-09-18 16:54:31.000000000 +0100
+++ metacity-2.8.6.rmy/src/prefs.c	2004-11-01 20:36:21.000000000 +0000
@@ -41,6 +41,7 @@
  */
 #define KEY_MOUSE_BUTTON_MODS "/apps/metacity/general/mouse_button_modifier"
 #define KEY_FOCUS_MODE "/apps/metacity/general/focus_mode"
+#define KEY_PLACEMENT_MODE "/apps/metacity/general/placement_mode"
 #define KEY_ACTION_DOUBLE_CLICK_TITLEBAR "/apps/metacity/general/action_double_click_titlebar"
 #define KEY_AUTO_RAISE "/apps/metacity/general/auto_raise"
 #define KEY_AUTO_RAISE_DELAY "/apps/metacity/general/auto_raise_delay"
@@ -74,6 +75,7 @@
 static PangoFontDescription *titlebar_font = NULL;
 static MetaVirtualModifier mouse_button_mods = Mod1Mask;
 static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
+static MetaPlacementMode placement_mode = META_PLACEMENT_MODE_AUTOMATIC;
 static char* current_theme = NULL;
 static int num_workspaces = 4;
 static MetaActionDoubleClickTitlebar action_double_click_titlebar =
@@ -112,6 +114,7 @@
 static gboolean update_titlebar_font      (const char *value);
 static gboolean update_mouse_button_mods  (const char *value);
 static gboolean update_focus_mode         (const char *value);
+static gboolean update_placement_mode     (const char *value);
 static gboolean update_theme              (const char *value);
 static gboolean update_visual_bell        (gboolean v1, gboolean v2);
 static gboolean update_visual_bell_type   (const char *value);
@@ -316,6 +319,12 @@
   update_focus_mode (str_val);
   g_free (str_val);  
 
+  str_val = gconf_client_get_string (default_client, KEY_PLACEMENT_MODE,
+                                     &err);
+  cleanup_error (&err);
+  update_placement_mode (str_val);
+  g_free (str_val);  
+
   str_val = gconf_client_get_string (default_client,
                                      KEY_ACTION_DOUBLE_CLICK_TITLEBAR,
 				     &err);
@@ -482,6 +491,22 @@
       if (update_focus_mode (str))
         queue_changed (META_PREF_FOCUS_MODE);
     }
+  else if (strcmp (key, KEY_PLACEMENT_MODE) == 0)
+    {
+      const char *str;
+
+      if (value && value->type != GCONF_VALUE_STRING)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                        KEY_PLACEMENT_MODE);
+          goto out;
+        }
+      
+      str = value ? gconf_value_get_string (value) : NULL;
+
+      if (update_placement_mode (str))
+        queue_changed (META_PREF_PLACEMENT_MODE);
+    }
   else if (strcmp (key, KEY_THEME) == 0)
     {
       const char *str;
@@ -841,6 +866,27 @@
 
 #ifdef HAVE_GCONF
 static gboolean
+update_placement_mode (const char *value)
+{
+  MetaPlacementMode old_mode = placement_mode;
+  
+  if (value != NULL)
+    {
+      if (g_ascii_strcasecmp (value, "manual") == 0)
+        placement_mode = META_PLACEMENT_MODE_MANUAL;
+      else if (g_ascii_strcasecmp (value, "automatic") == 0)
+        placement_mode = META_PLACEMENT_MODE_AUTOMATIC;
+      else
+        meta_warning (_("GConf key '%s' is set to an invalid value\n"),
+                      KEY_PLACEMENT_MODE);
+    }
+
+  return (old_mode != placement_mode);
+}
+#endif /* HAVE_GCONF */
+
+#ifdef HAVE_GCONF
+static gboolean
 update_theme (const char *value)
 {
   char *old_theme;
@@ -885,6 +931,12 @@
   return focus_mode;
 }
 
+MetaPlacementMode
+meta_prefs_get_placement_mode (void)
+{
+  return placement_mode;
+}
+
 const char*
 meta_prefs_get_theme (void)
 {
@@ -1302,6 +1354,9 @@
     case META_PREF_FOCUS_MODE:
       return "FOCUS_MODE";
 
+    case META_PREF_PLACEMENT_MODE:
+      return "PLACEMENT_MODE";
+
     case META_PREF_THEME:
       return "THEME";
 
--- metacity-2.8.6/src/prefs.h	2004-02-19 18:36:14.000000000 +0000
+++ metacity-2.8.6.rmy/src/prefs.h	2004-11-01 20:24:33.000000000 +0000
@@ -30,6 +30,7 @@
 {
   META_PREF_MOUSE_BUTTON_MODS,
   META_PREF_FOCUS_MODE,
+  META_PREF_PLACEMENT_MODE,
   META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
   META_PREF_AUTO_RAISE,
   META_PREF_AUTO_RAISE_DELAY,
@@ -62,6 +63,7 @@
 
 MetaVirtualModifier         meta_prefs_get_mouse_button_mods  (void);
 MetaFocusMode               meta_prefs_get_focus_mode         (void);
+MetaPlacementMode           meta_prefs_get_placement_mode     (void);
 const char*                 meta_prefs_get_theme              (void);
 /* returns NULL if GTK default should be used */
 const PangoFontDescription* meta_prefs_get_titlebar_font      (void);
--- metacity-2.8.6/src/window.c	2004-10-11 16:42:37.000000000 +0100
+++ metacity-2.8.6.rmy/src/window.c	2004-11-06 21:33:48.647343365 +0000
@@ -3601,6 +3601,7 @@
       switch (window->display->grab_op)
         {
         case META_GRAB_OP_MOVING:
+        case META_GRAB_OP_PLACING:
         case META_GRAB_OP_RESIZING_SE:
         case META_GRAB_OP_RESIZING_S:
         case META_GRAB_OP_RESIZING_SW:
--- metacity-2.8.6/src/workspace.c	2004-10-11 16:42:37.000000000 +0100
+++ metacity-2.8.6.rmy/src/workspace.c	2004-10-31 12:13:50.000000000 +0000
@@ -294,6 +294,7 @@
 
   move_window = NULL;
   if (workspace->screen->display->grab_op == META_GRAB_OP_MOVING ||
+      workspace->screen->display->grab_op == META_GRAB_OP_PLACING ||
       workspace->screen->display->grab_op == META_GRAB_OP_KEYBOARD_MOVING)
     move_window = workspace->screen->display->grab_window;
       
