Index: src/display.c
===================================================================
RCS file: /cvs/gnome/metacity/src/display.c,v
retrieving revision 1.270
diff -p -u -r1.270 display.c
--- src/display.c	13 Jan 2006 19:41:01 -0000	1.270
+++ src/display.c	14 Jan 2006 04:21:08 -0000
@@ -336,6 +336,8 @@ meta_display_open (const char *name)
   display->grab_old_window_stacking = NULL;
 
   display->mouse_mode = TRUE; /* Only relevant for mouse or sloppy focus */
+  display->allow_terminal_deactivation = TRUE; /* Only relevant for when a
+                                                  terminal has the focus */
 
 #ifdef HAVE_XSYNC
   display->grab_sync_request_alarm = None;
@@ -1687,6 +1689,11 @@ event_callback (XEvent   *event,
                                   window->desc, event->xbutton.button);
                       meta_window_focus (window, event->xbutton.time);
                     }
+                  else
+                    /* However, do allow terminals to lose focus due to new
+                     * window mappings after the user clicks on a panel.
+                     */
+                    display->allow_terminal_deactivation = TRUE;
                 }
               
               /* you can move on alt-click but not on
Index: src/display.h
===================================================================
RCS file: /cvs/gnome/metacity/src/display.h,v
retrieving revision 1.142
diff -p -u -r1.142 display.h
--- src/display.h	10 Jan 2006 19:43:21 -0000	1.142
+++ src/display.h	14 Jan 2006 04:21:08 -0000
@@ -204,6 +204,14 @@ struct _MetaDisplay
    */
   guint mouse_mode : 1;
 
+  /* Helper var for strict focus for terminals; only relevant if the focus
+   * window is a terminal.  Typically, we don't allow new windows to take
+   * focus away from a terminal, but if the user explicitly did something
+   * that should allow a different window to gain focus (e.g. global
+   * keybinding or clicking on a dock), then we will allow the transfer.
+   */
+  guint allow_terminal_deactivation : 1;
+
   guint static_gravity_works : 1;
   
   /*< private-ish >*/
Index: src/keybindings.c
===================================================================
RCS file: /cvs/gnome/metacity/src/keybindings.c,v
retrieving revision 1.121
diff -p -u -r1.121 keybindings.c
--- src/keybindings.c	10 Jan 2006 19:43:21 -0000	1.121
+++ src/keybindings.c	14 Jan 2006 04:21:09 -0000
@@ -1540,6 +1540,12 @@ process_event (MetaKeyBinding       *bin
                         "Running handler for %s\n",
                         bindings[i].name);
           
+          /* Global keybindings count as a let-the-terminal-lose-focus
+           * due to new window mapping until the user starts
+           * interacting with the terminal again.
+           */
+          display->allow_terminal_deactivation = TRUE;
+
           (* handler->func) (display, screen, window, event,
                              &bindings[i]);
           return;
@@ -2809,13 +2815,6 @@ handle_panel_keybinding (MetaDisplay    
       break;
     case META_KEYBINDING_ACTION_PANEL_RUN_DIALOG:
       action_atom = display->atom_gnome_panel_action_run_dialog;
-      /* We want the dialog to take focus from a terminal since this
-       * should be considered an explicit focus transfer.
-       */
-      if (__window_is_terminal (display->focus_window))
-        meta_display_focus_the_no_focus_window (display, 
-                                                screen,
-                                                event->xkey.time);
       break;
     default:
       return;
Index: src/window.c
===================================================================
RCS file: /cvs/gnome/metacity/src/window.c,v
retrieving revision 1.410
diff -p -u -r1.410 window.c
--- src/window.c	13 Jan 2006 19:41:01 -0000	1.410
+++ src/window.c	14 Jan 2006 04:21:10 -0000
@@ -567,12 +567,12 @@ meta_window_new_with_attrs (MetaDisplay 
   initial_props[i++] = display->atom_net_wm_user_time;
   g_assert (N_INITIAL_PROPS == i);
   
+  update_wm_class (window);
   meta_window_reload_properties (window, initial_props, N_INITIAL_PROPS);
 
   update_net_wm_state (window);
   
   update_mwm_hints (window);
-  update_wm_class (window);
   update_transient_for (window);
   update_sm_hints (window); /* must come after transient_for */
   update_role (window);
@@ -1781,6 +1781,7 @@ window_state_on_map (MetaWindow *window,
    * approximation to enforce so we do that.
    */
   if (*takes_focus &&
+      !window->display->allow_terminal_deactivation &&
       __window_is_terminal (window->display->focus_window) &&
       !meta_window_is_ancestor_of_transient (window->display->focus_window,
                                              window))
@@ -7885,5 +7886,11 @@ meta_window_set_user_time (MetaWindow *w
       window->net_wm_user_time = timestamp;
       if (XSERVER_TIME_IS_BEFORE (window->display->last_user_time, timestamp))
         window->display->last_user_time = timestamp;
+
+      /* If this is a terminal, user interaction with it means the user likely
+       * doesn't want to have focus transferred for now due to new windows.
+       */
+      if (__window_is_terminal (window))
+        window->display->allow_terminal_deactivation = FALSE;
     }
 }
