Index: workspace.c
===================================================================
--- workspace.c	(revision 3285)
+++ workspace.c	(working copy)
@@ -163,6 +163,10 @@
       workspace->mru_list = g_list_prepend (workspace->mru_list, window);
     }
 
+  /* Also put it in the global MRU list */
+  if (!g_list_find (workspace->screen->mru_list, window))
+    workspace->screen->mru_list =  g_list_prepend (workspace->screen->mru_list, window);
+
   workspace->windows = g_list_prepend (workspace->windows, window);
   window->workspace = workspace;
 
@@ -212,6 +216,10 @@
       g_assert (g_list_find (workspace->mru_list, window) == NULL);
     }
 
+  /* also remove it from the global MRU list */
+  workspace->screen->mru_list = 
+      g_list_remove (workspace->screen->mru_list, window);
+
   meta_window_set_current_workspace_hint (window);
   
   if (window->struts)
Index: display.c
===================================================================
--- display.c	(revision 3285)
+++ display.c	(working copy)
@@ -2247,13 +2247,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)
@@ -4232,7 +4240,7 @@
       tmp = tmp->next;
     }
 
-  tmp = workspace->mru_list;
+  tmp = screen->mru_list;
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
@@ -4273,7 +4281,7 @@
       tmp = tmp->prev;
     }
 
-  tmp = g_list_last (workspace->mru_list);
+  tmp = g_list_last (screen->mru_list);
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
@@ -4294,6 +4302,8 @@
                            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);
 
@@ -4304,7 +4314,7 @@
     GList *tmp;
     
     tab_list = NULL;
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
@@ -4321,7 +4331,7 @@
   {
     GList *tmp;
     
-    tmp = workspace->mru_list;
+    tmp = mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
Index: keybindings.c
===================================================================
--- keybindings.c	(revision 3285)
+++ keybindings.c	(working copy)
@@ -2449,8 +2449,12 @@
                       "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");
           meta_display_end_grab_op (display, event->xkey.time);
Index: prefs.c
===================================================================
--- prefs.c	(revision 3285)
+++ prefs.c	(working copy)
@@ -93,6 +93,7 @@
 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;
@@ -129,6 +130,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_titlebar    (const char *key, const char *value, MetaActionTitlebar *action);
@@ -458,6 +460,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);
@@ -1615,6 +1618,25 @@
 
 #ifdef HAVE_GCONF
 static gboolean
+update_switching_per_workspace (gboolean value)
+{
+  gboolean old = switching_per_workspace;
+
+  switching_per_workspace = value;
+  meta_warning("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;
@@ -1882,6 +1904,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[] = {
Index: prefs.h
===================================================================
--- prefs.h	(revision 3285)
+++ prefs.h	(working copy)
@@ -80,6 +80,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);
@@ -102,6 +103,7 @@
 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,
Index: screen.c
===================================================================
--- screen.c	(revision 3285)
+++ screen.c	(working copy)
@@ -531,6 +531,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;
@@ -706,6 +708,8 @@
     }
 #endif
   
+  g_list_free (screen->mru_list);
+
   meta_ui_free (screen->ui);
 
   meta_stack_free (screen->stack);
@@ -1034,22 +1038,24 @@
 
 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]);
+  meta_warning ("Setting _NET_NUMBER_OF_DESKTOPS to %lu\n", data[0]);
 
   meta_error_trap_push (screen->display);
   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);
 }
 
@@ -1175,7 +1181,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);
 }
@@ -1790,6 +1797,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
    */
Index: screen.h
===================================================================
--- screen.h	(revision 3285)
+++ screen.h	(working copy)
@@ -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,
Index: core.c
===================================================================
--- core.c	(revision 3285)
+++ core.c	(working copy)
@@ -287,6 +287,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 */
Index: window.c
===================================================================
--- window.c	(revision 3285)
+++ window.c	(working copy)
@@ -4061,6 +4061,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;
     }
 
@@ -5102,6 +5105,23 @@
           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
@@ -7871,6 +7891,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->active_workspace->mru_list =
+        g_list_insert_before (window->screen->mru_list, after_this_one_position->next,
+                              window);
+    }
 }
 
 void
