window: Allow activation on non-active workspaces with proper timestamps

Our focus stealing prevention is still mostly inherited from metacity;
in particular, a (non-transient) window that is not on the current
workspace will not be given focus. This behavior made sense in the
GNOME 2 days, where workspaces were separated much more strictly.
However this is no longer the case in GNOME 3 - activating a launcher
will switch workspaces if necessary, and so will the app switcher.
There is no good reason to not do the same for other user actions
like clicking a URL or activating a search result, so allow activation
of windows on non-active workspaces if a proper timestamp is supplied,
assuming that this is a strong enough indication that we are dealing
with a legitimate user action.

https://bugzilla.gnome.org/show_bug.cgi?id=728018
This commit is contained in:
Florian Müllner 2014-04-11 13:52:55 +02:00
parent 5defe574d7
commit 87bec99a0a

View File

@ -3703,11 +3703,13 @@ meta_window_activate_full (MetaWindow *window,
MetaClientType source_indication, MetaClientType source_indication,
MetaWorkspace *workspace) MetaWorkspace *workspace)
{ {
gboolean allow_workspace_switch;
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"_NET_ACTIVE_WINDOW message sent for %s at time %u " "_NET_ACTIVE_WINDOW message sent for %s at time %u "
"by client type %u.\n", "by client type %u.\n",
window->desc, timestamp, source_indication); window->desc, timestamp, source_indication);
allow_workspace_switch = (timestamp != 0);
if (timestamp != 0 && if (timestamp != 0 &&
XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time)) XSERVER_TIME_IS_BEFORE (timestamp, window->display->last_user_time))
{ {
@ -3735,6 +3737,7 @@ meta_window_activate_full (MetaWindow *window,
rather than move windows or workspaces. rather than move windows or workspaces.
See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */ See http://bugzilla.gnome.org/show_bug.cgi?id=482354 */
if (window->transient_for == NULL && if (window->transient_for == NULL &&
!allow_workspace_switch &&
!meta_window_located_on_workspace (window, workspace)) !meta_window_located_on_workspace (window, workspace))
{ {
meta_window_set_demands_attention (window); meta_window_set_demands_attention (window);
@ -3760,7 +3763,10 @@ meta_window_activate_full (MetaWindow *window,
meta_topic (META_DEBUG_FOCUS, meta_topic (META_DEBUG_FOCUS,
"Focusing window %s due to activation\n", "Focusing window %s due to activation\n",
window->desc); window->desc);
if (meta_window_located_on_workspace (window, workspace))
meta_window_focus (window, timestamp); meta_window_focus (window, timestamp);
else
meta_workspace_activate_with_focus (window->workspace, window, timestamp);
meta_window_check_alive (window, timestamp); meta_window_check_alive (window, timestamp);
} }