From 716e33f1067ec97577f89a8a7292ba0f6087b320 Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Tue, 25 Mar 2025 12:17:39 -0400
Subject: [PATCH] x11: Send the _XWAYLAND_MAY_GRAB_KEYBOARD message when
grabbing the keyboard
GNOME requires this to allow keyboard grabs on XWayland. Otherwise, XGrabKeyboard will still report success, but shortcuts won't be inhibited.
See https://gitlab.gnome.org/GNOME/mutter/-/commit/5f132f39750f684c3732b4346dec810cd218d609
---
docs/README-wayland.md | 4 ++++
src/video/x11/SDL_x11window.c | 27 +++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/docs/README-wayland.md b/docs/README-wayland.md
index 557a81391882c..fddbcece53e7e 100644
--- a/docs/README-wayland.md
+++ b/docs/README-wayland.md
@@ -59,6 +59,10 @@ encounter limitations or behavior that is different from other windowing systems
`SDL_APP_ID` hint string, the desktop entry file name should match the application ID. For example, if your
application ID is set to `org.my_org.sdl_app`, the desktop entry file should be named `org.my_org.sdl_app.desktop`.
+### Keyboard grabs don't work when running under XWayland
+
+- One GNOME based desktops, the dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled.
+
## Using custom Wayland windowing protocols with SDL windows
Under normal operation, an `SDL_Window` corresponds to an XDG toplevel window, which provides a standard desktop window.
diff --git a/src/video/x11/SDL_x11window.c b/src/video/x11/SDL_x11window.c
index 62f8661030282..5ad27d854b6e1 100644
--- a/src/video/x11/SDL_x11window.c
+++ b/src/video/x11/SDL_x11window.c
@@ -2097,6 +2097,33 @@ bool X11_SetWindowKeyboardGrab(SDL_VideoDevice *_this, SDL_Window *window, bool
return true;
}
+ /* GNOME needs the _XWAYLAND_MAY_GRAB_KEYBOARD message on XWayland:
+ *
+ * - message_type set to "_XWAYLAND_MAY_GRAB_KEYBOARD"
+ * - window set to the xid of the window on which the grab is to be issued
+ * - data.l[0] to a non-zero value
+ *
+ * The dconf setting `org/gnome/mutter/wayland/xwayland-allow-grabs` must be enabled as well.
+ *
+ * https://gitlab.gnome.org/GNOME/mutter/-/commit/5f132f39750f684c3732b4346dec810cd218d609
+ */
+ if (_this->internal->is_xwayland) {
+ Atom _XWAYLAND_MAY_GRAB_ATOM = X11_XInternAtom(display, "_XWAYLAND_MAY_GRAB_KEYBOARD", False);
+
+ if (_XWAYLAND_MAY_GRAB_ATOM != None) {
+ XClientMessageEvent client_message;
+ client_message.type = ClientMessage;
+ client_message.window = data->xwindow;
+ client_message.format = 32;
+ client_message.message_type = _XWAYLAND_MAY_GRAB_ATOM;
+ client_message.data.l[0] = 1;
+ client_message.data.l[1] = CurrentTime;
+
+ X11_XSendEvent(display, DefaultRootWindow(display), False, SubstructureNotifyMask | SubstructureRedirectMask, (XEvent *)&client_message);
+ X11_XFlush(display);
+ }
+ }
+
X11_XGrabKeyboard(display, data->xwindow, True, GrabModeAsync,
GrabModeAsync, CurrentTime);
} else {