ArcticaProject / nx-libs

nx-libs
Other
120 stars 39 forks source link

Synchronize capslock in nxagent #97

Open sunweaver opened 8 years ago

sunweaver commented 8 years ago

Something similar would make sense for nxagent, I guess..

commit 43014795087a0a8774dd9687f5967329b15f06a2
Author: Olivier Fourdan <ofourdan@redhat.com>
Date:   Mon Jan 5 16:44:22 2015 +0100

    Synchronize capslock in Xnest and Xephyr

    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@redhat.com>
    Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>

diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c
index 907bbeb..164ebdc 100644
--- a/hw/kdrive/ephyr/ephyr.c
+++ b/hw/kdrive/ephyr/ephyr.c
@@ -806,7 +806,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 +824,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;
                 }
     }
sunweaver commented 8 years ago

requires a follow up commit:

commit 4affa75a90d2455c81087b930126ad7adfd019f0
Author: Adam Jackson <ajax@redhat.com>
Date:   Thu Nov 19 12:21:08 2015 -0500

    xnest: Fix needless build dependency on xcb-util-keysyms

    This was added in:

        commit 43014795087a0a8774dd9687f5967329b15f06a2
        Author: Olivier Fourdan <ofourdan@redhat.com>
        Date:   Mon Jan 5 16:44:22 2015 +0100

            Synchronize capslock in Xnest and Xephyr

    Which is fine if you're building both, but if you don't happen to have
    xcb-util-keysyms' headers installed Xnest will configure as enabled but
    fail to build.

    Fortunately <X11/X.h> has a corresponding #define, so use that instead.

    Signed-off-by: Adam Jackson <ajax@redhat.com>
    Reviewed-by: Olivier Fourdan <ofourdan@redhat.com>

diff --git a/hw/xnest/Keyboard.c b/hw/xnest/Keyboard.c
index 7ee7a7c..85deaba 100644
--- a/hw/xnest/Keyboard.c
+++ b/hw/xnest/Keyboard.c
@@ -22,7 +22,6 @@ 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"
@@ -252,7 +251,7 @@ xnestUpdateModifierState(unsigned int state)

             for (key = 0; key < MAP_LENGTH; key++)
                 if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
-                    if (mask == XCB_MOD_MASK_LOCK) {
+                    if (mask == LockMask) {
                         xnestQueueKeyEvent(KeyPress, key);
                         xnestQueueKeyEvent(KeyRelease, key);
                     }
@@ -270,7 +269,7 @@ 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)
+                    if (mask == LockMask)
                         xnestQueueKeyEvent(KeyRelease, key);
                     break;
                 }
sunweaver commented 8 years ago

I am not fully sure, if the above patches are needed for nxagent. With some quick tests, it seems that CAPS lock is kept in sync between local X and nested X session.

However, we have an with the NUMLOCK key, which may be similar here (needs to be verified): with NUMLOCK, some session managers manipulate the NUMLOCK state (e.g. MATE's session manager). In the remote session NUMLOCK is then enabled, whereas the keys' functionality is that of a keyboard with NUMLOCK disabled.

When disabling NUMLOCK via keyboard then, it actually gets enabled and vice versa.

So, what we need to check is: Is software manipulation of CAPS lock accurately reflected in the nested and the local X11 session.