ui: fix keymap detection under Xwayland
authorDaniel P. Berrangé <berrange@redhat.com>
Tue, 13 Mar 2018 10:42:35 +0000 (10:42 +0000)
committerGerd Hoffmann <kraxel@redhat.com>
Tue, 10 Apr 2018 09:21:54 +0000 (11:21 +0200)
The X11 code currently detects the keymap by looking for the keycode
name property. Unfortunately due to the way Xwayland handles keyboards,
this property gets unset almost immediately after the first application
starts using Xwayland resulting in

  ** (qemu-system-x86_64:19644): WARNING **: Unknown X11 keycode mapping '(unnamed)'.
  Please report to qemu-devel@nongnu.org
  including the following information:

    - Operating system
    - X11 Server
    - xprop -root
    - xdpyinfo

Fortunately people will only see this problem if they built QEMU with
GTK2, or have told GTK3 to prefer X11 by setting the GDK_BACKEND=x11
env variable.

To workaround the problem, we add a heuristic that looks at what
scancode the XK_Page_Up keysymbol maps to, to determine if we've
likely got the X11 kbd or evdev driver.

Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20180313104235.20725-1-berrange@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
ui/x_keymap.c

index 22e0e77c4d6930c38721517a01d43e0972dc53c9..2bc01432e5ca3807c01e2c3e53dd80b005d3ef6a 100644 (file)
@@ -17,6 +17,7 @@
 #include "ui/input.h"
 
 #include <X11/XKBlib.h>
+#include <X11/Xutil.h>
 
 static gboolean check_for_xwin(Display *dpy)
 {
@@ -87,11 +88,13 @@ const guint16 *qemu_xkeymap_mapping_table(Display *dpy, size_t *maplen)
         trace_xkeymap_keymap("xquartz");
         *maplen = qemu_input_map_xorgxquartz_to_qcode_len;
         return qemu_input_map_xorgxquartz_to_qcode;
-    } else if (keycodes && g_str_has_prefix(keycodes, "evdev")) {
+    } else if ((keycodes && g_str_has_prefix(keycodes, "evdev")) ||
+               (XKeysymToKeycode(dpy, XK_Page_Up) == 0x70)) {
         trace_xkeymap_keymap("evdev");
         *maplen = qemu_input_map_xorgevdev_to_qcode_len;
         return qemu_input_map_xorgevdev_to_qcode;
-    } else if (keycodes && g_str_has_prefix(keycodes, "xfree86")) {
+    } else if ((keycodes && g_str_has_prefix(keycodes, "xfree86")) ||
+               (XKeysymToKeycode(dpy, XK_Page_Up) == 0x63)) {
         trace_xkeymap_keymap("kbd");
         *maplen = qemu_input_map_xorgkbd_to_qcode_len;
         return qemu_input_map_xorgkbd_to_qcode;