[PATCH] xwayland: Handle the wl_keyboard modifiers event

Rui Matos tiagomatos at gmail.com
Tue Oct 22 16:52:06 CEST 2013


This allows us to keep track of latched and locked modifiers as well
as the XKB group while the keyboard focus is on another wayland
client. Note that we don't need to track depressed modifiers since
wayland guarantees that we'll get them as key press events whenever
we get the keyboard focus.
---
 hw/xfree86/xwayland/xwayland-input.c   | 40 +++++++++++++++++++++++++++++++++-
 hw/xfree86/xwayland/xwayland-private.h |  2 +-
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/hw/xfree86/xwayland/xwayland-input.c b/hw/xfree86/xwayland/xwayland-input.c
index ebf1af1..2f14b20 100644
--- a/hw/xfree86/xwayland/xwayland-input.c
+++ b/hw/xfree86/xwayland/xwayland-input.c
@@ -504,6 +504,7 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
     uint32_t *k;
 
     xwl_seat->xwl_screen->serial = serial;
+    xwl_seat->keyboard_focus = surface;
 
     wl_array_copy(&xwl_seat->keys, keys);
     wl_array_for_each(k, &xwl_seat->keys)
@@ -521,6 +522,8 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
 
     wl_array_for_each(k, &xwl_seat->keys)
 	xf86PostKeyboardEvent(xwl_seat->keyboard, *k + 8, 0);
+
+    xwl_seat->keyboard_focus = NULL;
 }
 
 static void
@@ -529,7 +532,42 @@ keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
 			  uint32_t mods_latched, uint32_t mods_locked,
 			  uint32_t group)
 {
-    /* FIXME: Need more server XKB API here. */
+    struct xwl_seat *xwl_seat = data;
+    DeviceIntPtr dev;
+    XkbStateRec old_state, *new_state;
+    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))
+            continue;
+
+        old_state = dev->key->xkbInfo->state;
+        new_state = &dev->key->xkbInfo->state;
+
+        new_state->locked_group = group & XkbAllGroupsMask;
+        new_state->locked_mods = mods_locked & XkbAllModifiersMask;
+        XkbLatchModifiers(dev, XkbAllModifiersMask, mods_latched & XkbAllModifiersMask);
+
+        XkbComputeDerivedState(dev->key->xkbInfo);
+
+        changed = XkbStateChangedFlags(&old_state, new_state);
+        if (!changed)
+            continue;
+
+        sn.keycode = 0;
+        sn.eventType = 0;
+        sn.requestMajor = XkbReqCode;
+        sn.requestMinor = X_kbLatchLockState; /* close enough */
+        sn.changed = changed;
+        XkbSendStateNotify(dev, &sn);
+    }
 }
 
 static const struct wl_keyboard_listener keyboard_listener = {
diff --git a/hw/xfree86/xwayland/xwayland-private.h b/hw/xfree86/xwayland/xwayland-private.h
index aa9fc03..bdecf8a 100644
--- a/hw/xfree86/xwayland/xwayland-private.h
+++ b/hw/xfree86/xwayland/xwayland-private.h
@@ -112,7 +112,7 @@ struct xwl_seat {
 
     size_t			 keymap_size;
     char			*keymap;
-
+    struct wl_surface           *keyboard_focus;
 };
 
 
-- 
1.8.3.1



More information about the wayland-devel mailing list