[PATCH] Synchronize capslock in Xnest and Xephyr

Olivier Fourdan ofourdan at redhat.com
Mon Jan 5 07:44:22 PST 2015


In Xnest or Xephyr, pressing CapsLock when focus is on another
window does not update the state in the nested X server.

This is because when synchronizing the lock modifier, sending a
keypress or a key release only is not sufficient to toggle the state,
unlike regular modifiers, one has to emulate a full press/release
to lock or unlock the modifier.

Signed-off-by: Olivier Fourdan <ofourdan at redhat.com>
---
 hw/kdrive/ephyr/ephyr.c | 9 +++++++--
 hw/xnest/Keyboard.c     | 9 ++++++++-
 2 files changed, 15 insertions(+), 3 deletions(-)

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 907bbeb..f512e91 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -792,7 +792,6 @@ ephyrUpdateModifierState(unsigned int state)
 
     xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
     state = state & 0xff;
-
     if (xkb_state == state)
         return;
 
@@ -806,7 +805,11 @@ ephyrUpdateModifierState(unsigned int state)
 
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (key_is_down(pDev, key, KEY_PROCESSED))
+                    if (mask == XCB_MOD_MASK_LOCK) {
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
+                    }
+                    else if (key_is_down(pDev, key, KEY_PROCESSED))
                         KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
 
                     if (--count == 0)
@@ -820,6 +823,8 @@ ephyrUpdateModifierState(unsigned int state)
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
                     KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE);
+                    if (mask == XCB_MOD_MASK_LOCK)
+                        KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE);
                     break;
                 }
     }
diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 2cf1624..ee3f68e 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -18,6 +18,7 @@ is" without express or implied warranty.
 
 #include <X11/X.h>
 #include <X11/Xproto.h>
+#include <xcb/xcb_keysyms.h>
 #include <X11/keysym.h>
 #include "screenint.h"
 #include "inputstr.h"
@@ -247,7 +248,11 @@ xnestUpdateModifierState(unsigned int state)
 
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (key_is_down(pDev, key, KEY_PROCESSED))
+                    if (mask == XCB_MOD_MASK_LOCK) {
+                        xnestQueueKeyEvent(KeyPress, key);
+                        xnestQueueKeyEvent(KeyRelease, key);
+                    }
+                    else if (key_is_down(pDev, key, KEY_PROCESSED))
                         xnestQueueKeyEvent(KeyRelease, key);
 
                     if (--count == 0)
@@ -261,6 +266,8 @@ xnestUpdateModifierState(unsigned int state)
             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
                     xnestQueueKeyEvent(KeyPress, key);
+                    if (mask == XCB_MOD_MASK_LOCK)
+                        xnestQueueKeyEvent(KeyRelease, key);
                     break;
                 }
     }
-- 
2.1.0



More information about the xorg-devel mailing list