summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--man/setxkbmap.man12
-rw-r--r--setxkbmap.c48
3 files changed, 62 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index d5733ff..9b475d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -47,7 +47,8 @@ AC_ARG_WITH(xkb-config-root,
AC_SUBST([XKBCONFIGROOT])
# Checks for pkg-config packages
-PKG_CHECK_MODULES(SETXKBMAP, xkbfile x11)
+# xrandr is needed for the XWayland check
+PKG_CHECK_MODULES(SETXKBMAP, xkbfile x11 xrandr)
# Allow checking code with lint, sparse, etc.
XORG_WITH_LINT
diff --git a/man/setxkbmap.man b/man/setxkbmap.man
index 926b6f7..d02f25f 100644
--- a/man/setxkbmap.man
+++ b/man/setxkbmap.man
@@ -138,6 +138,18 @@ directly to the \fBxkbcomp\fP input. For example, the command
makes both steps run on the same (client) machine and loads a keyboard map into
the server.
+
+.SH "XWAYLAND"
+Xwayland is an X server that uses a Wayland Compositor as backend.
+Xwayland acts as translation layer between the X protocol and the Wayland
+protocol but does not manage the keymaps - these are handled by the Wayland
+Compositor.
+.PP
+Changing the keymap with \fBsetxkbmap\fP is not supported by Xwayland.
+In most instances, using \fBsetxkbmap\fP on Xwayland is indicative of a
+bug in a shell script and \fBsetxkbmap\fP will print a warning. Use the Wayland
+Compositor's native XKB configuration methods instead.
+
.SH SEE ALSO
xkbcomp(__appmansuffix__), xkeyboard-config(__miscmansuffix__)
.SH FILES
diff --git a/setxkbmap.c b/setxkbmap.c
index 3af641e..68eb9a6 100644
--- a/setxkbmap.c
+++ b/setxkbmap.c
@@ -38,6 +38,7 @@
#include <X11/extensions/XKBfile.h>
#include <X11/extensions/XKBconfig.h>
#include <X11/extensions/XKBrules.h>
+#include <X11/extensions/Xrandr.h>
#ifndef PATH_MAX
#ifdef MAXPATHLEN
@@ -1067,12 +1068,59 @@ applyComponentNames(void)
return True;
}
+static Bool
+is_xwayland(void)
+{
+ /* Code copied from xisxwayland.c */
+ Bool rc = False;
+ XRRScreenResources *resources = NULL;
+ XRROutputInfo *output = NULL;
+
+ /* There is no definitive way of checking for an XWayland server,
+ * but the two working methods are:
+ * - RandR output names in Xwayland are XWAYLAND0, XWAYLAND1, etc.
+ * - XI devices are xwayland-pointer:10, xwayland-keyboard:11
+ * Let's go with the XRandR check here because it's slightly less
+ * code to write.
+ */
+
+ int event_base, error_base, major, minor;
+ if (!XRRQueryExtension(dpy, &event_base, &error_base) ||
+ !XRRQueryVersion(dpy, &major, &minor)) {
+ /* e.g. Xnest, but definitely not Xwayland */
+ goto out;
+ }
+
+ resources = XRRGetScreenResourcesCurrent(dpy, DefaultRootWindow(dpy));
+ if (!resources) {
+ goto out;
+ }
+
+ output = XRRGetOutputInfo(dpy, resources, resources->outputs[0]);
+ if (!output) {
+ goto out;
+ }
+
+ if (strncmp(output->name, "XWAYLAND", 8) == 0)
+ rc = True;
+
+ XRRFreeOutputInfo(output);
+out:
+ if (resources)
+ XRRFreeScreenResources(resources);
+
+ return rc;
+}
int
main(int argc, char **argv)
{
if ((!parseArgs(argc, argv)) || (!getDisplay(argc, argv)))
exit(-1);
+
+ if (is_xwayland())
+ MSG("WARNING: Running setxkbmap against an XWayland server\n");
+
settings.locale.value = setlocale(LC_ALL, settings.locale.value);
settings.locale.src = FROM_SERVER;
VMSG1(7, "locale is %s\n", settings.locale.value);