From a5f360cb9e2ae0188410051c027c97fa7ef47d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 13 Nov 2018 01:31:52 -0600 Subject: [PATCH] workspace: Focus only ancestors who can be actually focused 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 fault window instead of trying to request focus for a window that can't get focus anyways. Fixes #308 --- src/core/workspace.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/core/workspace.c b/src/core/workspace.c index 1f129fd12..1d8d8104c 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -87,6 +87,12 @@ typedef struct _MetaWorkspaceLogicalMonitorData MetaRectangle logical_monitor_work_area; } MetaWorkspaceLogicalMonitorData; +typedef struct _MetaWorkspaceFocusableAncestorData +{ + MetaWorkspace *workspace; + MetaWindow **win; +} MetaWorkspaceFocusableAncestorData; + static MetaWorkspaceLogicalMonitorData * meta_workspace_get_logical_monitor_data (MetaWorkspace *workspace, MetaLogicalMonitor *logical_monitor) @@ -1328,13 +1334,21 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace, } static gboolean -record_ancestor (MetaWindow *window, - void *data) +find_focusable_ancestor (MetaWindow *window, + void *data) { - MetaWindow **result = data; + MetaWorkspaceFocusableAncestorData *mwfa = data; + MetaWindow **result = mwfa->win; - *result = window; - return FALSE; /* quit with the first ancestor we find */ + if ((window->input || window->take_focus) && + meta_window_located_on_workspace (window, mwfa->workspace) && + meta_window_showing_on_its_workspace (window)) + { + *result = window; + return FALSE; + } + + return TRUE; } /* Focus ancestor of not_this_one if there is one */ @@ -1355,12 +1369,10 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace, /* First, check to see if we need to focus an ancestor of a window */ 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)) + MetaWindow *ancestor = NULL; + MetaWorkspaceFocusableAncestorData mwfa = { workspace, &ancestor }; + meta_window_foreach_ancestor (not_this_one, find_focusable_ancestor, &mwfa); + if (ancestor != NULL) { meta_topic (META_DEBUG_FOCUS, "Focusing %s, ancestor of %s\n",