Index: src/common.h
===================================================================
RCS file: /cvs/gnome/metacity/src/common.h,v
retrieving revision 1.36
diff -u -p -r1.36 common.h
--- src/common.h	21 Jan 2006 19:18:51 -0000	1.36
+++ src/common.h	4 Apr 2006 16:34:55 -0000
@@ -116,6 +116,11 @@ typedef enum
   /* Alt+Esc */
   META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL,
   META_GRAB_OP_KEYBOARD_ESCAPING_DOCK,
+
+  META_GRAB_OP_KEYBOARD_ESCAPING_GROUP,
+  
+  /* Alt+F6 */
+  META_GRAB_OP_KEYBOARD_TABBING_GROUP,
   
   META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING,
   
Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.280
diff -u -p -r1.280 display.c
--- src/display.c	3 Mar 2006 15:53:10 -0000	1.280
+++ src/display.c	4 Apr 2006 16:34:55 -0000
@@ -70,8 +70,10 @@
 #define GRAB_OP_IS_WINDOW_SWITCH(g)                     \
         (g == META_GRAB_OP_KEYBOARD_TABBING_NORMAL  ||  \
          g == META_GRAB_OP_KEYBOARD_TABBING_DOCK    ||  \
+         g == META_GRAB_OP_KEYBOARD_TABBING_GROUP   ||  \
          g == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL ||  \
-         g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK)
+         g == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK   ||  \
+         g == META_GRAB_OP_KEYBOARD_ESCAPING_GROUP)
 
 typedef struct 
 {
@@ -122,6 +124,8 @@ static void    prefs_changed_callback   
 static void    sanity_check_timestamps   (MetaDisplay *display,
                                           Time         known_good_timestamp);
 
+MetaGroup*     get_focussed_group (MetaDisplay *display);
+
 static void
 ping_data_free (MetaPingData *ping_data)
 {
@@ -1122,8 +1126,10 @@ grab_op_is_keyboard (MetaGrabOp op)
     case META_GRAB_OP_KEYBOARD_RESIZING_NW:
     case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
     case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
+    case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
     case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
     case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
+    case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
     case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
       return TRUE;
 
@@ -3547,6 +3553,15 @@ meta_display_begin_grab_op (MetaDisplay 
                                     META_TAB_LIST_DOCKS,
                                     META_TAB_SHOW_INSTANTLY);
       break;
+    case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
+      meta_screen_ensure_tab_popup (screen,
+                                    META_TAB_LIST_GROUP,
+                                    META_TAB_SHOW_ICON);
+      break;
+     case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
+      meta_screen_ensure_tab_popup (screen,
+                                    META_TAB_LIST_GROUP,
+                                    META_TAB_SHOW_INSTANTLY);
       
     case META_GRAB_OP_KEYBOARD_WORKSPACE_SWITCHING:
       meta_screen_ensure_workspace_popup (screen);
@@ -4252,7 +4267,18 @@ meta_display_window_has_pending_pings (M
   return FALSE;
 }
 
-#define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)))
+MetaGroup*
+get_focussed_group (MetaDisplay *display)
+{
+  if (display->focus_window)
+    return display->focus_window->group;
+  else
+    return NULL;
+}
+
+#define IN_TAB_CHAIN(w,t) (((t) == META_TAB_LIST_NORMAL && META_WINDOW_IN_NORMAL_TAB_CHAIN (w)) \
+    || ((t) == META_TAB_LIST_DOCKS && META_WINDOW_IN_DOCK_TAB_CHAIN (w)) \
+    || ((t) == META_TAB_LIST_GROUP && META_WINDOW_IN_GROUP_TAB_CHAIN (w, get_focussed_group(w->display))))
 
 static MetaWindow*
 find_tab_forward (MetaDisplay   *display,
Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.146
diff -u -p -r1.146 display.h
--- src/display.h	30 Jan 2006 17:22:14 -0000	1.146
+++ src/display.h	4 Apr 2006 16:34:55 -0000
@@ -500,7 +500,8 @@ gboolean meta_display_window_has_pending
 typedef enum
 {
   META_TAB_LIST_NORMAL,
-  META_TAB_LIST_DOCKS
+  META_TAB_LIST_DOCKS,
+  META_TAB_LIST_GROUP
 } MetaTabList;
 
 typedef enum
Index: src/keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.126
diff -u -p -r1.126 keybindings.c
--- src/keybindings.c	13 Feb 2006 19:26:40 -0000	1.126
+++ src/keybindings.c	4 Apr 2006 16:34:56 -0000
@@ -1,5 +1,4 @@
-/* Metacity Keybindings */
-
+/* Metacity Keybindings */ 
 /* 
  * Copyright (C) 2001 Havoc Pennington
  * Copyright (C) 2002 Red Hat Inc.
@@ -280,6 +279,14 @@ static const MetaKeyHandler screen_handl
     GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
   { META_KEYBINDING_SWITCH_PANELS_BACKWARD, handle_tab_backward,
     GINT_TO_POINTER (META_TAB_LIST_DOCKS) },
+  { META_KEYBINDING_SWITCH_GROUP, handle_tab_forward,
+    GINT_TO_POINTER (META_TAB_LIST_GROUP) },
+  { META_KEYBINDING_SWITCH_GROUP_BACKWARD, handle_tab_backward,
+    GINT_TO_POINTER (META_TAB_LIST_GROUP) },
+  { META_KEYBINDING_CYCLE_GROUP, handle_cycle_forward,
+    GINT_TO_POINTER (META_TAB_LIST_GROUP) },
+  { META_KEYBINDING_CYCLE_GROUP_BACKWARD, handle_cycle_backward,
+    GINT_TO_POINTER (META_TAB_LIST_GROUP) },
   { META_KEYBINDING_CYCLE_WINDOWS, handle_cycle_forward,
     GINT_TO_POINTER (META_TAB_LIST_NORMAL) },
   { META_KEYBINDING_CYCLE_WINDOWS_BACKWARD, handle_cycle_backward,
@@ -1662,8 +1669,10 @@ meta_display_process_key_event (MetaDisp
 
         case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
         case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
+        case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
         case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
         case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
+        case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
           meta_topic (META_DEBUG_KEYBINDINGS,
                       "Processing event for keyboard tabbing/cycling\n");
           handled = process_tab_grab (display, screen, event, keysym);
@@ -2333,12 +2342,15 @@ process_tab_grab (MetaDisplay *display,
       /* CYCLE_* are traditionally Escape-based actions,
        * and should cancel traditionally Tab-based ones.
        */
-      if (display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_NORMAL ||
-          display->grab_op == META_GRAB_OP_KEYBOARD_TABBING_DOCK)
+       switch (display->grab_op)
         {
+        case META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL:
+        case META_GRAB_OP_KEYBOARD_ESCAPING_DOCK:
+         /* carry on */
+          break;
+        default:
           return FALSE;
         }
-      break;
     case META_KEYBINDING_ACTION_SWITCH_PANELS:
     case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
     case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
@@ -2346,9 +2358,13 @@ process_tab_grab (MetaDisplay *display,
       /* SWITCH_* are traditionally Tab-based actions,
        * and should cancel traditionally Escape-based ones.
        */
-      if (display->grab_op == META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL ||
-          display->grab_op == META_GRAB_OP_KEYBOARD_ESCAPING_DOCK)
+      switch (display->grab_op)
         {
+        case META_GRAB_OP_KEYBOARD_TABBING_NORMAL:
+        case META_GRAB_OP_KEYBOARD_TABBING_DOCK:
+          /* carry on */
+          break;
+        default:
           /* Also, we must re-lower and re-minimize whatever window
            * we'd previously raised and unminimized.
            */
@@ -2362,6 +2378,26 @@ process_tab_grab (MetaDisplay *display,
           return FALSE;
         }
       break;
+    case META_KEYBINDING_ACTION_CYCLE_GROUP:
+    case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
+    case META_KEYBINDING_ACTION_SWITCH_GROUP:
+    case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
+      /* If they were previously cycling using alt-Tab or alt-Escape,
+       * and they then start cycling through an app's windows
+       * using alt-f6, we should cycle through the selected app's
+       * windows and not the app we started with.
+       */
+      switch (display->grab_op)
+        {
+        case META_GRAB_OP_KEYBOARD_ESCAPING_GROUP:
+        case META_GRAB_OP_KEYBOARD_TABBING_GROUP:
+          /* carry on */
+             break;
+        default:
+             return FALSE;
+        }
+ 
+      break;
     default:
       break;
     }
@@ -2374,21 +2410,25 @@ process_tab_grab (MetaDisplay *display,
     {
     case META_KEYBINDING_ACTION_CYCLE_PANELS:
     case META_KEYBINDING_ACTION_CYCLE_WINDOWS:
+    case META_KEYBINDING_ACTION_CYCLE_GROUP:
       popup_not_showing = TRUE;
       key_used = TRUE;
       break;
     case META_KEYBINDING_ACTION_CYCLE_PANELS_BACKWARD:
     case META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD:
+    case META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD:
       popup_not_showing = TRUE;
       key_used = TRUE;
       backward = TRUE;
       break;
     case META_KEYBINDING_ACTION_SWITCH_PANELS:
     case META_KEYBINDING_ACTION_SWITCH_WINDOWS:
+    case META_KEYBINDING_ACTION_SWITCH_GROUP:
       key_used = TRUE;
       break;
     case META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD:
     case META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD:
+    case META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD:
       key_used = TRUE;
       backward = TRUE;
       break;
@@ -2904,6 +2944,8 @@ tab_op_from_tab_type (MetaTabList type)
       return META_GRAB_OP_KEYBOARD_TABBING_NORMAL;
     case META_TAB_LIST_DOCKS:
       return META_GRAB_OP_KEYBOARD_TABBING_DOCK;
+    case META_TAB_LIST_GROUP:
+      return META_GRAB_OP_KEYBOARD_TABBING_GROUP;
     }
 
   g_assert_not_reached ();
@@ -2920,6 +2962,8 @@ cycle_op_from_tab_type (MetaTabList type
       return META_GRAB_OP_KEYBOARD_ESCAPING_NORMAL;
     case META_TAB_LIST_DOCKS:
       return META_GRAB_OP_KEYBOARD_ESCAPING_DOCK;
+    case META_TAB_LIST_GROUP:
+      return META_GRAB_OP_KEYBOARD_ESCAPING_GROUP;
     }
 
   g_assert_not_reached ();
Index: src/metacity.schemas.in
===================================================================
RCS file: /cvs/gnome/metacity/src/metacity.schemas.in,v
retrieving revision 1.49
diff -u -p -r1.49 metacity.schemas.in
--- src/metacity.schemas.in	25 Mar 2006 07:21:27 -0000	1.49
+++ src/metacity.schemas.in	4 Apr 2006 16:34:56 -0000
@@ -1186,6 +1186,108 @@ you set
     </schema>
 
     <schema>
+      <key>/schemas/apps/metacity/global_keybindings/cycle_group</key>
+      <applyto>/apps/metacity/global_keybindings/cycle_group</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>disabled</default>
+      <locale name="C">
+         <short>Move between windows of an application immediately</short>
+         <long>
+          The keybinding used to move focus between windows of an
+          application without a popup window.
+          Holding the "shift" key while using this binding reverses
+          the direction of movement.
+
+          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/cycle_group_backward</key>
+      <applyto>/apps/metacity/global_keybindings/cycle_group_backward</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>disabled</default>
+      <locale name="C">
+         <short>Move backwards between windows of an application immediately</short>
+         <long>
+          The keybinding used to move focus backwards between windows
+          of an application without a popup window. Holding "shift"
+          together with this binding makes the direction go forward again.
+
+          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_group</key>
+      <applyto>/apps/metacity/global_keybindings/switch_group</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>&lt;Alt&gt;F6</default>
+      <locale name="C">
+         <short>Move between windows of an application with popup</short>
+         <long>
+          The keybinding used to move focus between windows of an
+          application, using a popup window.
+          (Traditionally &lt;Alt&gt;F6) Holding the "shift" key
+          while using this binding reverses the direction of movement.
+
+          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_group_backward</key>
+      <applyto>/apps/metacity/global_keybindings/switch_group_backward</applyto>
+      <owner>metacity</owner>
+      <type>string</type>
+      <default>disabled</default>
+      <locale name="C">
+         <short>Move backwards between windows of an application with popup</short>
+         <long>
+          The keybinding used to move focus backwards between windows
+          of an application, using a popup window. Holding "shift"
+          together with this binding makes the direction go forward again.
+
+          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/cycle_windows</key>
       <applyto>/apps/metacity/global_keybindings/cycle_windows</applyto>
       <owner>metacity</owner>
Index: src/prefs.c
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.c,v
retrieving revision 1.63
diff -u -p -r1.63 prefs.c
--- src/prefs.c	25 Mar 2006 11:47:31 -0000	1.63
+++ src/prefs.c	4 Apr 2006 16:34:56 -0000
@@ -1698,10 +1698,14 @@ static MetaKeyPref screen_bindings[] = {
   { META_KEYBINDING_WORKSPACE_RIGHT, 0, 0, FALSE },
   { META_KEYBINDING_WORKSPACE_UP, 0, 0, FALSE },
   { META_KEYBINDING_WORKSPACE_DOWN, 0, 0, FALSE },
+  { META_KEYBINDING_SWITCH_GROUP, 0, 0, TRUE },
+  { META_KEYBINDING_SWITCH_GROUP_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_SWITCH_WINDOWS, 0, 0, TRUE },
   { META_KEYBINDING_SWITCH_WINDOWS_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_SWITCH_PANELS, 0, 0, TRUE },
   { META_KEYBINDING_SWITCH_PANELS_BACKWARD, 0, 0, TRUE },
+  { META_KEYBINDING_CYCLE_GROUP, 0, 0, TRUE },
+  { META_KEYBINDING_CYCLE_GROUP_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_CYCLE_WINDOWS, 0, 0, TRUE },
   { META_KEYBINDING_CYCLE_WINDOWS_BACKWARD, 0, 0, TRUE },
   { META_KEYBINDING_CYCLE_PANELS, 0, 0, TRUE },
@@ -1801,6 +1805,7 @@ static MetaSimpleKeyMapping screen_strin
   { META_KEYBINDING_WORKSPACE_DOWN,         "<Control><Alt>Down"         },
   { META_KEYBINDING_SWITCH_WINDOWS,         "<Alt>Tab"                   },
   { META_KEYBINDING_SWITCH_PANELS,          "<Control><Alt>Tab"          },
+  { META_KEYBINDING_CYCLE_GROUP,            "<Alt>F6"                    },
   { META_KEYBINDING_CYCLE_WINDOWS,          "<Alt>Escape"                },
   { META_KEYBINDING_CYCLE_PANELS,           "<Control><Alt>Escape"       },
   { META_KEYBINDING_SHOW_DESKTOP,           "<Control><Alt>d"            },
Index: src/prefs.h
===================================================================
RCS file: /cvs/gnome/metacity/src/prefs.h,v
retrieving revision 1.40
diff -u -p -r1.40 prefs.h
--- src/prefs.h	16 Feb 2006 20:26:05 -0000	1.40
+++ src/prefs.h	4 Apr 2006 16:34:56 -0000
@@ -118,10 +118,14 @@ gboolean    meta_prefs_get_compositing_m
 #define META_KEYBINDING_WORKSPACE_RIGHT          "switch_to_workspace_right"
 #define META_KEYBINDING_WORKSPACE_UP             "switch_to_workspace_up"
 #define META_KEYBINDING_WORKSPACE_DOWN           "switch_to_workspace_down"
+#define META_KEYBINDING_SWITCH_GROUP             "switch_group"
+#define META_KEYBINDING_SWITCH_GROUP_BACKWARD    "switch_group_backward"
 #define META_KEYBINDING_SWITCH_WINDOWS           "switch_windows"
 #define META_KEYBINDING_SWITCH_WINDOWS_BACKWARD  "switch_windows_backward"
 #define META_KEYBINDING_SWITCH_PANELS            "switch_panels"
 #define META_KEYBINDING_SWITCH_PANELS_BACKWARD   "switch_panels_backward"
+#define META_KEYBINDING_CYCLE_GROUP              "cycle_group"
+#define META_KEYBINDING_CYCLE_GROUP_BACKWARD     "cycle_group_backward"
 #define META_KEYBINDING_CYCLE_WINDOWS            "cycle_windows"
 #define META_KEYBINDING_CYCLE_WINDOWS_BACKWARD   "cycle_windows_backward"
 #define META_KEYBINDING_CYCLE_PANELS             "cycle_panels"
@@ -219,10 +223,14 @@ typedef enum _MetaKeyBindingAction
   META_KEYBINDING_ACTION_WORKSPACE_RIGHT,
   META_KEYBINDING_ACTION_WORKSPACE_UP,
   META_KEYBINDING_ACTION_WORKSPACE_DOWN,
+  META_KEYBINDING_ACTION_SWITCH_GROUP,
+  META_KEYBINDING_ACTION_SWITCH_GROUP_BACKWARD,
   META_KEYBINDING_ACTION_SWITCH_WINDOWS,
   META_KEYBINDING_ACTION_SWITCH_WINDOWS_BACKWARD,
   META_KEYBINDING_ACTION_SWITCH_PANELS,
   META_KEYBINDING_ACTION_SWITCH_PANELS_BACKWARD,
+  META_KEYBINDING_ACTION_CYCLE_GROUP,
+  META_KEYBINDING_ACTION_CYCLE_GROUP_BACKWARD,
   META_KEYBINDING_ACTION_CYCLE_WINDOWS,
   META_KEYBINDING_ACTION_CYCLE_WINDOWS_BACKWARD,
   META_KEYBINDING_ACTION_CYCLE_PANELS,
Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.430
diff -u -p -r1.430 window.c
--- src/window.c	30 Mar 2006 19:22:38 -0000	1.430
+++ src/window.c	4 Apr 2006 16:34:57 -0000
@@ -3674,7 +3674,6 @@ meta_window_focus (MetaWindow  *window,
                    Time         timestamp)
 {  
   MetaWindow *modal_transient;
-
   meta_topic (META_DEBUG_FOCUS,
               "Setting input focus to window %s, input: %d take_focus: %d\n",
               window->desc, window->input, window->take_focus);
Index: src/window.h
===================================================================
RCS file: /cvs/gnome/metacity/src/window.h,v
retrieving revision 1.126
diff -u -p -r1.126 window.h
--- src/window.h	30 Mar 2006 19:22:38 -0000	1.126
+++ src/window.h	4 Apr 2006 16:34:58 -0000
@@ -542,6 +542,8 @@ gboolean meta_window_same_application (M
   (((w)->input || (w)->take_focus ) && META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w) && (!(w)->skip_taskbar))
 #define META_WINDOW_IN_DOCK_TAB_CHAIN(w) \
   (((w)->input || (w)->take_focus) && ! META_WINDOW_IN_NORMAL_TAB_CHAIN_TYPE (w))
+#define META_WINDOW_IN_GROUP_TAB_CHAIN(w, g) \
+  (((w)->input || (w)->take_focus) && (!g || meta_window_get_group(w)==g))
 
 void meta_window_refresh_resize_popup (MetaWindow *window);
 
