diff --git a/0001-x11-Avoid-updating-focus-on-wayland-compositor.patch b/0001-x11-Avoid-updating-focus-on-wayland-compositor.patch new file mode 100644 index 0000000..918a685 --- /dev/null +++ b/0001-x11-Avoid-updating-focus-on-wayland-compositor.patch @@ -0,0 +1,102 @@ +From faa003812c10ab14bc69d6add078ff10528dc78b Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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: +--- + 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 + diff --git a/0002-x11-Ignore-_NET_ACTIVE_WINDOW-client-messages-while-.patch b/0002-x11-Ignore-_NET_ACTIVE_WINDOW-client-messages-while-.patch new file mode 100644 index 0000000..90c6894 --- /dev/null +++ b/0002-x11-Ignore-_NET_ACTIVE_WINDOW-client-messages-while-.patch @@ -0,0 +1,101 @@ +From 184c4fd7b8d13767ce8fd525040b211c1f133dbf Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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 + diff --git a/0003-core-Avoid-focusing-windows-on-map-during-grabs.patch b/0003-core-Avoid-focusing-windows-on-map-during-grabs.patch new file mode 100644 index 0000000..690f8ac --- /dev/null +++ b/0003-core-Avoid-focusing-windows-on-map-during-grabs.patch @@ -0,0 +1,90 @@ +From 6ccd0c2ea3f0628b3ffe8158ec69bee9420e9089 Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +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 +