summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2023-02-08 15:25:32 +0100
committerFlorian Müllner <fmuellner@gnome.org>2023-02-13 19:12:01 +0100
commit8aa9916c8b3707c2b8c5978c9d05cc45824ba07a (patch)
treed8be3e3cb981078b6f22947014cb022fb91d5624
parent1f39a0cb24df58ad02d066e16550ee18e40edb0f (diff)
downloadmutter-8aa9916c8b3707c2b8c5978c9d05cc45824ba07a.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.c4
-rw-r--r--src/x11/meta-x11-display-private.h2
-rw-r--r--src/x11/meta-x11-display.c20
3 files changed, 26 insertions, 0 deletions
diff --git a/src/core/events.c b/src/core/events.c
index aaf6f49ae..f6477b783 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 a81113132..d8be49e5b 100644
--- a/src/x11/meta-x11-display-private.h
+++ b/src/x11/meta-x11-display-private.h
@@ -258,6 +258,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);
#endif /* META_X11_DISPLAY_PRIVATE_H */
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 729d8c0f8..09cd332d0 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -1944,6 +1944,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
@@ -2016,6 +2020,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)
{