Index: delete.c
===================================================================
RCS file: /cvs/gnome/metacity/src/delete.c,v
retrieving revision 1.5
diff -p -u -r1.5 delete.c
--- delete.c	8 Dec 2002 19:17:17 -0000	1.5
+++ delete.c	15 Aug 2003 20:41:36 -0000
@@ -23,6 +23,7 @@
 #include "util.h"
 #include "window.h"
 #include "errors.h"
+#include "workspace.h"
 
 #include <sys/types.h>
 #include <signal.h>
@@ -387,7 +388,8 @@ meta_window_delete (MetaWindow  *window,
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing top window because focus window %s was deleted/killed\n",
                   window->desc);
-      meta_screen_focus_top_window (window->screen, window);
+      meta_workspace_focus_top_window (window->screen->active_workspace,
+                                       window);
     }
   else
     {
Index: display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.191
diff -p -u -r1.191 display.c
--- display.c	26 Jun 2003 03:09:37 -0000	1.191
+++ display.c	15 Aug 2003 20:41:40 -0000
@@ -310,7 +310,6 @@ meta_display_open (const char *name)
   display->autoraise_timeout_id = 0;
   display->focus_window = NULL;
   display->expected_focus_window = NULL;
-  display->mru_list = NULL;
 
 #ifdef HAVE_XSYNC
   display->grab_update_alarm = None;
@@ -3417,6 +3416,7 @@ find_tab_forward (MetaDisplay   *display
   GList *tmp;
 
   g_return_val_if_fail (start != NULL, NULL);
+  g_return_val_if_fail (workspace != NULL, NULL);
 
   tmp = start->next;
   while (tmp != NULL)
@@ -3424,22 +3424,18 @@ find_tab_forward (MetaDisplay   *display
       MetaWindow *window = tmp->data;
 
       if (window->screen == screen &&
-	  IN_TAB_CHAIN (window, type) &&
-          (workspace == NULL ||
-           meta_window_visible_on_workspace (window, workspace)))
+	  IN_TAB_CHAIN (window, type))
         return window;
 
       tmp = tmp->next;
     }
 
-  tmp = display->mru_list;
+  tmp = workspace->mru_list;
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
 
-      if (IN_TAB_CHAIN (window, type) &&
-          (workspace == NULL ||
-           meta_window_visible_on_workspace (window, workspace)))
+      if (IN_TAB_CHAIN (window, type))
         return window;
 
       tmp = tmp->next;
@@ -3458,6 +3454,7 @@ find_tab_backward (MetaDisplay   *displa
   GList *tmp;
 
   g_return_val_if_fail (start != NULL, NULL);
+  g_return_val_if_fail (workspace != NULL, NULL);
   
   tmp = start->prev;
   while (tmp != NULL)
@@ -3465,22 +3462,18 @@ find_tab_backward (MetaDisplay   *displa
       MetaWindow *window = tmp->data;
 
       if (window->screen == screen &&
-	  IN_TAB_CHAIN (window, type) &&
-          (workspace == NULL ||
-           meta_window_visible_on_workspace (window, workspace)))
+	  IN_TAB_CHAIN (window, type))
         return window;
 
       tmp = tmp->prev;
     }
 
-  tmp = g_list_last (display->mru_list);
+  tmp = g_list_last (workspace->mru_list);
   while (tmp != start)
     {
       MetaWindow *window = tmp->data;
 
-      if (IN_TAB_CHAIN (window, type) &&
-          (workspace == NULL ||
-           meta_window_visible_on_workspace (window, workspace)))
+      if (IN_TAB_CHAIN (window, type))
         return window;
 
       tmp = tmp->prev;
@@ -3497,7 +3490,7 @@ meta_display_get_tab_list (MetaDisplay  
 {
   GList *tab_list;
 
-  /* workspace can be NULL for all workspaces */  
+  g_return_val_if_fail (workspace != NULL, NULL);
 
   /* Windows sellout mode - MRU order. Collect unminimized windows
    * then minimized so minimized windows aren't in the way so much.
@@ -3506,16 +3499,14 @@ meta_display_get_tab_list (MetaDisplay  
     GList *tmp;
     
     tab_list = NULL;
-    tmp = screen->display->mru_list;
+    tmp = workspace->mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
         
         if (!window->minimized &&
             window->screen == screen &&
-            IN_TAB_CHAIN (window, type) &&
-            (workspace == NULL ||
-             meta_window_visible_on_workspace (window, workspace)))
+            IN_TAB_CHAIN (window, type))
           tab_list = g_list_prepend (tab_list, window);
         
         tmp = tmp->next;
@@ -3525,16 +3516,14 @@ meta_display_get_tab_list (MetaDisplay  
   {
     GList *tmp;
     
-    tmp = screen->display->mru_list;
+    tmp = workspace->mru_list;
     while (tmp != NULL)
       {
         MetaWindow *window = tmp->data;
         
         if (window->minimized &&
             window->screen == screen &&
-            IN_TAB_CHAIN (window, type) &&
-            (workspace == NULL ||
-             meta_window_visible_on_workspace (window, workspace)))
+            IN_TAB_CHAIN (window, type))
           tab_list = g_list_prepend (tab_list, window);
         
         tmp = tmp->next;
Index: display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.106
diff -p -u -r1.106 display.h
--- display.h	26 Jun 2003 03:09:37 -0000	1.106
+++ display.h	15 Aug 2003 20:41:40 -0000
@@ -179,11 +179,6 @@ struct _MetaDisplay
    */
   MetaWindow *expected_focus_window;
 
-  /* Most recently focused list. Always contains all
-   * live windows.
-   */
-  GList *mru_list;  
-
   guint static_gravity_works : 1;
   
   /*< private-ish >*/
Index: keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.89
diff -p -u -r1.89 keybindings.c
--- keybindings.c	1 Jul 2003 14:59:09 -0000	1.89
+++ keybindings.c	15 Aug 2003 20:41:43 -0000
@@ -2609,7 +2609,7 @@ handle_toggle_desktop (MetaDisplay    *d
   if (screen->showing_desktop)
     {
       meta_screen_unshow_desktop (screen);
-      meta_screen_focus_top_window (screen, NULL);
+      meta_workspace_focus_top_window (screen->active_workspace, NULL);
     }
   else
     meta_screen_show_desktop (screen);
Index: screen.c
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.c,v
retrieving revision 1.109
diff -p -u -r1.109 screen.c
--- screen.c	10 Aug 2003 20:14:45 -0000	1.109
+++ screen.c	15 Aug 2003 20:41:46 -0000
@@ -1188,39 +1188,6 @@ meta_screen_ensure_workspace_popup (Meta
   /* don't show tab popup, since proper space isn't selected yet */
 }
 
-/* Focus top window on active workspace */
-void
-meta_screen_focus_top_window (MetaScreen *screen,
-                              MetaWindow *not_this_one)
-{
-  MetaWindow *window;
-
-  if (not_this_one)
-    meta_topic (META_DEBUG_FOCUS,
-                "Focusing top window excluding %s\n", not_this_one->desc);
-  
-  window = meta_stack_get_default_focus_window (screen->stack,
-                                                screen->active_workspace,
-                                                not_this_one);
-
-  /* FIXME I'm a loser on the CurrentTime front */
-  if (window)
-    {
-      meta_topic (META_DEBUG_FOCUS,
-                  "Focusing top window %s\n", window->desc);
-
-      meta_window_focus (window, meta_display_get_current_time (screen->display));
-
-      /* Also raise the window if in click-to-focus */
-      if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
-        meta_window_raise (window);
-    }
-  else
-    {
-      meta_topic (META_DEBUG_FOCUS, "No top window to focus found\n");
-    }
-}
-
 void
 meta_screen_focus_mouse_window (MetaScreen  *screen,
                                 MetaWindow  *not_this_one)
@@ -1271,16 +1238,6 @@ meta_screen_focus_mouse_window (MetaScre
     }
 }
 
-void
-meta_screen_focus_default_window (MetaScreen *screen,
-                                  MetaWindow *not_this_one)
-{
-  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
-    meta_screen_focus_top_window (screen, not_this_one);
-  else
-    meta_screen_focus_mouse_window (screen, not_this_one);
-}
-
 const MetaXineramaScreenInfo*
 meta_screen_get_xinerama_for_rect (MetaScreen    *screen,
 				   MetaRectangle *rect)
@@ -2199,7 +2156,7 @@ meta_screen_show_desktop (MetaScreen *sc
 
   update_showing_desktop_hint (screen);
 
-  meta_screen_focus_top_window (screen, NULL);
+  meta_workspace_focus_top_window (screen->active_workspace, NULL);
 }
 
 void
Index: screen.h
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.h,v
retrieving revision 1.50
diff -p -u -r1.50 screen.h
--- screen.h	26 Jun 2003 03:09:37 -0000	1.50
+++ screen.h	15 Aug 2003 20:41:46 -0000
@@ -134,13 +134,8 @@ void          meta_screen_ensure_tab_pop
 
 void          meta_screen_ensure_workspace_popup (MetaScreen *screen);
 
-void          meta_screen_focus_top_window     (MetaScreen                 *screen,
-                                                MetaWindow                 *not_this_one);
 void          meta_screen_focus_mouse_window   (MetaScreen                 *screen,
                                                 MetaWindow                 *not_this_one);
-void          meta_screen_focus_default_window (MetaScreen                 *screen,
-                                                MetaWindow                 *not_this_one);
-
 
 const MetaXineramaScreenInfo* meta_screen_get_current_xinerama    (MetaScreen    *screen);
 const MetaXineramaScreenInfo* meta_screen_get_xinerama_for_rect   (MetaScreen    *screen,
Index: window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.292
diff -p -u -r1.292 window.c
--- window.c	28 Jul 2003 02:09:19 -0000	1.292
+++ window.c	15 Aug 2003 20:41:52 -0000
@@ -657,10 +657,6 @@ meta_window_new (MetaDisplay *display,
                                     window->size_hints.width,
                                     window->size_hints.height);
 
-  /* add to MRU list */
-  window->display->mru_list =
-    g_list_append (window->display->mru_list, window);
-  
   meta_stack_add (window->screen->stack, 
                   window);
 
@@ -883,7 +879,7 @@ meta_window_free (MetaWindow  *window)
       meta_topic (META_DEBUG_FOCUS,
                   "Focusing top window since we're unmanaging %s\n",
                   window->desc);
-      meta_screen_focus_top_window (window->screen, window);
+      meta_workspace_focus_top_window (window->screen->active_workspace, window);
     }
   else if (window->display->expected_focus_window == window)
     {
@@ -891,7 +887,7 @@ meta_window_free (MetaWindow  *window)
                   "Focusing top window since expected focus window freed %s\n",
                   window->desc);
       window->display->expected_focus_window = NULL;
-      meta_screen_focus_top_window (window->screen, window);
+      meta_workspace_focus_top_window (window->screen->active_workspace, window);
     }
   else
     {
@@ -920,9 +916,6 @@ meta_window_free (MetaWindow  *window)
   if (window->display->focus_window == window)
     window->display->focus_window = NULL;
 
-  window->display->mru_list =
-    g_list_remove (window->display->mru_list, window);
-  
   meta_window_unqueue_calc_showing (window);
   meta_window_unqueue_move_resize (window);
   meta_window_unqueue_update_icon (window);
@@ -1763,7 +1756,7 @@ meta_window_minimize (MetaWindow  *windo
           meta_topic (META_DEBUG_FOCUS,
                       "Focusing top window due to minimization of focus window %s\n",
                       window->desc);
-          meta_screen_focus_top_window (window->screen, window);
+          meta_workspace_focus_top_window (window->screen->active_workspace, window);
         }
       else
         {
@@ -3194,6 +3187,9 @@ meta_window_change_workspace (MetaWindow
 void
 meta_window_stick (MetaWindow  *window)
 {
+  GList *tmp; 
+  MetaWorkspace *workspace;
+
   meta_verbose ("Sticking window %s current on_all_workspaces = %d\n",
                 window->desc, window->on_all_workspaces);
   
@@ -3206,6 +3202,18 @@ meta_window_stick (MetaWindow  *window)
    */
   window->on_all_workspaces = TRUE;
 
+  /* We do, however, change the MRU lists of all the workspaces
+   */
+  tmp = window->workspaces;
+  while (tmp)
+    {
+      workspace = (MetaWorkspace *) tmp->data;
+      if (!g_list_find (workspace->mru_list, window))
+          g_list_append (workspace->mru_list, window);
+
+      tmp = tmp->next;
+    }
+
   meta_window_set_current_workspace_hint (window);
   
   meta_window_queue_calc_showing (window);
@@ -3214,6 +3222,9 @@ meta_window_stick (MetaWindow  *window)
 void
 meta_window_unstick (MetaWindow  *window)
 {
+  GList *tmp;
+  MetaWorkspace *workspace;
+
   if (!window->on_all_workspaces)
     return;
 
@@ -3221,6 +3232,16 @@ meta_window_unstick (MetaWindow  *window
 
   window->on_all_workspaces = FALSE;
 
+  /* Remove window from MRU lists that it doesn't belong in */
+  tmp = window->workspaces;
+  while (tmp)
+    {
+      workspace = (MetaWorkspace *) tmp->data;
+      if (!meta_workspace_contains_window (workspace, window))
+          g_list_remove (workspace->mru_list, window);
+      tmp = tmp->next;
+    }
+
   /* We change ourselves to the active workspace, since otherwise you'd get
    * a weird window-vaporization effect. Once we have UI for being
    * on more than one workspace this should probably be add_workspace
@@ -3946,11 +3967,21 @@ meta_window_notify_focus (MetaWindow *wi
                       "* Focus --> %s\n", window->desc);
           window->display->focus_window = window;
           window->has_focus = TRUE;
-          /* Move to the front of the MRU list */
-          window->display->mru_list =
-            g_list_remove (window->display->mru_list, window);
-          window->display->mru_list =
-            g_list_prepend (window->display->mru_list, window);
+
+          /* Move to the front of the focusing workspace's MRU list
+	   * FIXME: is the active workspace guaranteed to be the focusing
+	   *        workspace?
+           */
+          if (window->screen->active_workspace)
+            {
+              window->screen->active_workspace->mru_list = 
+                g_list_remove (window->screen->active_workspace->mru_list, 
+                               window);
+              window->screen->active_workspace->mru_list = 
+                g_list_prepend (window->screen->active_workspace->mru_list, 
+                                window);
+            }
+
           if (window->frame)
             meta_frame_queue_draw (window->frame);
           
Index: workspace.c
===================================================================
RCS file: /cvs/gnome/metacity/src/workspace.c,v
retrieving revision 1.45
diff -p -u -r1.45 workspace.c
--- workspace.c	28 Jun 2003 16:12:32 -0000	1.45
+++ workspace.c	15 Aug 2003 20:41:53 -0000
@@ -41,6 +41,7 @@ meta_workspace_new (MetaScreen *screen)
   workspace->screen->workspaces =
     g_list_append (workspace->screen->workspaces, workspace);
   workspace->windows = NULL;
+  workspace->mru_list = NULL;
 
   workspace->work_areas = NULL;
   workspace->work_areas_invalid = TRUE;
@@ -113,6 +114,8 @@ meta_workspace_add_window (MetaWorkspace
   workspace->windows = g_list_prepend (workspace->windows, window);
   window->workspaces = g_list_prepend (window->workspaces, workspace);
 
+  workspace->mru_list = g_list_append (workspace->mru_list, window);
+
   meta_window_set_current_workspace_hint (window);
   
   meta_window_queue_calc_showing (window);
@@ -138,6 +141,7 @@ meta_workspace_remove_window (MetaWorksp
 
   workspace->windows = g_list_remove (workspace->windows, window);
   window->workspaces = g_list_remove (window->workspaces, workspace);
+  workspace->mru_list = g_list_remove (workspace->mru_list, window);
 
   meta_window_set_current_workspace_hint (window);
   
@@ -239,7 +243,7 @@ meta_workspace_activate_with_focus (Meta
   else
     {
       meta_topic (META_DEBUG_FOCUS, "Focusing default window on new workspace\n");
-      meta_screen_focus_default_window (workspace->screen, NULL);
+      meta_workspace_focus_default_window (workspace, NULL);
     }
 }
 
@@ -686,4 +690,92 @@ const char*
 meta_workspace_get_name (MetaWorkspace *workspace)
 {
   return meta_prefs_get_workspace_name (meta_workspace_index (workspace));
+}
+
+void
+meta_workspace_focus_default_window (MetaWorkspace *workspace,
+                                     MetaWindow *not_this_one)
+{
+  if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+    meta_workspace_focus_mru_window (workspace, not_this_one);
+  else
+    meta_screen_focus_mouse_window (workspace->screen, not_this_one);
+}
+
+/* Focus MRU window (or top window if failed) on active workspace */
+void
+meta_workspace_focus_mru_window (MetaWorkspace *workspace,
+                                 MetaWindow *not_this_one)
+{
+  MetaWindow *window = NULL;
+  GList *tmp;
+
+  if (not_this_one)
+    meta_topic (META_DEBUG_FOCUS,
+                "Focusing MRU window excluding %s\n", not_this_one->desc);
+  
+  tmp = workspace->mru_list;  
+
+  while (tmp)
+    {
+      if (((MetaWindow*) tmp->data) != not_this_one)
+        {
+          window = tmp->data;
+	  break;
+        }
+
+      tmp = tmp->next;
+    }
+
+  if (window)
+    {
+      meta_topic (META_DEBUG_FOCUS,
+                  "Focusing workspace MRU window %s\n", window->desc);
+      
+      meta_window_focus (window,
+                         meta_display_get_current_time (workspace->screen->display));
+
+      /* Also raise the window if in click-to-focus */
+      if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+        meta_window_raise (window);
+    }
+  else
+    {
+      meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found\n");
+      meta_workspace_focus_top_window (workspace, not_this_one);
+    }
+}
+
+/* Focus top window on workspace */
+void
+meta_workspace_focus_top_window (MetaWorkspace *workspace,
+                                 MetaWindow    *not_this_one)
+{
+  MetaWindow *window;
+
+  if (not_this_one)
+    meta_topic (META_DEBUG_FOCUS,
+                "Focusing top window excluding %s\n", not_this_one->desc);
+  
+  window = meta_stack_get_default_focus_window (workspace->screen->stack,
+                                                workspace,
+                                                not_this_one);
+
+  /* FIXME I'm a loser on the CurrentTime front */
+  if (window)
+    {
+      meta_topic (META_DEBUG_FOCUS,
+                  "Focusing top window %s\n", window->desc);
+
+      meta_window_focus (window, 
+	                 meta_display_get_current_time (workspace->screen->display));
+
+      /* Also raise the window if in click-to-focus */
+      if (meta_prefs_get_focus_mode () == META_FOCUS_MODE_CLICK)
+        meta_window_raise (window);
+    }
+  else
+    {
+      meta_topic (META_DEBUG_FOCUS, "No top window to focus found\n");
+    }
 }
Index: workspace.h
===================================================================
RCS file: /cvs/gnome/metacity/src/workspace.h,v
retrieving revision 1.16
diff -p -u -r1.16 workspace.h
--- workspace.h	26 Jun 2003 03:09:37 -0000	1.16
+++ workspace.h	15 Aug 2003 20:41:53 -0000
@@ -40,6 +40,7 @@ struct _MetaWorkspace
   MetaScreen *screen;
   
   GList *windows;
+  GList *mru_list;
 
   MetaRectangle all_work_areas;
   MetaRectangle *work_areas;
@@ -76,9 +77,12 @@ void meta_workspace_get_work_area_for_xi
 void meta_workspace_get_work_area_all_xineramas (MetaWorkspace *workspace,
                                                  MetaRectangle *area);
 
-
-
-
+void meta_workspace_focus_mru_window     (MetaWorkspace *workspace,
+                                          MetaWindow    *not_this_one);
+void meta_workspace_focus_default_window (MetaWorkspace *workspace,
+                                          MetaWindow    *not_this_one);
+void meta_workspace_focus_top_window     (MetaWorkspace *workspace,
+                                          MetaWindow    *not_this_one);
 
 MetaWorkspace* meta_workspace_get_neighbor (MetaWorkspace      *workspace,
                                             MetaMotionDirection direction);
