[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#891915: Patch for Debian 10 (buster), it fixes the problem



Tags: patch


I attached patch from ArchLinux AUR (https://aur.archlinux.org/packages/xorg-server-bug865/, https://aur.archlinux.org/cgit/aur.git/tree/freedesktop-bug-865.patch?h=xorg-server-bug865 ). This patch is stable and reliable. ArchLinux users are happy with it.

It fixes current bug on Debian 10 (buster).
I have tested it with <Ctrl+Shift> on MATE desktop.

Please kindly review it and consider applying it before official final release of Debian 10.
As the result Debian and Ubuntu users will be as happy as ArchLinux's users.
--- xorg-server-1.19.1/xkb/xkbActions.c.orig	2017-01-12 18:34:23.435568903 +0300
+++ xorg-server-1.19.1/xkb/xkbActions.c	2017-02-23 12:58:00.719948700 +0300
@@ -351,26 +351,83 @@
     return 1;
 }
 
+static int xkbSwitchGroupOnRelease(void)
+{
+    /* TODO: user configuring */
+    return TRUE;
+}
+
+static void xkbUpdateLockedGroup(XkbSrvInfoPtr xkbi, XkbAction* pAction)
+{
+    XkbGroupAction ga = pAction->group;
+    if (ga.flags&XkbSA_GroupAbsolute)
+       xkbi->state.locked_group= XkbSAGroup(&ga);
+    else
+       xkbi->state.locked_group+= XkbSAGroup(&ga);
+}
+
+static XkbFilterPtr _XkbNextFreeFilter(XkbSrvInfoPtr xkbi);
+
 static int
-_XkbFilterLockState(XkbSrvInfoPtr xkbi,
+_XkbFilterLockGroup(XkbSrvInfoPtr xkbi,
                     XkbFilterPtr filter, unsigned keycode, XkbAction *pAction)
 {
+    int sendEvent = 1;
+
     if (filter->keycode == 0) /* initial press */
         AccessXCancelRepeatKey(xkbi, keycode);
-
-    if (pAction && (pAction->type == XkbSA_LockGroup)) {
-        if (pAction->group.flags & XkbSA_GroupAbsolute)
-            xkbi->state.locked_group = XkbSAGroup(&pAction->group);
-        else
-            xkbi->state.locked_group += XkbSAGroup(&pAction->group);
-        return 1;
+    if (!xkbSwitchGroupOnRelease()) {
+       xkbUpdateLockedGroup(xkbi, pAction);
+       return sendEvent;
+    }
+    
+    /* Delay switch till button release */
+    if (filter->keycode==0) {          /* initial press */
+       filter->keycode = keycode;
+       filter->active = 1;
+       filter->filterOthers = 0; /* for what? */
+       filter->filter = _XkbFilterLockGroup;
+
+       /* filter->priv = 0; */
+       filter->upAction = *pAction;
+
+       /* Ok, now we need to simulate the action which would go if this action didn't block it.
+          XkbSA_SetMods is the one: it is to set modifier' flag up. */
+       {
+           XkbStateRec fake_state = xkbi->state;
+           XkbAction act;
+
+           fake_state.mods = 0;
+           act = XkbGetKeyAction(xkbi, &fake_state, keycode);
+
+           /* KLUDGE: XkbSA_SetMods only? */
+           if (act.type == XkbSA_SetMods) { 
+               XkbFilterPtr filter = _XkbNextFreeFilter(xkbi);
+               sendEvent = _XkbFilterSetState(xkbi,filter,keycode,&act);
+           }
+       }
+    }
+    else {
+       /* do nothing if some button else is pressed */
+       if (!pAction)
+           xkbUpdateLockedGroup(xkbi, &filter->upAction);
+       filter->active = 0;
     }
+    return sendEvent;
+}
+
+static int
+_XkbFilterLockMods(    XkbSrvInfoPtr   xkbi,
+                       XkbFilterPtr    filter,
+                       unsigned        keycode,
+                       XkbAction *     pAction)
+{
     if (filter->keycode == 0) { /* initial press */
         filter->keycode = keycode;
         filter->active = 1;
         filter->filterOthers = 0;
         filter->priv = xkbi->state.locked_mods & pAction->mods.mask;
-        filter->filter = _XkbFilterLockState;
+        filter->filter = _XkbFilterLockMods;
         filter->upAction = *pAction;
         if (!(filter->upAction.mods.flags & XkbSA_LockNoLock))
             xkbi->state.locked_mods |= pAction->mods.mask;
@@ -1244,9 +1301,12 @@
         *sendEvent = _XkbFilterLatchState(xkbi, filter, key, act);
         break;
     case XkbSA_LockMods:
+        filter = _XkbNextFreeFilter(xkbi);
+        *sendEvent = _XkbFilterLockMods(xkbi, filter, key, act);
+        break;
     case XkbSA_LockGroup:
         filter = _XkbNextFreeFilter(xkbi);
-        *sendEvent = _XkbFilterLockState(xkbi, filter, key, act);
+        *sendEvent = _XkbFilterLockGroup(xkbi, filter, key, act);
         break;
     case XkbSA_ISOLock:
         filter = _XkbNextFreeFilter(xkbi);

Reply to: