[mutter/gnome-3-36] core: Make sure focus_default_window() worked
- From: Robert Mader <rmader src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter/gnome-3-36] core: Make sure focus_default_window() worked
- Date: Tue, 22 Dec 2020 19:07:46 +0000 (UTC)
commit 0cf7ec5409c545730fa9be9c9ecd3d26c43623a0
Author: Olivier Fourdan <ofourdan redhat com>
Date: Wed Dec 16 16:51:24 2020 +0100
core: Make sure focus_default_window() worked
The function focus_default_window() optionally takes a MetaWindow
argument denoting a window that should not be focused.
That function calls focus_ancestor_or_top_window() which in turn
calls meta_window_focus() to pass focus to another window.
However meta_window_focus() gives no guarantee that the given window
will end up being the one focused, and can fail in various and creative
ways.
If that fails, we could possibly end up with the focus window being the
one to avoid, while the caller assumes focus was changed, going as far
as asserting that fact like meta_window_unmanage() does.
As a result, mutter may abort simply because meta_window_focus() failed
to set focus on the expected window.
To avoid that issue, check that the focus did not end up on the window
that we explicitly did not want, and if that's the case, simply fallback
to the default focus window.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/862
(cherry picked from commit afa431547b696a82375412a289993a8d0eebdabd)
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1653>
src/core/workspace.c | 58 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 42 insertions(+), 16 deletions(-)
---
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 6125481a18..01b8487c49 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -1343,6 +1343,30 @@ find_focusable_ancestor (MetaWindow *window,
return TRUE;
}
+static gboolean
+try_to_set_focus_and_check (MetaWindow *window,
+ MetaWindow *not_this_one,
+ uint32_t timestamp)
+{
+ meta_window_focus (window, timestamp);
+
+ /* meta_window_focus() does not guarantee that focus will end up
+ * where we expect, it can fail for various reasons, better check
+ * it did not actually changed or even left focus to the window we
+ * explicitly want to avoid.
+ */
+ if (not_this_one &&
+ meta_display_get_focus_window (window->display) == not_this_one)
+ {
+ meta_warning ("Failed to focus window %s while avoiding %s",
+ window->desc, not_this_one->desc);
+
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/* Focus ancestor of not_this_one if there is one */
static void
focus_ancestor_or_top_window (MetaWorkspace *workspace,
@@ -1376,13 +1400,14 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
"Focusing %s, ancestor of %s\n",
ancestor->desc, not_this_one->desc);
- meta_window_focus (ancestor, timestamp);
-
- /* Also raise the window if in click-to-focus */
- if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
- meta_window_raise (ancestor);
+ if (try_to_set_focus_and_check (ancestor, not_this_one, timestamp))
+ {
+ /* Also raise the window if in click-to-focus */
+ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
+ meta_window_raise (ancestor);
- return;
+ return;
+ }
}
}
@@ -1394,18 +1419,19 @@ focus_ancestor_or_top_window (MetaWorkspace *workspace,
{
meta_topic (META_DEBUG_FOCUS,
"Focusing workspace MRU window %s\n", window->desc);
+ if (try_to_set_focus_and_check (window, not_this_one, timestamp))
+ {
+ /* Also raise the window if in click-to-focus */
+ if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
+ meta_window_raise (window);
- meta_window_focus (window, timestamp);
-
- /* Also raise the window if in click-to-focus */
- if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
- meta_window_raise (window);
- }
- else
- {
- meta_topic (META_DEBUG_FOCUS, "No MRU window to focus found; focusing no_focus_window.\n");
- meta_display_unset_input_focus (workspace->display, timestamp);
+ return;
+ }
}
+
+ meta_topic (META_DEBUG_FOCUS,
+ "No MRU window to focus found; focusing no_focus_window.");
+ meta_display_unset_input_focus (workspace->display, timestamp);
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]