diff --git a/ChangeLog b/ChangeLog index 7fb2a031c..34e88c0c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +2006-01-15 Elijah Newren + + Fix accidental overzealous focus holding by the terminal + introduced by the original patch in bug 326159. Windows launched + from panel icons, the panel menu, or global keybindings should get + focus now. #326159. + + * src/display.c (meta_display_open, event_callback): + * src/display.h (struct MetaDisplay): + * src/keybindings.c (process_event): + * src/window.c (meta_window_set_user_time): + Add a new allow_terminal_deactivation field to MetaDisplay and use + it to track whether the user's last action was interaction with + the terminal or some outside action (global keybinding, clicking + on a dock, etc.) likely to launch a new window. + + * src/window.c (window_state_on_map): + Allow the focus switch from a terminal to something else if + allow_terminal_deactiviation is true. + + * src/keybindings.c (handle_panel_keybinding): + Remove some unneeded code. + 2006-01-15 Elijah Newren Patch from Jens Granseuer to fix more build issues with gcc 2.95. diff --git a/src/display.c b/src/display.c index b1de733b3..fca268548 100644 --- a/src/display.c +++ b/src/display.c @@ -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 diff --git a/src/display.h b/src/display.h index d89558c04..0afc5242b 100644 --- a/src/display.h +++ b/src/display.h @@ -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 >*/ diff --git a/src/keybindings.c b/src/keybindings.c index 2cdd13fee..1477b7e34 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -1540,6 +1540,12 @@ process_event (MetaKeyBinding *bindings, "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 *display, 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; diff --git a/src/window.c b/src/window.c index f16df6543..74ff58c2d 100644 --- a/src/window.c +++ b/src/window.c @@ -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)) @@ -7886,5 +7887,11 @@ meta_window_set_user_time (MetaWindow *window, 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; } }