From 0cbf6d9326c35534321468a487fb6d36aaa1233d Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Fri, 12 Jan 2024 09:37:58 +0100 Subject: [PATCH] xwayland: Add a -nokeymap option By default, Xwayland (as any Wayland client) uses the keymap set by the Wayland compositor using the standard Wayland protocol. There are some specific uses cases where a user would want to let the X11 clients control the keymap. However, the Wayland compositor may (re)send the keymap at any time, overriding whatever change was made using the X11 mechanisms. Add a new "-nokeymap" option to Xwayland to instruct Xwayland to simply ignore the standard Wayland mechanism to set the keymap, hence leaving the control entirely to the X11 clients. Signed-off-by: Olivier Fourdan Reviewed-by: Peter Hutterer --- hw/xwayland/man/Xwayland.man | 9 +++++++++ hw/xwayland/xwayland-input.c | 4 ++++ hw/xwayland/xwayland-screen.c | 3 +++ hw/xwayland/xwayland-screen.h | 1 + hw/xwayland/xwayland.c | 4 ++++ 5 files changed, 21 insertions(+) diff --git a/hw/xwayland/man/Xwayland.man b/hw/xwayland/man/Xwayland.man index 62ace369a..f26b94035 100644 --- a/hw/xwayland/man/Xwayland.man +++ b/hw/xwayland/man/Xwayland.man @@ -124,6 +124,15 @@ support touch input. Force additional non-native modes to be exposed when viewporter is not supported by the Wayland compositor. .TP 8 +.B \-nokeymap +Instructs \fIXwayland\fP to ignore the keymap set by the Wayland compositor. + +By default, \fIXwayland\fP (as any Wayland client) uses the keymap set by the +Wayland compositor using the standard Wayland protocol. + +This option is meant for some specific use cases where it may be desirable to +let the X11 clients control the keymap used in Xwayland, ignoring the keymap +specified by the Wayland compositor. .B \-output \fIname\fP Specifies on which output \fIXwayland\fP fullscreen rootful should be placed. The name must match the name of an existing Wayland output (output names can diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c index 52dc4f86f..078e7c2d3 100644 --- a/hw/xwayland/xwayland-input.c +++ b/hw/xwayland/xwayland-input.c @@ -1113,10 +1113,14 @@ keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, uint32_t format, int fd, uint32_t size) { struct xwl_seat *xwl_seat = data; + struct xwl_screen *xwl_screen = xwl_seat->xwl_screen; DeviceIntPtr master; XkbDescPtr xkb; XkbChangesRec changes = { 0 }; + if (xwl_screen->nokeymap) + return; + if (xwl_seat->keymap) munmap(xwl_seat->keymap, xwl_seat->keymap_size); diff --git a/hw/xwayland/xwayland-screen.c b/hw/xwayland/xwayland-screen.c index 22afd4e94..03ee4e668 100644 --- a/hw/xwayland/xwayland-screen.c +++ b/hw/xwayland/xwayland-screen.c @@ -869,6 +869,9 @@ xwl_screen_init(ScreenPtr pScreen, int argc, char **argv) ErrorF("This build does not have XDG portal support\n"); #endif } + else if (strcmp(argv[i], "-nokeymap") == 0) { + xwl_screen->nokeymap = 1; + } } if (!xwl_screen->rootless) { diff --git a/hw/xwayland/xwayland-screen.h b/hw/xwayland/xwayland-screen.h index 92688a7e0..a53d18bad 100644 --- a/hw/xwayland/xwayland-screen.h +++ b/hw/xwayland/xwayland-screen.h @@ -68,6 +68,7 @@ struct xwl_screen { int has_grab; int decorate; int enable_ei_portal; + int nokeymap; CreateScreenResourcesProcPtr CreateScreenResources; CloseScreenProcPtr CloseScreen; diff --git a/hw/xwayland/xwayland.c b/hw/xwayland/xwayland.c index 2aa9893a1..0879db69e 100644 --- a/hw/xwayland/xwayland.c +++ b/hw/xwayland/xwayland.c @@ -94,6 +94,7 @@ ddxUseMsg(void) ErrorF("-fullscreen run fullscreen when rootful\n"); ErrorF("-geometry WxH set Xwayland window size when rootful\n"); ErrorF("-host-grab disable host keyboard shortcuts when rootful\n"); + ErrorF("-nokeymap ignore keymap from the Wayland compositor\n"); ErrorF("-output specify which output to use for fullscreen when rootful\n"); ErrorF("-wm fd create X client for wm on given fd\n"); ErrorF("-initfd fd add given fd as a listen socket for initialization clients\n"); @@ -267,6 +268,9 @@ ddxProcessArgument(int argc, char *argv[], int i) CHECK_FOR_REQUIRED_ARGUMENTS(1); return 2; } + else if (strcmp(argv[i], "-nokeymap") == 0) { + return 1; + } return 0; }