Add forgotten patches, sigh

This commit is contained in:
Ray Strode 2023-03-05 13:09:23 -05:00
parent 59b0ac85a7
commit e5aa1384a4
3 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,102 @@
From faa003812c10ab14bc69d6add078ff10528dc78b Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Mon, 13 Feb 2023 20:12:38 +0100
Subject: [PATCH 1/3] x11: Avoid updating focus on wayland compositor
Reading upon the history of this code branch (commits 6891ce95dce
and 7a4c808e43d4 are most relevant), it seems this code is meant to
synchronize Mutter focus state taking the Xserver state as true.
That is, if Mutter tried to change the focus but something truncated
that action, Mutter focus will be changed to be in sync with the
Xserver again.
This sounds backwards in a Wayland session. Mutter focus should be
the canonical source, and not second-guessed from the current Xserver
focus window. These race conditions might still apply between X11
clients, so make these paths only apply in that case.
An example of this breaking can be reproduced with a Spotify and
Firefox window, moving the focus from the first to the second by
going to the GNOME Shell overview in between, and clicking the
Firefox window from there. The Firefox window will be raised, but
refuse to take focus.
It's unclear what made this an issue recently, perhaps commit
0e6395d9328 since the now possibly ignored XI_FocusIn/Out events
affect this accounting of the Xserver focused window. Anyhow it
sounds better to ignore these paths for Wayland/native altogether.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2841>
---
src/x11/events.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/x11/events.c b/src/x11/events.c
index fd0f84c4a..89733ba33 100644
--- a/src/x11/events.c
+++ b/src/x11/events.c
@@ -1928,60 +1928,61 @@ meta_x11_display_handle_xevent (MetaX11Display *x11_display,
bypass_gtk = bypass_compositor = TRUE;
goto out;
}
#ifdef HAVE_XWAYLAND
wayland_compositor = meta_context_get_wayland_compositor (context);
if (meta_is_wayland_compositor () &&
meta_xwayland_manager_handle_xevent (&wayland_compositor->xwayland_manager,
event))
{
bypass_gtk = bypass_compositor = TRUE;
goto out;
}
#endif
if (process_selection_event (x11_display, event))
{
bypass_gtk = bypass_compositor = TRUE;
goto out;
}
display->current_time = event_get_time (x11_display, event);
if (META_IS_BACKEND_X11 (backend))
meta_backend_x11_handle_event (META_BACKEND_X11 (backend), event);
if (x11_display->focused_by_us &&
event->xany.serial > x11_display->focus_serial &&
display->focus_window &&
+ display->focus_window->client_type == META_WINDOW_CLIENT_TYPE_X11 &&
!window_has_xwindow (display->focus_window, x11_display->server_focus_window) &&
meta_display_windows_are_interactable (display))
{
meta_topic (META_DEBUG_FOCUS, "Earlier attempt to focus %s failed",
display->focus_window->desc);
meta_x11_display_update_focus_window (x11_display,
x11_display->server_focus_window,
x11_display->server_focus_serial,
FALSE);
meta_display_update_focus_window (display,
meta_x11_display_lookup_x_window (x11_display,
x11_display->server_focus_window));
}
if (event->xany.window == x11_display->xroot)
{
cursor_tracker = meta_backend_get_cursor_tracker (backend);
if (META_IS_CURSOR_TRACKER_X11 (cursor_tracker))
{
MetaCursorTrackerX11 *cursor_tracker_x11 =
META_CURSOR_TRACKER_X11 (cursor_tracker);
if (meta_cursor_tracker_x11_handle_xevent (cursor_tracker_x11, event))
{
bypass_gtk = bypass_compositor = TRUE;
goto out;
}
}
}
--
2.39.2

View File

@ -0,0 +1,101 @@
From 184c4fd7b8d13767ce8fd525040b211c1f133dbf Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 28 Feb 2023 22:02:05 +0100
Subject: [PATCH 2/3] x11: Ignore _NET_ACTIVE_WINDOW client messages while
grabbed
When a X11 application is started, typically what happens is:
- A startup notification token is created, with a _TIME%d suffix
- The application being spawned receives it through the environment
- (dbus piping, maybe)
- The application replies the startup notification token, and
fetches the timestamp from it
- The application makes a _NET_ACTIVE_WINDOW client message request
with this timestamp
- Mutter handles this client request and activates/focuses the window
Prevent this last step if windows are not interactable (e.g. there is
a compositor grab) and ignore the focus request. This specifically
applies to X11 clients requesting focus themselves, and unlike previous
approaches, doesn't try to prevent focus changes that do come through
interaction with Mutter/GNOME Shell.
This should only break if applications do not observe _NET_ACTIVE_WINDOW
and perform XSetInputFocus on themselves, but in that case the X11
keyboard focus is stolen from our hands already.
---
src/x11/window-x11.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 34dbeb855..36728555a 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -3421,61 +3421,62 @@ meta_window_x11_client_message (MetaWindow *window,
if (window_drag && (button_mask & (1 << button)) == 0)
meta_window_drag_end (window_drag);
}
}
return TRUE;
}
else if (event->xclient.message_type ==
x11_display->atom__NET_MOVERESIZE_WINDOW)
{
MetaGravity gravity;
guint value_mask;
gravity = (MetaGravity) (event->xclient.data.l[0] & 0xff);
value_mask = (event->xclient.data.l[0] & 0xf00) >> 8;
/* source = (event->xclient.data.l[0] & 0xf000) >> 12; */
if (gravity == 0)
gravity = window->size_hints.win_gravity;
meta_window_move_resize_request(window,
value_mask,
gravity,
event->xclient.data.l[1], /* x */
event->xclient.data.l[2], /* y */
event->xclient.data.l[3], /* width */
event->xclient.data.l[4]); /* height */
}
else if (event->xclient.message_type ==
- x11_display->atom__NET_ACTIVE_WINDOW)
+ x11_display->atom__NET_ACTIVE_WINDOW &&
+ meta_display_windows_are_interactable (window->display))
{
MetaClientType source_indication;
guint32 timestamp;
meta_verbose ("_NET_ACTIVE_WINDOW request for window '%s', activating",
window->desc);
source_indication = event->xclient.data.l[0];
timestamp = event->xclient.data.l[1];
if (source_indication > META_CLIENT_TYPE_MAX_RECOGNIZED)
source_indication = META_CLIENT_TYPE_UNKNOWN;
if (timestamp == 0)
{
/* Client using older EWMH _NET_ACTIVE_WINDOW without a timestamp */
meta_warning ("Buggy client sent a _NET_ACTIVE_WINDOW message with a "
"timestamp of 0 for %s",
window->desc);
timestamp = meta_display_get_current_time (display);
}
meta_window_activate_full (window, timestamp, source_indication, NULL);
return TRUE;
}
else if (event->xclient.message_type ==
x11_display->atom__NET_WM_FULLSCREEN_MONITORS)
{
MetaLogicalMonitor *top, *bottom, *left, *right;
--
2.39.2

View File

@ -0,0 +1,90 @@
From 6ccd0c2ea3f0628b3ffe8158ec69bee9420e9089 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Wed, 1 Mar 2023 13:58:13 +0100
Subject: [PATCH 3/3] core: Avoid focusing windows on map during grabs
Normally, mutter implicitly allows a window being shown to take
focus. This is normally desired, except it steals input from
GNOME Shell self. Avoid focusing the just shown window in those
situations.
---
src/core/window.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/core/window.c b/src/core/window.c
index 2ec62c22c..f137e6822 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -1967,60 +1967,69 @@ window_is_terminal (MetaWindow *window)
else if (strcmp (window->res_class, "Terminal") == 0)
return TRUE;
return FALSE;
}
/* This function determines what state the window should have assuming that it
* and the focus_window have no relation
*/
static void
window_state_on_map (MetaWindow *window,
gboolean *takes_focus,
gboolean *places_on_top)
{
gboolean intervening_events;
intervening_events = intervening_user_event_occurred (window);
*takes_focus = !intervening_events;
*places_on_top = *takes_focus;
/* don't initially focus windows that are intended to not accept
* focus
*/
if (!meta_window_is_focusable (window))
{
*takes_focus = FALSE;
return;
}
+ /* Do not focus window on map if input is already taken by the
+ * compositor.
+ */
+ if (!meta_display_windows_are_interactable (window->display))
+ {
+ *takes_focus = FALSE;
+ return;
+ }
+
/* Terminal usage may be different; some users intend to launch
* many apps in quick succession or to just view things in the new
* window while still interacting with the terminal. In that case,
* apps launched from the terminal should not take focus. This
* isn't quite the same as not allowing focus to transfer from
* terminals due to new window map, but the latter is a much easier
* approximation to enforce so we do that.
*/
if (*takes_focus &&
meta_prefs_get_focus_new_windows () == G_DESKTOP_FOCUS_NEW_WINDOWS_STRICT &&
!window->display->allow_terminal_deactivation &&
window_is_terminal (window->display->focus_window) &&
!meta_window_is_ancestor_of_transient (window->display->focus_window,
window))
{
meta_topic (META_DEBUG_FOCUS,
"focus_window is terminal; not focusing new window.");
*takes_focus = FALSE;
*places_on_top = FALSE;
}
switch (window->type)
{
case META_WINDOW_UTILITY:
case META_WINDOW_TOOLBAR:
*takes_focus = FALSE;
*places_on_top = FALSE;
break;
case META_WINDOW_DOCK:
case META_WINDOW_DESKTOP:
--
2.39.2