diff --git a/ChangeLog b/ChangeLog index 0adff9716..66b748246 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2006-01-10 Elijah Newren + + Don't "steal" focus from terminal windows for new window mappings + as the difference in usage between terminals and other apps seems + to suggest this difference in treatment. See #326159 for details, + feedback welcome. + + * src/window.[ch] (__window_is_terminal): New function, currently + an ugly hack and should be replaced by a new property set by + applications if the behavior works to our liking, + (window_state_on_map): don't transfer focus to new windows from + terminals unless the new window is a transient of the focused + terminal + + * src/keybindigns.c (handle_panel_keybinding): panel run dialog + keybinding should be counted as an explicit transfer of focus to + the new window, so override the + don't-transfer-focus-from-terminals in this case + 2006-01-09 Elijah Newren More thorough handling of source indication. Part of #326041. diff --git a/src/keybindings.c b/src/keybindings.c index a70a5359e..42aa64d80 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -2809,6 +2809,13 @@ 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 f9fde8fd0..b2ebfa75f 100644 --- a/src/window.c +++ b/src/window.c @@ -1675,6 +1675,45 @@ intervening_user_event_occurred (MetaWindow *window) } } +/* This function is an ugly hack. It's experimental in nature and ought to be + * replaced by a real hint from the app to the WM if we decide the experimental + * behavior is worthwhile. The basic idea is to get more feedback about how + * usage scenarios of "strict" focus users and what they expect. See #326159. + */ +gboolean +__window_is_terminal (MetaWindow *window) +{ + if (window == NULL) + return FALSE; + + /* gnome-terminal -- if you couldn't guess */ + if (strcmp (window->res_name, "gnome-terminal") == 0) + return TRUE; + /* xterm, rxvt, aterm */ + else if (strcmp (window->res_name, "XTerm") == 0) + return TRUE; + /* konsole, KDE's terminal program */ + else if (strcmp (window->res_name, "Konsole") == 0) + return TRUE; + /* rxvt-unicode */ + else if (strcmp (window->res_name, "URxvt") == 0) + return TRUE; + /* eterm */ + else if (strcmp (window->res_name, "Eterm") == 0) + return TRUE; + /* KTerm -- some terminal not KDE based; so not like Konsole */ + else if (strcmp (window->res_name, "KTerm") == 0) + return TRUE; + /* Multi-gnome-terminal */ + else if (strcmp (window->res_name, "Multi-gnome-terminal") == 0) + return TRUE; + /* mlterm ("multi lingual terminal emulator on X") */ + else if (strcmp (window->res_name, "mlterm") == 0) + return TRUE; + + return FALSE; +} + /* This function determines what state the window should have assuming that it * and the focus_window have no relation */ @@ -1699,6 +1738,25 @@ window_state_on_map (MetaWindow *window, return; } + /* Terminal usage is different; users typically intend to launch + * many apps in quick succession or to just view things in the new + * window while still interacting with the terminal. Therefore, + * apps launched from the terminal should not take focus. This + * isn't quite the same as not allowing focus to transfer from + * terminals due to new window map, but the latter is a much easier + * approximation to enforce so we do that. + */ + if (*takes_focus && + __window_is_terminal (window->display->focus_window) && + !meta_window_is_ancestor_of_transient (window->display->focus_window, + window)) + { + meta_topic (META_DEBUG_FOCUS, + "focus_window is terminal; not focusing new window.\n"); + *takes_focus = FALSE; + *places_on_top = FALSE; + } + switch (window->type) { case META_WINDOW_UTILITY: diff --git a/src/window.h b/src/window.h index 2f57919d7..441e588cb 100644 --- a/src/window.h +++ b/src/window.h @@ -426,6 +426,9 @@ gboolean meta_window_showing_on_its_workspace (MetaWindow *window); /* Return whether the window should be currently mapped */ gboolean meta_window_should_be_showing (MetaWindow *window); +/* See warning in window.c about this function */ +gboolean __window_is_terminal (MetaWindow *window); + /* This recalcs the window/frame size, and recalcs the frame * size/contents as well. */