Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/metacity/ChangeLog,v
retrieving revision 1.1154
diff -p -u -r1.1154 ChangeLog
--- ChangeLog	24 Jan 2006 01:07:36 -0000	1.1154
+++ ChangeLog	27 Jan 2006 22:53:54 -0000
@@ -1,3 +1,25 @@
+2005-06-10  Leena Gunda  <leena.gunda@wipro.com>
+
+	Added a keybinding to allow users to switch between the screens 
+	in multihead setup only.  Fixes #101659.
+
+	* src/display.c (grab_op_is_keyboard), 
+	(meta_display_begin_grab_op), (meta_display_end_grab_op):
+	* src/keybindings.c (rebuild_binding_table), 
+	(meta_display_process_key_event), (process_screen_switch_grab), 
+	(find_screen_neighbor), (handle_move_to_screen): Functions 
+	to move between screens in tabpopup and to switch to the screen 
+	selected by user.
+	* src/metacity.schemas.in: Add gconf keys switch_screen and 
+	switch_screen_backward.
+	* src/prefs.c: Add the keys to switch screen to screen_binding 
+	table.
+	* src/prefs.h: Define the keybinding and keybinding action for 
+	switch screen.
+	* src/screen.[ch] (meta_screen_ensure_screen_popup) :
+	Create the tabpopup for screen switching.
+	* src/common.h: Add enum for screen switching.
+
 2006-01-23  Elijah Newren  <newren gmail com>
 
 	* src/display.c (meta_display_check_threshold_reached): change the
Index: src/common.h
===================================================================
RCS file: /cvs/gnome/metacity/src/common.h,v
retrieving revision 1.36
diff -p -u -r1.36 common.h
--- src/common.h	21 Jan 2006 19:18:51 -0000	1.36
+++ src/common.h	27 Jan 2006 22:53:54 -0000
@@ -118,6 +118,7 @@ typedef enum
   META_GRAB_OP_KEYBOARD_ESCAPING_DOCK,
   
   META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
+  META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING,
   
   /* Frame button ops */
   META_GRAB_OP_CLICKING_MINIMIZE,
Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.275
diff -p -u -r1.275 display.c
--- src/display.c	24 Jan 2006 01:07:41 -0000	1.275
+++ src/display.c	27 Jan 2006 22:53:55 -0000
@@ -1091,6 +1091,7 @@ grab_op_is_keyboard (MetaGrabOp op)
     case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
     case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
     case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
+    case META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING:
       return TRUE;
 
     default:
@@ -3188,15 +3189,22 @@ meta_display_set_grab_op_cursor (MetaDis
     }
   else
     {
+      Window confine_to;
       g_assert (screen != NULL);
 
+      /* Avoid funky pointer warping in dual head (non-xinerama) mode */
+      if (grab_op_is_keyboard (op))
+        confine_to = None;
+      else
+        confine_to = screen->xroot;
+
       meta_error_trap_push (display);
       if (XGrabPointer (display->xdisplay,
                         grab_xwindow,
                         False,
                         GRAB_MASK,
                         GrabModeAsync, GrabModeAsync,
-                        screen->xroot,
+                        confine_to,
                         cursor,
                         timestamp) == GrabSuccess)
         {
@@ -3472,6 +3480,10 @@ meta_display_begin_grab_op (MetaDisplay 
       meta_screen_ensure_workspace_popup (screen);
       break;
 
+    case META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING:
+      meta_screen_ensure_screen_popup (screen);
+      break;
+
     default:
       break;
     }
@@ -3514,7 +3526,8 @@ meta_display_end_grab_op (MetaDisplay *d
     }
 
   if (GRAB_OP_IS_WINDOW_SWITCH (display->grab_op) ||
-      display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING)
+      display->grab_op == META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING ||
+      display->grab_op == META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING)
     {
       meta_ui_tab_popup_free (display->grab_screen->tab_popup);
       display->grab_screen->tab_popup = NULL;
Index: src/keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.123
diff -p -u -r1.123 keybindings.c
--- src/keybindings.c	20 Jan 2006 22:03:55 -0000	1.123
+++ src/keybindings.c	27 Jan 2006 22:53:55 -0000
@@ -50,6 +50,10 @@ typedef void (* MetaKeyHandlerFunc) (Met
                                      XEvent         *event,
                                      MetaKeyBinding *binding);
 
+static int find_screen_neighbor (MetaDisplay    *display,
+                                 MetaScreen     *screen,
+                                 int             backward);
+
 static void handle_activate_workspace (MetaDisplay    *display,
                                        MetaScreen     *screen,
                                        MetaWindow     *window,
@@ -90,6 +94,16 @@ static void handle_toggle_desktop     (M
                                        MetaWindow     *window,
                                        XEvent         *event,
                                        MetaKeyBinding *binding);
+static void handle_switch_to_screen   (MetaDisplay    *display,
+                                       MetaScreen     *screen,
+                                       MetaWindow     *window,
+                                       XEvent         *event,
+                                       MetaKeyBinding *binding);
+static void handle_switch_to_screen_backward (MetaDisplay    *display,
+                                              MetaScreen     *screen,
+                                              MetaWindow     *window,
+                                              XEvent         *event,
+                                              MetaKeyBinding *binding);
 static void handle_panel_keybinding   (MetaDisplay    *display,
                                        MetaScreen     *screen,
                                        MetaWindow     *window,
@@ -219,6 +233,11 @@ static gboolean process_workspace_switch
                                                XEvent      *event,
                                                KeySym       keysym);
 
+static gboolean process_screen_switch_grab (MetaDisplay *display,
+                                            MetaScreen  *screen,
+                                            XEvent      *event,
+                                            KeySym       keysym);
+
 static void regrab_screen_bindings         (MetaDisplay *display);
 static void regrab_window_bindings         (MetaDisplay *display);
 
@@ -290,6 +309,10 @@ static const MetaKeyHandler screen_handl
     GINT_TO_POINTER (META_TAB_LIST_DOCKS) },  
   { META_KEYBINDING_SHOW_DESKTOP, handle_toggle_desktop,
     NULL },
+  { META_KEYBINDING_SWITCH_SCREEN, handle_switch_to_screen,
+    NULL },
+  { META_KEYBINDING_SWITCH_SCREEN_BACKWARD, handle_switch_to_screen_backward,
+    NULL },
   { META_KEYBINDING_PANEL_MAIN_MENU, handle_panel_keybinding,
     GINT_TO_POINTER (META_KEYBINDING_ACTION_PANEL_MAIN_MENU) },
   { META_KEYBINDING_PANEL_RUN_DIALOG, handle_panel_keybinding,
@@ -655,7 +678,7 @@ rebuild_binding_table (MetaDisplay      
                        int                 n_prefs)
 {
   int n_bindings;
-  int src, dest;
+  int src, dest, skipped;
   
   n_bindings = count_bindings (prefs, n_prefs);
   g_free (*bindings_p);
@@ -663,10 +686,26 @@ rebuild_binding_table (MetaDisplay      
 
   src = 0;
   dest = 0;
+  skipped = 0;
   while (src < n_prefs)
     {
       if (prefs[src].keysym != None)
         {
+          if (strcmp (prefs[src].name,
+                      META_KEYBINDING_SWITCH_SCREEN) == 0 ||
+              strcmp (prefs[src].name,
+                      META_KEYBINDING_SWITCH_SCREEN_BACKWARD) == 0)
+            {
+              if (ScreenCount (display->xdisplay) <= 1)
+                {
+                  meta_topic (META_DEBUG_KEYBINDINGS,
+                              "Multihead setup not found. Not binding switch screen key.\n");
+                  ++src;
+                  ++skipped;
+                  continue;
+                }
+            }
+
           (*bindings_p)[dest].name = prefs[src].name;
           (*bindings_p)[dest].keysym = prefs[src].keysym;
           (*bindings_p)[dest].modifiers = prefs[src].modifiers;
@@ -696,8 +735,7 @@ rebuild_binding_table (MetaDisplay      
       ++src;
     }
 
-  g_assert (dest == n_bindings);
-  
+  g_assert (dest + skipped == n_bindings);
   *n_bindings_p = dest;
 
   meta_topic (META_DEBUG_KEYBINDINGS,
@@ -1675,6 +1713,12 @@ meta_display_process_key_event (MetaDisp
           handled = process_workspace_switch_grab (display, screen, event, keysym);
           break;
 
+        case META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING:
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Processing event for keyboard screen switching\n");
+          handled = process_screen_switch_grab (display, screen, event, keysym);
+          break;
+
         default:
           break;
         }
@@ -2776,6 +2820,116 @@ process_workspace_switch_grab (MetaDispl
   return FALSE;
 }
 
+static gboolean
+process_screen_switch_grab (MetaDisplay *display,
+                            MetaScreen  *screen,
+                            XEvent      *event,
+                            KeySym       keysym)
+{
+  MetaKeyBindingAction action;
+  gboolean backward;
+  gboolean key_used;
+
+  if (screen != display->grab_screen)
+    return FALSE;
+
+  g_return_val_if_fail (screen->tab_popup != NULL, FALSE);
+
+  if (event->type == KeyRelease &&
+      keycode_is_primary_modifier (display, event->xkey.keycode,
+                                   display->grab_mask))
+    {
+      MetaScreen *target_screen;
+
+      target_screen = (MetaScreen *) meta_ui_tab_popup_get_selected (screen->tab_popup);  
+
+      meta_topic (META_DEBUG_KEYBINDINGS,
+                  "Ending screen tab operation, primary modifier released\n");
+
+      if (target_screen)
+        {
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Ending grab early so we can focus the target screen\n");
+          meta_display_end_grab_op (display, event->xkey.time);
+
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Activating target screen\n");
+
+          meta_workspace_focus_default_window (target_screen->active_workspace,
+                                               NULL,
+                                               event->xkey.time);
+
+          return TRUE; /* we already ended the grab */
+        }
+
+      return FALSE; /* end grab */
+    }
+
+  /* don't care about other releases, but eat them, don't end grab */
+  if (event->type == KeyRelease)
+    return TRUE;
+
+  /* don't end grab on modifier key presses */
+  if (is_modifier (display, event->xkey.keycode))
+    return TRUE;
+
+  action = display_get_keybinding_action (display,
+                                          keysym,
+                                          display->grab_mask);
+
+  backward = FALSE;
+  key_used = FALSE;
+
+  switch (action)
+    {
+    case META_KEYBINDING_ACTION_SWITCH_SCREEN:
+      backward = FALSE;
+      key_used = TRUE;
+      break;
+    case META_KEYBINDING_ACTION_SWITCH_SCREEN_BACKWARD:
+      backward = TRUE;
+      key_used = TRUE;
+      break;
+    default:
+      break;
+    }
+	 
+  if (key_used)
+    {
+      MetaScreen *target_screen;
+
+      meta_topic (META_DEBUG_KEYBINDINGS,
+                  "Key pressed, moving tab focus in popup\n");
+
+      if (backward)
+        meta_ui_tab_popup_backward (screen->tab_popup);
+      else
+        meta_ui_tab_popup_forward (screen->tab_popup);
+
+      target_screen = (MetaScreen *) meta_ui_tab_popup_get_selected (screen->tab_popup);
+
+      if (target_screen)
+        {
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Tab key pressed, moving tab focus in popup\n");
+
+          meta_topic (META_DEBUG_KEYBINDINGS,
+                      "Activating target screen\n");
+
+          meta_workspace_focus_default_window (target_screen->active_workspace,
+                                               NULL,
+                                               event->xkey.time);
+        }
+    }
+  else
+    {
+      /* end grab */
+      meta_topic (META_DEBUG_KEYBINDINGS,
+                  "Ending screen tabbing, uninteresting key pressed\n");
+    }
+  return key_used;
+}
+
 static void
 handle_toggle_desktop (MetaDisplay    *display,
                        MetaScreen     *screen,
@@ -2792,6 +2946,117 @@ handle_toggle_desktop (MetaDisplay    *d
     }
   else
     meta_screen_show_desktop (screen, event->xkey.time);
+}
+
+static int
+find_screen_neighbor (MetaDisplay    *display,
+                      MetaScreen     *screen,
+                      gboolean        backward)
+{
+  unsigned int ind;
+
+  ind  = g_slist_index (display->screens, screen);
+
+  if (backward)
+    {
+      if (ind == (g_slist_length (display->screens) - 1))
+        ind = 0;
+      else
+	ind++;
+    }
+  else
+    {
+      if (!ind)
+        ind =  g_slist_length (display->screens) - 1;
+      else
+        ind--;
+    }
+  
+  return (ind);
+}
+
+static void
+do_handle_switch_to_screen (MetaDisplay    *display,
+                            MetaScreen     *screen,
+                            MetaWindow     *window,
+                            XEvent         *event,
+                            MetaKeyBinding *binding,
+                            gboolean        backward)
+{
+  unsigned int grab_mask;
+
+  meta_topic (META_DEBUG_KEYBINDINGS,
+              "Starting tab between screen, showing popup\n");
+
+  grab_mask = event->xkey.state & ~(display->ignored_modifier_mask);
+
+  if (meta_display_begin_grab_op (display,
+                                  screen,
+                                  NULL,
+                                  META_GRAB_OP_KEYBOARD_SCREEN_SWITCHING,
+                                  FALSE,
+                                  event->xkey.serial,
+                                  0,
+                                  grab_mask,
+                                  event->xkey.time,
+                                  0, 0))
+    {
+      MetaScreen *target_screen;
+      gboolean grabbed_before_release;
+      int ind;
+
+      ind = find_screen_neighbor (display, screen, backward);
+      target_screen = (MetaScreen *) g_slist_nth_data (display->screens, ind);
+
+      grabbed_before_release = primary_modifier_still_pressed (display, 
+                                                               grab_mask);
+
+      meta_topic (META_DEBUG_KEYBINDINGS,
+                  "Activating target screen\n");
+
+      if (!grabbed_before_release)
+        {
+          /* end the grab right away, modifier possibly released
+           * before we could establish the grab and receive the
+           * release event. Must end grab before we can switch
+           * spaces.
+           */
+          meta_display_end_grab_op (display, event->xkey.time);
+        }
+
+      meta_workspace_focus_default_window (target_screen->active_workspace,
+                                           NULL,
+                                           event->xkey.time);
+
+      if (grabbed_before_release)
+        {
+          meta_ui_tab_popup_select (screen->tab_popup,
+                                    (MetaTabEntryKey) target_screen);
+
+          /* only after selecting proper space */
+          meta_ui_tab_popup_set_showing (screen->tab_popup, TRUE);
+        }
+    }
+}
+
+static void
+handle_switch_to_screen (MetaDisplay    *display,
+                         MetaScreen     *screen,
+                         MetaWindow     *window,
+                         XEvent         *event,
+                         MetaKeyBinding *binding)
+{
+  do_handle_switch_to_screen (display, screen, window, event, binding, FALSE);
+}
+
+static void
+handle_switch_to_screen_backward (MetaDisplay    *display,
+                                  MetaScreen     *screen,
+                                  MetaWindow     *window,
+                                  XEvent         *event,
+                                  MetaKeyBinding *binding)
+{
+  do_handle_switch_to_screen (display, screen, window, event, binding, TRUE);
 }
 
 static void
Index: src/metacity.schemas.in
===================================================================
RCS file: /cvs/gnome/metacity/src/metacity.schemas.in,v
retrieving revision 1.47
diff -p -u -r1.47 metacity.schemas.in
--- src/metacity.schemas.in	21 Jan 2006 19:18:51 -0000	1.47
+++ src/metacity.schemas.in	27 Jan 2006 22:53:55 -0000
@@ -1295,6 +1295,56 @@ you set
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/global_keybindings/switch_screen</key>
+      <applyto>/apps/metacity/global_keybindings/switch_screen</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Control&gt;&lt;Alt&gt;Page_Down</default>
+      <locale name="C">
+        <short>Move between screens</short>
+        <long>
+          The keybinding used to move to the next screen in multihead
+          (not xinerama) setup.  The keybinding is disabled if there
+          is only one screen.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
+      <key>/schemas/apps/metacity/global_keybindings/switch_screen_backward</key>
+      <applyto>/apps/metacity/global_keybindings/switch_screen_backward</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Control&gt;&lt;Alt&gt;Page_Up</default>
+      <locale name="C">
+        <short>Move between screens - backwards</short>
+        <long>
+          The keybinding used to move to the previous screen in multihead
+          (not xinerama) setup.  The keybinding is disabled if there
+          is only one screen.
+
+          The format looks like "&lt;Control&gt;a" or
+          "&lt;Shift&gt;&lt;Alt&gt;F1.
+
+          The parser is fairly liberal and allows lower or upper case,
+          and also abbreviations such as "&lt;Ctl&gt;" and
+          "&lt;Ctrl&gt;". If you set the option to the special string
+          "disabled", then there will be no keybinding for this
+          action.
+        </long>
+      </locale>
+    </schema>
+
+    <schema>
       <key>/schemas/apps/metacity/global_keybindings/switch_to_workspace_1</key>
       <applyto>/apps/metacity/global_keybindings/switch_to_workspace_1</applyto>
       <owner>metacity</owner>
Index: src/prefs.c
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.c,v
retrieving revision 1.59
diff -p -u -r1.59 prefs.c
--- src/prefs.c	24 Jan 2006 01:07:41 -0000	1.59
+++ src/prefs.c	27 Jan 2006 22:53:56 -0000
@@ -1699,6 +1699,8 @@ static MetaKeyPref screen_bindings[] = {
   { META_KEYBINDING_CYCLE_PANELS, 0, 0, TRUE },
   { META_KEYBINDING_CYCLE_PANELS_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_SHOW_DESKTOP, 0, 0, FALSE },
+  { META_KEYBINDING_SWITCH_SCREEN, 0, 0, TRUE },
+  { META_KEYBINDING_SWITCH_SCREEN_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_PANEL_MAIN_MENU, 0, 0, FALSE },
   { META_KEYBINDING_PANEL_RUN_DIALOG, 0, 0, FALSE },
   { META_KEYBINDING_COMMAND_1, 0, 0, FALSE },
Index: src/prefs.h
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.h,v
retrieving revision 1.39
diff -p -u -r1.39 prefs.h
--- src/prefs.h	10 Jan 2006 19:43:21 -0000	1.39
+++ src/prefs.h	27 Jan 2006 22:53:56 -0000
@@ -125,6 +125,8 @@ int         meta_prefs_get_cursor_size  
 #define META_KEYBINDING_CYCLE_PANELS             "cycle_panels"
 #define META_KEYBINDING_CYCLE_PANELS_BACKWARD    "cycle_panels_backward"
 #define META_KEYBINDING_SHOW_DESKTOP             "show_desktop"
+#define META_KEYBINDING_SWITCH_SCREEN            "switch_screen"
+#define META_KEYBINDING_SWITCH_SCREEN_BACKWARD   "switch_screen_backward"
 #define META_KEYBINDING_PANEL_MAIN_MENU          "panel_main_menu"
 #define META_KEYBINDING_PANEL_RUN_DIALOG         "panel_run_dialog"
 #define META_KEYBINDING_COMMAND_1                "run_command_1"
@@ -226,6 +228,8 @@ typedef enum _MetaKeyBindingAction
   META_KEYBINDING_ACTION_CYCLE_PANELS,
   META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD,
   META_KEYBINDING_ACTION_SHOW_DESKTOP,
+  META_KEYBINDING_ACTION_SWITCH_SCREEN,
+  META_KEYBINDING_ACTION_SWITCH_SCREEN_BACKWARD,
   META_KEYBINDING_ACTION_PANEL_MAIN_MENU,
   META_KEYBINDING_ACTION_PANEL_RUN_DIALOG,
   META_KEYBINDING_ACTION_COMMAND_1,
Index: src/screen.c
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.c,v
retrieving revision 1.152
diff -p -u -r1.152 screen.c
--- src/screen.c	20 Jan 2006 22:03:55 -0000	1.152
+++ src/screen.c	27 Jan 2006 22:53:56 -0000
@@ -48,6 +48,7 @@
 #include <locale.h>
 #include <string.h>
 #include <stdio.h>
+#include <gtk/gtkicontheme.h>
 
 static char* get_screen_name (MetaDisplay *display,
                               int          number);
@@ -1249,7 +1250,7 @@ meta_screen_ensure_tab_popup (MetaScreen
                                              screen->number,
                                              len,
                                              5, /* FIXME */
-                                             TRUE);
+                                             META_TABPOPUP_WINDOW);
   g_free (entries);
 
   g_list_free (tab_list);
@@ -1317,12 +1318,68 @@ meta_screen_ensure_workspace_popup (Meta
                                              screen->number,
                                              len,
                                              layout.cols,
-                                             FALSE);      
+                                             META_TABPOPUP_WORKSPACE);      
 
   g_free (entries);
   meta_screen_free_workspace_layout (&layout);
 
   /* don't show tab popup, since proper space isn't selected yet */
+}
+
+void
+meta_screen_ensure_screen_popup (MetaScreen *screen)
+{
+  MetaTabEntry *entries;
+  MetaDisplay *display;
+  MetaScreen *srn;
+  GSList *tmp;
+  GdkPixbuf *pixbuf;
+  int len, i;
+  
+  if (screen->tab_popup) 
+    return ;
+
+  pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (),
+                                     "gnome-monitor", 48, 0, NULL);
+
+  if (!pixbuf)
+    {
+      char *path;
+      path = g_strdup_printf (METACITY_DATADIR "/pixmaps/gnome-monitor.png");
+      pixbuf = gdk_pixbuf_new_from_file (path, NULL);
+      g_free (path);
+    }
+
+  display = screen->display;
+  
+  len = g_slist_length (display->screens);  
+ 
+  entries = g_new (MetaTabEntry, len + 1);
+  entries[len].key = NULL;
+  entries[len].title = NULL;
+  entries[len].icon = NULL;
+
+  for (tmp = display->screens, i = len - 1; tmp; tmp = tmp->next, i--)
+    {
+      srn = (MetaScreen *) tmp->data;
+
+      entries[i].key = (MetaTabEntryKey) srn;
+      entries[i].title = g_strdup (srn->screen_name);
+      entries[i].icon = pixbuf;
+      entries[i].blank = FALSE;
+      entries[i].hidden = FALSE;
+      entries[i].demands_attention = FALSE;
+ 
+      g_assert (entries[i].title != NULL);
+    } 
+
+  screen->tab_popup = meta_ui_tab_popup_new (entries,
+                                             screen->number,
+                                             len,
+                                             5,
+                                             META_TABPOPUP_SCREEN);
+
+  g_free (entries);
 }
 
 MetaWindow*
Index: src/screen.h
===================================================================
RCS file: /cvs/gnome/metacity/src/screen.h,v
retrieving revision 1.69
diff -p -u -r1.69 screen.h
--- src/screen.h	13 Jan 2006 19:41:01 -0000	1.69
+++ src/screen.h	27 Jan 2006 22:53:56 -0000
@@ -145,6 +145,7 @@ void          meta_screen_ensure_tab_pop
                                                MetaTabList                 list_type,
                                                MetaTabShowType             show_type);
 void          meta_screen_ensure_workspace_popup (MetaScreen *screen);
+void          meta_screen_ensure_screen_popup (MetaScreen *screen);
 
 MetaWindow*   meta_screen_get_mouse_window     (MetaScreen                 *screen,
                                                 MetaWindow                 *not_this_one);
Index: src/tabpopup.c
===================================================================
RCS file: /cvs/gnome/metacity/src/tabpopup.c,v
retrieving revision 1.41
diff -p -u -r1.41 tabpopup.c
--- src/tabpopup.c	20 Jan 2006 22:03:55 -0000	1.41
+++ src/tabpopup.c	27 Jan 2006 22:53:56 -0000
@@ -57,6 +57,7 @@ struct _MetaTabPopup
   TabEntry *current_selected_entry;
   GtkWidget *outline_window;
   gboolean outline;
+  MetaTabPopupType popup_type;
 };
 
 static GtkWidget* selectable_image_new (GdkPixbuf *pixbuf);
@@ -142,7 +143,7 @@ meta_ui_tab_popup_new (const MetaTabEntr
                        int                 screen_number,
                        int                 entry_count,
                        int                 width,
-                       gboolean            outline)
+                       MetaTabPopupType    popup_type)
 {
   MetaTabPopup *popup;
   int i, left, right, top, bottom;
@@ -188,7 +189,8 @@ meta_ui_tab_popup_new (const MetaTabEntr
   popup->current = NULL;
   popup->entries = NULL;
   popup->current_selected_entry = NULL;
-  popup->outline = outline;
+  popup->outline = (popup_type == META_TABPOPUP_WINDOW);
+  popup->popup_type = popup_type;
 
   /* make max title size some random relationship to the screen,
    * avg char width of our font would be a better number.
@@ -239,7 +241,7 @@ meta_ui_tab_popup_new (const MetaTabEntr
             te->dimmed_icon = dimm_icon (entries[i].icon);
         }
 
-      if (outline)
+      if (popup->outline)
         {
           te->rect.x = entries[i].rect.x;
           te->rect.y = entries[i].rect.y;
@@ -312,25 +314,34 @@ meta_ui_tab_popup_new (const MetaTabEntr
               /* just stick a widget here to avoid special cases */
               image = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
             }
-          else if (outline)
+          else
             {
-              if (te->dimmed_icon)
-                {
-                  image = selectable_image_new (te->dimmed_icon);
-                }
-              else 
+              switch (popup_type)
                 {
-                  image = selectable_image_new (te->icon);
+                case META_TABPOPUP_WINDOW:
+                case META_TABPOPUP_SCREEN:
+                  if (te->dimmed_icon)
+                    {
+                      image = selectable_image_new (te->dimmed_icon);
+                    }
+                  else 
+                    {
+                      image = selectable_image_new (te->icon);
+                    }
+
+                  gtk_misc_set_padding (GTK_MISC (image),
+                                        INSIDE_SELECT_RECT +
+                                        OUTSIDE_SELECT_RECT + 1,
+                                        INSIDE_SELECT_RECT +
+                                        OUTSIDE_SELECT_RECT + 1);
+                  gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
+                  break;
+                case META_TABPOPUP_WORKSPACE:
+                  image = selectable_workspace_new ((MetaWorkspace *) te->key);
+                  break;
+                default:
+                  g_assert_not_reached ();
                 }
-
-              gtk_misc_set_padding (GTK_MISC (image),
-                                    INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1,
-                                    INSIDE_SELECT_RECT + OUTSIDE_SELECT_RECT + 1);
-              gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
-            }   
-          else
-            {
-              image = selectable_workspace_new ((MetaWorkspace *) te->key);
             }
 
           te->widget = image;
@@ -430,18 +441,30 @@ display_entry (MetaTabPopup *popup,
   
   if (popup->current_selected_entry)
   {
-    if (popup->outline)
-      unselect_image (popup->current_selected_entry->widget);
-    else
-      unselect_workspace (popup->current_selected_entry->widget);
+    switch (popup->popup_type)
+      {
+      case META_TABPOPUP_WINDOW:
+      case META_TABPOPUP_SCREEN:
+        unselect_image (popup->current_selected_entry->widget);
+        break;
+      case META_TABPOPUP_WORKSPACE:
+        unselect_workspace (popup->current_selected_entry->widget);
+        break;
+      }
   }
   
   gtk_label_set_markup (GTK_LABEL (popup->label), te->title);
 
-  if (popup->outline)
-    select_image (te->widget);
-  else
-    select_workspace (te->widget);
+  switch (popup->popup_type)
+    {
+    case META_TABPOPUP_WINDOW:
+    case META_TABPOPUP_SCREEN:
+      select_image (te->widget);
+      break;
+    case META_TABPOPUP_WORKSPACE:
+      select_workspace (te->widget);
+      break;
+    }
 
   if (popup->outline)
     {
Index: src/tabpopup.h
===================================================================
RCS file: /cvs/gnome/metacity/src/tabpopup.h,v
retrieving revision 1.8
diff -p -u -r1.8 tabpopup.h
--- src/tabpopup.h	19 Nov 2005 14:58:50 -0000	1.8
+++ src/tabpopup.h	27 Jan 2006 22:53:56 -0000
@@ -46,11 +46,18 @@ struct _MetaTabEntry
   guint            demands_attention : 1;
 };
 
+typedef enum
+{
+  META_TABPOPUP_WINDOW,
+  META_TABPOPUP_WORKSPACE,
+  META_TABPOPUP_SCREEN
+} MetaTabPopupType;
+
 MetaTabPopup*   meta_ui_tab_popup_new          (const MetaTabEntry *entries,
                                                 int                 screen_number,
                                                 int                 entry_count,
                                                 int                 width,
-                                                gboolean            outline);
+                                                MetaTabPopupType    popup_type);
 void            meta_ui_tab_popup_free         (MetaTabPopup       *popup);
 void            meta_ui_tab_popup_set_showing  (MetaTabPopup       *popup,
                                                 gboolean            showing);
