From 68691cb1b93112f215fb94ad693eba431e99c426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 13 Nov 2018 08:31:52 +0100 Subject: [PATCH] workspace: Focus only ancestors that are focusable When destroying a window that has a parent, we initially try to focus one of its ancestors. However if no ancestor can be focused, then we should instead focus the default focus window instead of trying to request focus for a window that can't get focus anyways. Fixes https://gitlab.gnome.org/GNOME/mutter/issues/308 (cherry picked from commit eccc791f3b3451216f957e67fec47a73b65ed2b2) --- src/core/workspace.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/core/workspace.c b/src/core/workspace.c index a964e6603..d19494309 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -85,6 +85,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData MetaRectangle logical_monitor_work_area; } MetaWorkspaceLogicalMonitorData; +typedef struct _MetaWorkspaceFocusableAncestorData +{ + MetaWorkspace *workspace; + MetaWindow *out_window; +} MetaWorkspaceFocusableAncestorData; + static MetaWorkspaceLogicalMonitorData * meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, MetaLogicalMonitor *logical_monitor) @@ -1319,13 +1325,20 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, } static gboolean -record_ancestor (MetaWindow *window, - void *data) +find_focusable_ancestor (MetaWindow *window, + gpointer user_data) { - MetaWindow **result = data; + MetaWorkspaceFocusableAncestorData *data = user_data; - *result = window; - return FALSE; /* quit with the first ancestor we find */ + if (!window->unmanaging && (window->input || window->take_focus) && + meta_window_located_on_workspace (window, data->workspace) && + meta_window_showing_on_its_workspace (window)) + { + data->out_window = window; + return FALSE; + } + + return TRUE; } /* Focus ancestor of not_this_one if there is one */ @@ -1347,11 +1360,15 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, if (not_this_one) { MetaWindow *ancestor; - ancestor = NULL; - meta_window_foreach_ancestor (not_this_one, record_ancestor, &ancestor); - if (ancestor != NULL && - meta_window_located_on_workspace (ancestor, workspace) && - meta_window_showing_on_its_workspace (ancestor)) + MetaWorkspaceFocusableAncestorData data; + + data = (MetaWorkspaceFocusableAncestorData) { + .workspace = workspace, + }; + meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &data); + ancestor = data.out_window; + + if (ancestor) { meta_topic (META_DEBUG_FOCUS, "Focusing %s, ancestor of %s\n",