[PATCH] xwayland-input: Always set the xkb group index on modifiers events

Rui Matos tiagomatos at gmail.com
Tue Jul 15 06:57:20 PDT 2014

While we have keyboard focus, the server's xkb code is already locking
and latching modifiers appropriately while processing keyboard

Since there is no guaranteed order between wl_keyboard key and
modifiers events, if we got the modifiers event with a locked or
latched modifier and then process the key press event for that
modifier we would wrongly unlock/unlatch. To prevent this, we ignore
locked and latched modifiers while any of our surfaces has keyboard

But we always need to set the xkb group index since this might be
triggered programatically by the wayland compositor at any time.

Note that xwayland's xkb state handling needs quite a bit of work to
make it reliable. Basically, if the wl_keyboard.modifiers event comes
in after the wl_keyboard.enter event we won't update the locked and
latched modifiers properly. Right now this just happens to work with

I'm working on a proper fix for this which requires API changes to the
core xkb code in order for us to be able to tell it to ignore modifier
state processing on key events and instead always set that state from
wl_keyboard.modifiers events like any other wayland client.

Extra API will also be needed to tell the xkb request processing code
to return errors and/or silently drop X client requests that try to
change any xkb state and keymaps.

Anyway, that wouldn't be acceptable for the upcoming 1.16 release so
I'm just proposing this targetted fix for the group index to be
honored which I'd like to have working on the next GNOME release.

 hw/xwayland/xwayland-input.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
index 990cb82..9bdf9c3 100644
--- a/hw/xwayland/xwayland-input.c
+++ b/hw/xwayland/xwayland-input.c
@@ -420,12 +420,6 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
     xkbStateNotify sn;
     CARD16 changed;
-    /* We don't need any of this while we have keyboard focus since
-       the regular key event processing already takes care of setting
-       our internal state correctly. */
-    if (xwl_seat->keyboard_focus)
-        return;
     for (dev = inputInfo.devices; dev; dev = dev->next) {
         if (dev != xwl_seat->keyboard &&
             dev != GetMaster(xwl_seat->keyboard, MASTER_KEYBOARD))
@@ -434,10 +428,12 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
         old_state = dev->key->xkbInfo->state;
         new_state = &dev->key->xkbInfo->state;
+        if (!xwl_seat->keyboard_focus) {
+            new_state->locked_mods = mods_locked & XkbAllModifiersMask;
+            XkbLatchModifiers(dev, XkbAllModifiersMask,
+                              mods_latched & XkbAllModifiersMask);
+        }
         new_state->locked_group = group & XkbAllGroupsMask;
-        new_state->locked_mods = mods_locked & XkbAllModifiersMask;
-        XkbLatchModifiers(dev, XkbAllModifiersMask,
-                          mods_latched & XkbAllModifiersMask);

More information about the xorg-devel mailing list