Blob Blame History Raw
From eca25ab6a12770a2a767458d9b0129d4fde3995c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Tue, 13 Nov 2018 08:31:52 +0100
Subject: [PATCH 1/2] 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 f2b2c2c48..58fcfa78c 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)
@@ -1322,13 +1328,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;
+
+  if (!window->unmanaging && meta_window_is_focusable (window) &&
+      meta_window_located_on_workspace (window, data->workspace) &&
+      meta_window_showing_on_its_workspace (window))
+    {
+      data->out_window = window;
+      return FALSE;
+    }
 
-  *result = window;
-  return FALSE; /* quit with the first ancestor we find */
+  return TRUE;
 }
 
 /* Focus ancestor of not_this_one if there is one */
@@ -1350,11 +1363,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",
-- 
2.21.0