diff -pNaur metacity-2.26.0-orig/src/core/core.c metacity-2.26.0/src/core/core.c
--- metacity-2.26.0-orig/src/core/core.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/core.c	2009-07-25 14:23:52.000000000 +0200
@@ -287,6 +287,22 @@ meta_core_user_lower_and_unfocus (Displa
             g_list_append (window->screen->active_workspace->mru_list, 
                            window);
         }
+ 
+      /* Also move the window to the end of the global MRU list
+       */
+      if (window->screen)
+        {
+          GList* link;
+          link = g_list_find (window->screen->mru_list, window);
+          g_assert (link);
+
+          window->screen->mru_list = 
+            g_list_remove_link (window->screen->mru_list, link);
+          g_list_free (link);
+
+          window->screen->mru_list = 
+            g_list_append (window->screen->mru_list, window);
+        }
     }
 
   /* focus the default window, if needed */
diff -pNaur metacity-2.26.0-orig/src/core/display.c metacity-2.26.0/src/core/display.c
--- metacity-2.26.0-orig/src/core/display.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/display.c	2009-07-25 14:23:52.000000000 +0200
@@ -2262,13 +2262,21 @@ event_callback (XEvent   *event,
                        display->atom__NET_NUMBER_OF_DESKTOPS)
                 {
                   int num_spaces;
+		  gboolean switching_per_workspace;
               
                   num_spaces = event->xclient.data.l[0];
+		  switching_per_workspace = event->xclient.data.l[1] != 0;
               
-                  meta_verbose ("Request to set number of workspaces to %d\n",
-                                num_spaces);
+                  meta_verbose ("Request to set number of workspaces to %d"
+                                " with switching per %s\n",
+                                num_spaces,
+                                switching_per_workspace? "workspace": "screen");
 
                   meta_prefs_set_num_workspaces (num_spaces);
+                  meta_prefs_set_switching_per_workspace (switching_per_workspace);
+
+                  /* FIXME: Temporary hack until we integrate properly with gconf */
+                  meta_screen_update_workspace_names (screen);
                 }
               else if (event->xclient.message_type ==
                        display->atom__NET_SHOWING_DESKTOP)
@@ -4316,7 +4324,8 @@ find_tab_forward (MetaDisplay   *display
       tmp = tmp->next;
     }
 
-  tmp = workspace->mru_list;
+  tmp = meta_prefs_get_switching_per_workspace() ? workspace->mru_list : screen->mru_list;
+  g_assert (tmp);
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
@@ -4357,7 +4366,8 @@ find_tab_backward (MetaDisplay   *displa
       tmp = tmp->prev;
     }
 
-  tmp = g_list_last (workspace->mru_list);
+  tmp = g_list_last (meta_prefs_get_switching_per_workspace() ? workspace->mru_list : screen->mru_list);
+  g_assert (tmp);
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
@@ -4378,6 +4388,8 @@ meta_display_get_tab_list (MetaDisplay  
                            MetaWorkspace *workspace)
 {
   GList *tab_list;
+  GList *mru_list = meta_prefs_get_switching_per_workspace() ?
+    workspace->mru_list : screen->mru_list;
 
   g_return_val_if_fail (workspace != NULL, NULL);
 
@@ -4388,7 +4400,7 @@ meta_display_get_tab_list (MetaDisplay  
     GList *tmp;
     
     tab_list = NULL;
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
@@ -4405,7 +4417,7 @@ meta_display_get_tab_list (MetaDisplay  
   {
     GList *tmp;
     
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
diff -pNaur metacity-2.26.0-orig/src/core/keybindings.c metacity-2.26.0/src/core/keybindings.c
--- metacity-2.26.0-orig/src/core/keybindings.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/keybindings.c	2009-07-25 14:23:52.000000000 +0200
@@ -2028,7 +2028,11 @@ process_tab_grab (MetaDisplay *display,
                       "selection and turning mouse_mode off\n",
                       target_window->desc);
           display->mouse_mode = FALSE;
-          meta_window_activate (target_window, event->xkey.time);
+
+          if (screen->active_workspace == target_window->workspace)
+            meta_window_activate (target_window, event->xkey.time);
+          else
+            meta_workspace_activate_with_focus (target_window->workspace, target_window, event->xkey.time);
 
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Ending grab early so we can focus the target window\n");
@@ -2885,7 +2889,9 @@ do_choose_window (MetaDisplay    *displa
                       "switch/cycle windows with no modifiers\n",
                       initial_selection->desc);
           display->mouse_mode = FALSE;
-          meta_window_activate (initial_selection, event->xkey.time);
+
+          /* keep window on workspace - rather switch workspace then move window */
+          meta_window_activate_with_workspace (initial_selection, event->xkey.time, initial_selection->workspace);
         }
       else if (meta_display_begin_grab_op (display,
                                            screen,
@@ -2914,7 +2920,9 @@ do_choose_window (MetaDisplay    *displa
                           initial_selection->desc);
               meta_display_end_grab_op (display, event->xkey.time);
               display->mouse_mode = FALSE;
-              meta_window_activate (initial_selection, event->xkey.time);
+
+              /* keep window on workspace - rather switch workspace then move window */
+              meta_window_activate_with_workspace (initial_selection, event->xkey.time, initial_selection->workspace);
             }
           else
             {
diff -pNaur metacity-2.26.0-orig/src/core/prefs.c metacity-2.26.0/src/core/prefs.c
--- metacity-2.26.0-orig/src/core/prefs.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/prefs.c	2009-07-25 14:24:48.000000000 +0200
@@ -79,6 +79,7 @@ static MetaFocusNewWindows focus_new_win
 static gboolean raise_on_click = TRUE;
 static char* current_theme = NULL;
 static int num_workspaces = 4;
+static int switching_per_workspace = FALSE;
 static MetaActionTitlebar action_double_click_titlebar = META_ACTION_TITLEBAR_TOGGLE_MAXIMIZE;
 static MetaActionTitlebar action_middle_click_titlebar = META_ACTION_TITLEBAR_LOWER;
 static MetaActionTitlebar action_right_click_titlebar = META_ACTION_TITLEBAR_MENU;
@@ -409,6 +410,11 @@ static MetaBoolPreference preferences_bo
       &resize_with_right_button,
       FALSE,
     },
+    { "/apps/metacity/general/switch_per_workspace",
+      META_PREF_COMPOSITING_MANAGER,
+      &compositing_manager,
+      TRUE,
+    },
     { NULL, 0, NULL, FALSE },
   };
 
@@ -1640,6 +1646,12 @@ meta_prefs_get_num_workspaces (void)
 }
 
 gboolean
+meta_prefs_get_switching_per_workspace (void)
+{
+  return switching_per_workspace;
+}
+
+gboolean
 meta_prefs_get_application_based (void)
 {
   return FALSE; /* For now, we never want this to do anything */
@@ -1787,6 +1799,13 @@ meta_prefs_set_num_workspaces (int n_wor
 #endif /* HAVE_GCONF */
 }
 
+void
+meta_prefs_set_switching_per_workspace (gboolean whether)
+{
+  /* FIXME: For now, until we use gconf and the prefs queue */
+  switching_per_workspace = whether; 
+}
+
 #define keybind(name, handler, param, flags, stroke, description) \
   { #name, NULL, !!(flags & BINDING_REVERSES), !!(flags & BINDING_PER_WINDOW) },
 static MetaKeyPref key_bindings[] = {
diff -pNaur metacity-2.26.0-orig/src/core/screen.c metacity-2.26.0/src/core/screen.c
--- metacity-2.26.0-orig/src/core/screen.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/screen.c	2009-07-25 14:23:52.000000000 +0200
@@ -471,6 +471,8 @@ meta_screen_new (MetaDisplay *display,
   screen->default_xvisual = DefaultVisualOfScreen (screen->xscreen);
   screen->default_depth = DefaultDepthOfScreen (screen->xscreen);
   screen->flash_window = None;
+  
+  screen->mru_list = NULL;
 
   screen->wm_sn_selection_window = new_wm_sn_owner;
   screen->wm_sn_atom = wm_sn_atom;
@@ -650,7 +652,9 @@ meta_screen_free (MetaScreen *screen,
       screen->sn_context = NULL;
     }
 #endif
-  
+
+  g_list_free (screen->mru_list);
+
   meta_ui_free (screen->ui);
 
   meta_stack_free (screen->stack);
@@ -1007,14 +1011,16 @@ meta_screen_get_workspace_by_index (Meta
 
 static void
 set_number_of_spaces_hint (MetaScreen *screen,
-			   int         n_spaces)
+			   int         n_spaces,
+			   gboolean    switching_per_workspace)
 {
-  unsigned long data[1];
+  unsigned long data[2];
 
   if (screen->closing > 0)
     return;
 
   data[0] = n_spaces;
+  data[1] = switching_per_workspace? 1: 0;
 
   meta_verbose ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
 
@@ -1022,7 +1028,7 @@ set_number_of_spaces_hint (MetaScreen *s
   XChangeProperty (screen->display->xdisplay, screen->xroot,
                    screen->display->atom__NET_NUMBER_OF_DESKTOPS,
                    XA_CARDINAL,
-                   32, PropModeReplace, (guchar*) data, 1);
+                   32, PropModeReplace, (guchar*) data, 2);
   meta_error_trap_pop (screen->display, FALSE);
 }
 
@@ -1148,7 +1154,8 @@ update_num_workspaces (MetaScreen *scree
       ++i;
     }
 
-  set_number_of_spaces_hint (screen, new_num);
+  set_number_of_spaces_hint (screen, new_num,
+      meta_prefs_get_switching_per_workspace ());
 
   meta_screen_queue_workarea_recalc (screen);
 }
@@ -1839,6 +1846,10 @@ meta_screen_update_workspace_names (Meta
   int n_names;
   int i;
 
+  /* FIXME: Temporarily we also update the number of spaces */ 
+  update_num_workspaces (screen,
+      meta_display_get_current_time_roundtrip (screen->display));
+
   /* this updates names in prefs when the root window property changes,
    * iff the new property contents don't match what's already in prefs
    */
diff -pNaur metacity-2.26.0-orig/src/core/screen-private.h metacity-2.26.0/src/core/screen-private.h
--- metacity-2.26.0-orig/src/core/screen-private.h	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/screen-private.h	2009-07-25 14:23:52.000000000 +0200
@@ -132,6 +132,9 @@ struct _MetaScreen
 
   /* Managed by compositor.c */
   gpointer compositor_data;
+  
+  /* This list maintains a list of all windows in MRU order */
+  GList *mru_list;
 };
 
 MetaScreen*   meta_screen_new                 (MetaDisplay                *display,
diff -pNaur metacity-2.26.0-orig/src/core/window.c metacity-2.26.0/src/core/window.c
--- metacity-2.26.0-orig/src/core/window.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/window.c	2009-07-25 14:23:52.000000000 +0200
@@ -4240,6 +4240,9 @@ window_stick_impl (MetaWindow  *window)
       if (!g_list_find (workspace->mru_list, window))
         workspace->mru_list = g_list_prepend (workspace->mru_list, window);
 
+      if (!g_list_find (window->screen->mru_list, window))
+        window->screen->mru_list = g_list_prepend (window->screen->mru_list, window);
+
       tmp = tmp->next;
     }
 
@@ -5318,6 +5321,24 @@ meta_window_notify_focus (MetaWindow *wi
           meta_compositor_set_active_window (window->display->compositor,
                                              window->screen, window);
 
+          /* Move to the front of the global MRU list. We should only 
+           * be "removing" it from the MRU list if it's not already 
+           * there.
+           */
+            {
+              GList* link;
+              link = g_list_find (window->screen->mru_list, window);
+              g_assert (link);
+
+              window->screen->mru_list = 
+                g_list_remove_link (window->screen->mru_list, link);
+
+              g_list_free (link);
+
+              window->screen->mru_list = 
+                g_list_prepend (window->screen->mru_list, window);
+            }
+
           /* Move to the front of the focusing workspace's MRU list.
            * We should only be "removing" it from the MRU list if it's
            * not already there.  Note that it's possible that we might
@@ -7961,6 +7982,26 @@ ensure_mru_position_after (MetaWindow *w
                               after_this_one_position->next,
                               window);
     }
+
+  /* we need to do the same again for the global MRU list
+   */
+
+  active_mru_list         = window->screen->mru_list;
+  window_position         = g_list_find (active_mru_list, window);
+  after_this_one_position = g_list_find (active_mru_list, after_this_one);
+
+  if (after_this_one_position == NULL)
+    return;
+
+  if (g_list_length (window_position) > g_list_length (after_this_one_position))
+    {
+      window->screen->mru_list =
+        g_list_delete_link (window->screen->mru_list, window_position);
+
+      window->screen->mru_list =
+        g_list_insert_before (window->screen->mru_list, after_this_one_position->next,
+                              window);
+    }
 }
 
 void
diff -pNaur metacity-2.26.0-orig/src/core/workspace.c metacity-2.26.0/src/core/workspace.c
--- metacity-2.26.0-orig/src/core/workspace.c	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/core/workspace.c	2009-07-25 14:23:52.000000000 +0200
@@ -199,6 +199,10 @@ meta_workspace_add_window (MetaWorkspace
       workspace->mru_list = g_list_prepend (workspace->mru_list, window);
     }
 
+  /* Put it in the global MRU list as well */
+  if (!g_list_find (window->screen->mru_list, window))
+    window->screen->mru_list = g_list_prepend (window->screen->mru_list, window);
+
   workspace->windows = g_list_prepend (workspace->windows, window);
   window->workspace = workspace;
 
@@ -248,6 +252,10 @@ meta_workspace_remove_window (MetaWorksp
       g_assert (g_list_find (workspace->mru_list, window) == NULL);
     }
 
+  /* Remove it from the global MRU list as well */
+  window->screen->mru_list = g_list_remove (window->screen->mru_list, window);
+  g_assert (g_list_find (window->screen->mru_list, window) == NULL);
+
   meta_window_set_current_workspace_hint (window);
   
   if (window->struts)
diff -pNaur metacity-2.26.0-orig/src/include/prefs.h metacity-2.26.0/src/include/prefs.h
--- metacity-2.26.0-orig/src/include/prefs.h	2009-07-25 14:23:49.000000000 +0200
+++ metacity-2.26.0/src/include/prefs.h	2009-07-25 14:23:52.000000000 +0200
@@ -83,6 +83,7 @@ const char*                 meta_prefs_g
 /* returns NULL if GTK default should be used */
 const PangoFontDescription* meta_prefs_get_titlebar_font      (void);
 int                         meta_prefs_get_num_workspaces     (void);
+gboolean                    meta_prefs_get_switching_per_workspace (void);
 gboolean                    meta_prefs_get_application_based  (void);
 gboolean                    meta_prefs_get_disable_workarounds (void);
 gboolean                    meta_prefs_get_auto_raise         (void);
@@ -106,6 +107,7 @@ MetaActionTitlebar          meta_prefs_g
 MetaActionTitlebar          meta_prefs_get_action_right_click_titlebar (void);
 
 void meta_prefs_set_num_workspaces (int n_workspaces);
+void meta_prefs_set_switching_per_workspace (gboolean whether);
 
 const char* meta_prefs_get_workspace_name    (int         i);
 void        meta_prefs_change_workspace_name (int         i,
