Index: src/core.c
===================================================================
RCS file: /cvs/gnome/metacity/src/core.c,v
retrieving revision 1.45
diff -p -u -r1.45 core.c
--- src/core.c	19 Nov 2005 14:58:50 -0000	1.45
+++ src/core.c	8 Jan 2006 00:54:07 -0000
@@ -269,7 +269,8 @@ meta_core_user_lower_and_unfocus (Displa
   
   meta_window_lower (window);
 
-  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK &&
+      !meta_prefs_get_orthogonal_raise ())
     {
       /* Move window to the back of the focusing workspace's MRU list.
        * Do extra sanity checks to avoid possible race conditions.
@@ -611,7 +612,8 @@ meta_core_show_window_menu (Display *xdi
   if (window == NULL || window->frame == NULL)
     meta_bug ("No such frame window 0x%lx!\n", frame_xwindow);  
 
-  meta_window_raise (window);
+  if (!meta_prefs_get_orthogonal_raise ())
+    meta_window_raise (window);
   meta_window_focus (window, timestamp);
 
   meta_window_show_menu (window, root_x, root_y, button, timestamp);
Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.265
diff -p -u -r1.265 display.c
--- src/display.c	28 Dec 2005 06:24:30 -0000	1.265
+++ src/display.c	8 Jan 2006 00:54:08 -0000
@@ -1656,15 +1656,11 @@ event_callback (XEvent   *event,
                */
               if (!frame_was_receiver)
                 {
-                  /* Raise on clicking the client area always or only
-                   * in click to focus mode? The debate rages.
-                   * Feel free to change TRUE to FALSE or vice versa
-                   */
-                  if (TRUE /* meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK */) 
+                  if (!meta_prefs_get_orthogonal_raise ()) 
                     meta_window_raise (window);
                   else
                     meta_topic (META_DEBUG_FOCUS,
-                                "Not raising window on click due to mouse/sloppy focus mode\n");
+                                "Not raising window on click due to orthogonal raise option\n");
 
                   /* Don't focus panels--they must explicitly request focus.
                    * See bug 160470
@@ -1735,6 +1731,8 @@ event_callback (XEvent   *event,
             }
           else if (event->xbutton.button == 3)
             {
+              if (!meta_prefs_get_orthogonal_raise ())
+                meta_window_raise (window);
               meta_window_show_menu (window,
                                      event->xbutton.x_root,
                                      event->xbutton.y_root,
@@ -3227,6 +3225,19 @@ meta_display_begin_grab_op (MetaDisplay 
       return FALSE;
     }
 
+  if (window &&
+      (meta_grab_op_is_moving (op) || meta_grab_op_is_resizing (op)))
+    {
+      if (!meta_prefs_get_orthogonal_raise ())
+        meta_window_raise (window);
+      else
+        {
+          display->grab_initial_x = root_x;
+          display->grab_initial_y = root_y;
+          display->grab_threshold_movement_reached = FALSE;
+        }
+    }
+
   /* We'll ignore any events < this serial. */
   if (pointer_already_grabbed)
     display->grab_start_serial = event_serial;
@@ -3460,6 +3471,20 @@ meta_display_end_grab_op (MetaDisplay *d
   if (display->grab_window != NULL)
     display->grab_window->shaken_loose = FALSE;
   
+  if (display->grab_window != NULL &&
+      meta_prefs_get_orthogonal_raise () &&
+      (meta_grab_op_is_moving (display->grab_op) ||
+       meta_grab_op_is_resizing (display->grab_op)))
+    {
+      /* Only raise the window in orthogonal raise mode if the user
+       * didn't try to move or resize the given window by at least a
+       * threshold amount.  For non-orthogonal-raise mode, the window
+       * was raised at the beginning of the grab_op.
+       */
+      if (!display->grab_threshold_movement_reached)
+        meta_window_raise (display->grab_window);
+    }
+
   if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
       display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
     {
@@ -3555,6 +3580,20 @@ meta_display_end_grab_op (MetaDisplay *d
       g_source_remove (display->grab_resize_timeout_id);
       display->grab_resize_timeout_id = 0;
     }
+}
+
+void
+meta_display_check_threshold_reached (MetaDisplay *display,
+                                      int          x,
+                                      int          y)
+{
+  /* Don't bother doing the check again if we've already reached the threshold */
+  if (display->grab_threshold_movement_reached)
+    return;
+
+  if (ABS (display->grab_initial_x - x) >= 8 ||
+      ABS (display->grab_initial_y - y) >= 8)
+    display->grab_threshold_movement_reached = TRUE;
 }
 
 static void
Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.139
diff -p -u -r1.139 display.h
--- src/display.h	28 Dec 2005 06:24:30 -0000	1.139
+++ src/display.h	8 Jan 2006 00:54:08 -0000
@@ -261,6 +261,8 @@ struct _MetaDisplay
   MetaRectangle grab_wireframe_rect;
   MetaRectangle grab_wireframe_last_xor_rect;
   MetaRectangle grab_initial_window_pos;
+  int         grab_initial_x, grab_initial_y;
+  gboolean    grab_threshold_movement_reached;
   MetaResizePopup *grab_resize_popup;
   GTimeVal    grab_last_moveresize_time;
   Time        grab_motion_notify_time;
@@ -441,6 +443,9 @@ gboolean meta_display_begin_grab_op (Met
 void     meta_display_end_grab_op   (MetaDisplay *display,
                                      Time         timestamp);
 
+void    meta_display_check_threshold_reached (MetaDisplay *display,
+                                              int          x,
+                                              int          y);
 void     meta_display_grab_window_buttons    (MetaDisplay *display,
                                               Window       xwindow);
 void     meta_display_ungrab_window_buttons  (MetaDisplay *display,
Index: src/frames.c
===================================================================
RCS file: /cvs/gnome/metacity/src/frames.c,v
retrieving revision 1.84
diff -p -u -r1.84 frames.c
--- src/frames.c	19 Nov 2005 14:58:50 -0000	1.84
+++ src/frames.c	8 Jan 2006 00:54:08 -0000
@@ -1261,13 +1261,11 @@ meta_frames_button_press_event (GtkWidge
   
   control = get_control (frames, frame, event->x, event->y);
 
-  /* raise/focus on click, even if click was on client area */
+  /* focus on click, even if click was on client area */
   if (event->button == 1 &&
       !(control == META_FRAME_CONTROL_MINIMIZE ||
         control == META_FRAME_CONTROL_DELETE))
     {
-      meta_core_user_raise (gdk_display,
-                            frame->xwindow);
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing window with frame 0x%lx due to button 1 press\n",
                   frame->xwindow);
Index: src/metacity.schemas.in
===================================================================
RCS file: /cvs/gnome/metacity/src/metacity.schemas.in,v
retrieving revision 1.44
diff -p -u -r1.44 metacity.schemas.in
--- src/metacity.schemas.in	3 Oct 2005 20:10:56 -0000	1.44
+++ src/metacity.schemas.in	8 Jan 2006 00:54:08 -0000
@@ -62,6 +62,25 @@
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/general/orthogonal_raise</key>
+      <applyto>/apps/metacity/general/orthogonal_raise</applyto>
+      <owner>metacity</owner>
+      <type>bool</type>
+      <default>false</default>
+      <locale name="C">
+         <short>Wheter raising should be a side-effect of other user
+                interactions</short>
+         <long>
+           Set to true to decouple raising from other user interactions.
+           Windows can still be raised by an alt-left-click or a normal
+           click on the window decorations (assuming such clicks aren't
+           used to start a move or resize operation).  Special messages,
+           such as activation requests from pagers, may also raise windows.
+         </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>
Index: src/prefs.c
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.c,v
retrieving revision 1.52
diff -p -u -r1.52 prefs.c
--- src/prefs.c	25 Oct 2005 16:43:01 -0000	1.52
+++ src/prefs.c	8 Jan 2006 00:54:08 -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_ORTHOGONAL_RAISE "/apps/metacity/general/orthogonal_raise"
 #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"
@@ -80,6 +81,7 @@ static gboolean use_system_font = TRUE;
 static PangoFontDescription *titlebar_font = NULL;
 static MetaVirtualModifier mouse_button_mods = Mod1Mask;
 static MetaFocusMode focus_mode = META_FOCUS_MODE_CLICK;
+static gboolean orthogonal_raise = TRUE;
 static char* current_theme = NULL;
 static int num_workspaces = 4;
 static MetaActionDoubleClickTitlebar action_double_click_titlebar =
@@ -123,6 +125,7 @@ static gboolean update_use_system_font  
 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_orthogonal_raise   (gboolean    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);
@@ -346,6 +349,11 @@ meta_prefs_init (void)
   update_focus_mode (str_val);
   g_free (str_val);  
 
+  bool_val = gconf_client_get_bool (default_client, KEY_ORTHOGONAL_RAISE,
+				    &err);
+  cleanup_error (&err);
+  update_orthogonal_raise (bool_val);
+  
   str_val = gconf_client_get_string (default_client,
                                      KEY_ACTION_DOUBLE_CLICK_TITLEBAR,
 				     &err);
@@ -551,6 +559,22 @@ change_notify (GConfClient    *client,
       if (update_focus_mode (str))
         queue_changed (META_PREF_FOCUS_MODE);
     }
+  else if (strcmp (key, KEY_ORTHOGONAL_RAISE) == 0)
+    {
+      gboolean b;
+
+      if (value && value->type != GCONF_VALUE_BOOL)
+        {
+          meta_warning (_("GConf key \"%s\" is set to an invalid type\n"),
+                        KEY_ORTHOGONAL_RAISE);
+          goto out;
+        }
+
+      b = value ? gconf_value_get_bool (value) : TRUE;
+      
+      if (update_orthogonal_raise (b))
+        queue_changed (META_PREF_ORTHOGONAL_RAISE);
+    }
   else if (strcmp (key, KEY_THEME) == 0)
     {
       const char *str;
@@ -974,6 +998,18 @@ update_focus_mode (const char *value)
 
 #ifdef HAVE_GCONF
 static gboolean
+update_orthogonal_raise (gboolean value)
+{
+  gboolean old = orthogonal_raise;
+
+  orthogonal_raise = value;
+
+  return old != value;
+}
+#endif /* HAVE_GCONF */
+
+#ifdef HAVE_GCONF
+static gboolean
 update_theme (const char *value)
 {
   char *old_theme;
@@ -1018,6 +1054,12 @@ meta_prefs_get_focus_mode (void)
   return focus_mode;
 }
 
+gboolean
+meta_prefs_get_orthogonal_raise (void)
+{
+  return orthogonal_raise;
+}
+
 const char*
 meta_prefs_get_theme (void)
 {
@@ -1496,6 +1538,9 @@ meta_preference_to_string (MetaPreferenc
     case META_PREF_FOCUS_MODE:
       return "FOCUS_MODE";
 
+    case META_PREF_ORTHOGONAL_RAISE:
+      return "ORTHOGONAL_RAISE";
+      
     case META_PREF_THEME:
       return "THEME";
 
Index: src/prefs.h
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.h,v
retrieving revision 1.37
diff -p -u -r1.37 prefs.h
--- src/prefs.h	11 Jul 2005 13:25:08 -0000	1.37
+++ src/prefs.h	8 Jan 2006 00:54:08 -0000
@@ -30,6 +30,7 @@ typedef enum
 {
   META_PREF_MOUSE_BUTTON_MODS,
   META_PREF_FOCUS_MODE,
+  META_PREF_ORTHOGONAL_RAISE,
   META_PREF_ACTION_DOUBLE_CLICK_TITLEBAR,
   META_PREF_AUTO_RAISE,
   META_PREF_AUTO_RAISE_DELAY,
@@ -66,6 +67,7 @@ const char* meta_preference_to_string (M
 
 MetaVirtualModifier         meta_prefs_get_mouse_button_mods  (void);
 MetaFocusMode               meta_prefs_get_focus_mode         (void);
+gboolean                    meta_prefs_get_orthogonal_raise   (void);
 const char*                 meta_prefs_get_theme              (void);
 /* returns NULL if GTK default should be used */
 const PangoFontDescription* meta_prefs_get_titlebar_font      (void);
Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.404
diff -p -u -r1.404 window.c
--- src/window.c	2 Jan 2006 18:48:30 -0000	1.404
+++ src/window.c	8 Jan 2006 00:54:08 -0000
@@ -2354,8 +2354,11 @@ meta_window_activate (MetaWindow *window
     meta_window_unshade (window);
 
   unminimize_window_and_all_transient_parents (window);
-  
-  meta_window_raise (window);
+
+  if (!meta_prefs_get_orthogonal_raise () ||
+      source_indication == META_CLIENT_TYPE_PAGER)
+    meta_window_raise (window);
+
   meta_topic (META_DEBUG_FOCUS,
               "Focusing window %s due to activation\n",
               window->desc);
@@ -7031,6 +7034,9 @@ meta_window_handle_mouse_grab_op_event (
   switch (event->type)
     {
     case ButtonRelease:
+      meta_display_check_threshold_reached (window->display,
+                                            event->xbutton.x_root,
+                                            event->xbutton.y_root);
       /* If the user was snap moving then ignore the button release
        * because they may have let go of shift before releasing the
        * mouse button and they almost certainly do not want a
@@ -7059,6 +7065,9 @@ meta_window_handle_mouse_grab_op_event (
       break;    
 
     case MotionNotify:
+      meta_display_check_threshold_reached (window->display,
+                                            event->xmotion.x_root,
+                                            event->xmotion.y_root);
       if (meta_grab_op_is_moving (window->display->grab_op))
         {
           if (event->xmotion.root == window->screen->xroot)
@@ -7555,8 +7564,6 @@ meta_window_begin_grab_op (MetaWindow *w
 
   grab_start_serial = XNextRequest (window->display->xdisplay);
   
-  meta_window_raise (window);
-
   warp_grab_pointer (window,
                      op, &x, &y);
 
