diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2023-02-08 15:25:32 +0100 |
---|---|---|
committer | Florian Müllner <fmuellner@gnome.org> | 2023-02-13 19:08:03 +0100 |
commit | 8cdabfd91f025d2e03b24aa665408a7640252bd2 (patch) | |
tree | 17748ada0bf8a6efaabf2800075836956c9c3efd | |
parent | e6ab7432a7df39abc6a7cbb94555e97e7fe544a7 (diff) | |
download | mutter-8cdabfd91f025d2e03b24aa665408a7640252bd2.tar.gz |
x11: Do not move X11 input focus during grabs
On X11, the stage itself is backed by an XWindow, and moving the
input focus elsewhere will bypass any Clutter-level grabs.
This effectively allows newly opened windows to steal the focus
from gnome-shell itself, which is clearly undesirable. To prevent
that, only allow moving the X11 focus to a Window when no grab is
in place, just like commit 50e89e376 did for the stage focus.
But particularly the updating of x11_display->focus_xwindow is not
prevented. Since it's more consistent to the MetaDisplay/MetaX11Display
dual focus tracking and across Wayland/X11 backends, ensure the X11
input focus is actually set on the last focus Window after the
grabs are gone and windows became interactable again.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2832>
(cherry picked from commit a68b8e95954772cd6f5d676a803e01c13e48c83f)
-rw-r--r-- | src/core/events.c | 4 | ||||
-rw-r--r-- | src/x11/meta-x11-display-private.h | 2 | ||||
-rw-r--r-- | src/x11/meta-x11-display.c | 20 |
3 files changed, 26 insertions, 0 deletions
diff --git a/src/core/events.c b/src/core/events.c index 6f348fbcc..f26946d9f 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -34,6 +34,7 @@ #include "core/display-private.h" #include "core/window-private.h" #include "meta/meta-backend.h" +#include "x11/meta-x11-display-private.h" #ifdef HAVE_NATIVE_BACKEND #include "backends/native/meta-backend-native.h" @@ -260,6 +261,9 @@ meta_display_handle_event (MetaDisplay *display, display->grabbed_in_clutter = FALSE; meta_compositor_grab_end (compositor); } + + if (display->x11_display) + meta_x11_display_sync_input_focus (display->x11_display); } device = clutter_event_get_device (event); diff --git a/src/x11/meta-x11-display-private.h b/src/x11/meta-x11-display-private.h index d53073e11..5868a4f10 100644 --- a/src/x11/meta-x11-display-private.h +++ b/src/x11/meta-x11-display-private.h @@ -254,6 +254,8 @@ void meta_x11_display_set_input_focus (MetaX11Display *x11_display, gboolean focus_frame, uint32_t timestamp); +void meta_x11_display_sync_input_focus (MetaX11Display *x11_display); + MetaDisplay * meta_x11_display_get_display (MetaX11Display *x11_display); const gchar * meta_x11_get_display_name (void); diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c index e2c4e8e91..5abbe9504 100644 --- a/src/x11/meta-x11-display.c +++ b/src/x11/meta-x11-display.c @@ -1946,6 +1946,10 @@ meta_x11_display_set_input_focus_internal (MetaX11Display *x11_display, Window xwindow, uint32_t timestamp) { + if (xwindow != None && + !meta_display_windows_are_interactable (x11_display->display)) + return; + meta_x11_error_trap_push (x11_display); /* In order for mutter to know that the focus request succeeded, we track @@ -2018,6 +2022,22 @@ meta_x11_display_set_input_focus_xwindow (MetaX11Display *x11_display, x11_display->display->last_focus_time = timestamp; } +void +meta_x11_display_sync_input_focus (MetaX11Display *x11_display) +{ + guint timestamp; + + if (!meta_display_windows_are_interactable (x11_display->display)) + return; + + meta_x11_error_trap_push (x11_display); + timestamp = meta_display_get_current_time (x11_display->display); + meta_x11_display_set_input_focus_internal (x11_display, + x11_display->focus_xwindow, + timestamp); + meta_x11_error_trap_pop (x11_display); +} + static MetaX11DisplayLogicalMonitorData * get_x11_display_logical_monitor_data (MetaLogicalMonitor *logical_monitor) { |