xserver: Branch 'master'

Peter Hutterer whot at kemper.freedesktop.org
Wed Jan 4 03:25:08 UTC 2017


 include/xkbsrv.h |    2 ++
 xkb/xkbInit.c    |    9 +++++++++
 xkb/xkbPrKeyEv.c |   29 +++++++++++++++++++++--------
 3 files changed, 32 insertions(+), 8 deletions(-)

New commits:
commit 9d32b71c93cf6187e9320c99ae857e34a51b7102
Author: Mihail Konev <k.mvc at ya.ru>
Date:   Wed Jan 4 07:08:51 2017 +0500

    xkb: Match key releases with an overlaid press
    
    Testcase:
    
    In ~/.xbindkeysrc:
      "xterm &"
           XF86LaunchA
    
    In ~/ov.xkb:
      xkb_keymap {
          xkb_keycodes { include "evdev" };
          xkb_types    { include "complete" };
          xkb_compat   { include "complete"
              interpret Overlay1_Enable+AnyOfOrNone(all) {
                  action= SetControls(controls=Overlay1);
              };
          };
          xkb_symbols  { include "pc+inet(evdev)+us"
              key <INS> { [ Overlay1_Enable ] };
              key <AE01> { overlay1 = <AE02> }; // Insert+1 => 2
              key <TLDE> { overlay1 = <I128> }; // Insert+~ => XF86LaunchA
          };
          xkb_geometry { include "pc(pc104)" };
      };
    
    Apply this layout: 'xkbcomp ~/ov.xkb $DISPLAY'.
    Run "xbindkeys -n -v"
    In the exact order:
    - press Insert
    - press Tilde
    - release Insert
    - wait
    - release Tilde
    Keyboard input in the new terminal window(s) would be locked
    until another Insert+Tilde .
    
    Reported-by: Mariusz Mazur <mariusz.g.mazur at gmail.com>
    Signed-off-by: Mihail Konev <k.mvc at ya.ru>
    Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index 6e4ad44..2870f39 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -195,6 +195,8 @@ typedef struct _XkbSrvInfo {
     XkbFilterPtr filters;
 
     XkbSrvCheckRepeatPtr checkRepeat;
+
+    char overlay_perkey_state[256/8]; /* bitfield */
 } XkbSrvInfoRec, *XkbSrvInfoPtr;
 
 #define	XkbSLI_IsDefault	(1L<<0)
diff --git a/xkb/xkbInit.c b/xkb/xkbInit.c
index 9c772f5..46016ab 100644
--- a/xkb/xkbInit.c
+++ b/xkb/xkbInit.c
@@ -505,6 +505,13 @@ XkbInitControls(DeviceIntPtr pXDev, XkbSrvInfoPtr xkbi)
     return Success;
 }
 
+static Status
+XkbInitOverlayState(XkbSrvInfoPtr xkbi)
+{
+    memset(xkbi->overlay_perkey_state, 0, sizeof(xkbi->overlay_perkey_state));
+    return Success;
+}
+
 static Bool
 InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
                                  const char *keymap, int keymap_length,
@@ -608,6 +615,8 @@ InitKeyboardDeviceStructInternal(DeviceIntPtr dev, XkbRMLVOSet * rmlvo,
 
     XkbInitIndicatorMap(xkbi);
 
+    XkbInitOverlayState(xkbi);
+
     XkbUpdateActions(dev, xkb->min_key_code, XkbNumKeys(xkb), &changes,
                      &check, &cause);
 
diff --git a/xkb/xkbPrKeyEv.c b/xkb/xkbPrKeyEv.c
index f7a6b4b..d2c7e33 100644
--- a/xkb/xkbPrKeyEv.c
+++ b/xkb/xkbPrKeyEv.c
@@ -121,20 +121,33 @@ XkbProcessKeyboardEvent(DeviceEvent *event, DeviceIntPtr keybd)
         case XkbKB_Overlay2:
         {
             unsigned which;
+            unsigned overlay_active_now;
+            unsigned is_keyrelease = (event->type == ET_KeyRelease) ? 1 : 0;
+            /* Remembers whether the key was pressed while overlay was down,
+             * for when overlay is already released, but the key is not. */
+            unsigned key_was_overlaid = 0;
 
             if (behavior.type == XkbKB_Overlay1)
                 which = XkbOverlay1Mask;
             else
                 which = XkbOverlay2Mask;
-            if ((xkbi->desc->ctrls->enabled_ctrls & which) == 0)
-                break;
-            if ((behavior.data >= xkbi->desc->min_key_code) &&
-                (behavior.data <= xkbi->desc->max_key_code)) {
+            overlay_active_now = (xkbi->desc->ctrls->enabled_ctrls & which) ? 1 : 0;
+
+            if ((unsigned char)key == key) {
+                key_was_overlaid = BitIsOn(xkbi->overlay_perkey_state, key);
+                if (!is_keyrelease) {
+                    if (overlay_active_now)
+                        SetBit(xkbi->overlay_perkey_state, key);
+                } else {
+                    if (key_was_overlaid)
+                        ClearBit(xkbi->overlay_perkey_state, key);
+                }
+            }
+
+            if ((overlay_active_now || key_was_overlaid) &&
+                    (behavior.data >= xkbi->desc->min_key_code) &&
+                    (behavior.data <= xkbi->desc->max_key_code)) {
                 event->detail.key = behavior.data;
-                /* 9/11/94 (ef) -- XXX! need to match release with */
-                /*                 press even if the state of the  */
-                /*                 corresponding overlay control   */
-                /*                 changes while the key is down   */
             }
         }
             break;


More information about the xorg-commit mailing list