diff -aur metacity-2.18.5/src/core.c metacity-2.18.5-alt-tab/src/core.c
--- metacity-2.18.5/src/core.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/core.c	2007-08-07 23:48:21.000000000 +0200
@@ -256,6 +256,22 @@
             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 -aur metacity-2.18.5/src/display.c metacity-2.18.5-alt-tab/src/display.c
--- metacity-2.18.5/src/display.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/display.c	2007-08-07 23:48:21.000000000 +0200
@@ -2312,13 +2312,21 @@
                        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)
@@ -4306,7 +4314,8 @@
       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;
@@ -4347,7 +4356,8 @@
       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;
@@ -4368,8 +4378,11 @@
                            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);
+  g_return_val_if_fail (mru_list != NULL, NULL);
 
   /* Windows sellout mode - MRU order. Collect unminimized windows
    * then minimized so minimized windows aren't in the way so much.
@@ -4378,7 +4391,7 @@
     GList *tmp;
     
     tab_list = NULL;
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
@@ -4395,7 +4408,7 @@
   {
     GList *tmp;
     
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
diff -aur metacity-2.18.5/src/keybindings.c metacity-2.18.5-alt-tab/src/keybindings.c
--- metacity-2.18.5/src/keybindings.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/keybindings.c	2007-08-08 21:36:22.000000000 +0200
@@ -2446,7 +2446,11 @@
                       "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");
@@ -3319,7 +3323,9 @@
                       "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,
@@ -3349,7 +3355,9 @@
                           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 -aur metacity-2.18.5/src/prefs.c metacity-2.18.5-alt-tab/src/prefs.c
--- metacity-2.18.5/src/prefs.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/prefs.c	2007-08-08 00:00:52.000000000 +0200
@@ -91,6 +91,7 @@
 static gboolean raise_on_click = TRUE;
 static char* current_theme = NULL;
 static int num_workspaces = 4;
+static int switching_per_workspace = FALSE;
 static MetaActionDoubleClickTitlebar action_double_click_titlebar =
     META_ACTION_DOUBLE_CLICK_TITLEBAR_TOGGLE_MAXIMIZE;
 static gboolean application_based = FALSE;
@@ -139,6 +140,7 @@
 static gboolean update_visual_bell        (gboolean v1, gboolean v2);
 static gboolean update_visual_bell_type   (const char *value);
 static gboolean update_num_workspaces     (int         value);
+static gboolean update_switching_per_workspace (gboolean value);
 static gboolean update_application_based  (gboolean    value);
 static gboolean update_disable_workarounds (gboolean   value);
 static gboolean update_action_double_click_titlebar (const char *value);
@@ -456,6 +458,7 @@
                                   &err);
   cleanup_error (&err);
   update_num_workspaces (int_val);
+  update_switching_per_workspace (TRUE); /* FIXME: For now */
 
   if (get_bool (KEY_APPLICATION_BASED, &bool_val))
     update_application_based (bool_val);
@@ -1577,6 +1580,25 @@
 
 #ifdef HAVE_GCONF
 static gboolean
+update_switching_per_workspace (gboolean value)
+{
+  gboolean old = switching_per_workspace;
+
+  switching_per_workspace = value;
+  meta_verbose ("Setting per workspace = %d\n", value);
+
+  return old != switching_per_workspace;
+}
+#endif /* HAVE_GCONF */
+
+gboolean
+meta_prefs_get_switching_per_workspace (void)
+{
+  return switching_per_workspace;
+}
+
+#ifdef HAVE_GCONF
+static gboolean
 update_application_based (gboolean value)
 {
   gboolean old = application_based;
@@ -1834,6 +1856,13 @@
     }
 #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; 
+}
 
 /* Indexes must correspond to MetaKeybindingAction */
 static MetaKeyPref screen_bindings[] = {
diff -aur metacity-2.18.5/src/prefs.h metacity-2.18.5-alt-tab/src/prefs.h
--- metacity-2.18.5/src/prefs.h	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/prefs.h	2007-08-07 23:48:21.000000000 +0200
@@ -78,6 +78,7 @@
 /* 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);
@@ -96,6 +97,7 @@
 MetaActionDoubleClickTitlebar meta_prefs_get_action_double_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,
diff -aur metacity-2.18.5/src/screen.c metacity-2.18.5-alt-tab/src/screen.c
--- metacity-2.18.5/src/screen.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/screen.c	2007-08-07 23:48:21.000000000 +0200
@@ -527,6 +527,8 @@
   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;
@@ -702,6 +704,8 @@
     }
 #endif
   
+  g_list_free (screen->mru_list);
+
   meta_ui_free (screen->ui);
 
   meta_stack_free (screen->stack);
@@ -1030,14 +1034,16 @@
 
 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]);
 
@@ -1045,7 +1051,7 @@
   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);
 }
 
@@ -1171,7 +1177,8 @@
       ++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);
 }
@@ -1786,6 +1793,10 @@
   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 -aur metacity-2.18.5/src/screen.h metacity-2.18.5-alt-tab/src/screen.h
--- metacity-2.18.5/src/screen.h	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/screen.h	2007-08-07 23:48:21.000000000 +0200
@@ -120,6 +120,9 @@
 
   /* 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 -aur metacity-2.18.5/src/window.c metacity-2.18.5-alt-tab/src/window.c
--- metacity-2.18.5/src/window.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/window.c	2007-08-08 23:48:48.000000000 +0200
@@ -3998,6 +3998,9 @@
       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;
     }
 
@@ -4996,6 +4999,24 @@
           window->display->focus_window = window;
           window->has_focus = TRUE;
 
+          /* 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
@@ -7791,6 +7812,27 @@
                               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 -aur metacity-2.18.5/src/wm-tester/Makefile metacity-2.18.5-alt-tab/src/wm-tester/Makefile
diff -aur metacity-2.18.5/src/workspace.c metacity-2.18.5-alt-tab/src/workspace.c
--- metacity-2.18.5/src/workspace.c	2007-08-03 17:48:19.000000000 +0200
+++ metacity-2.18.5-alt-tab/src/workspace.c	2007-08-07 23:48:21.000000000 +0200
@@ -163,6 +163,10 @@
       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;
 
@@ -213,6 +217,10 @@
       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);
   
   meta_window_queue_calc_showing (window);
