xserver: Branch 'master'

Adam Jackson ajax at kemper.freedesktop.org
Wed May 4 14:55:52 UTC 2016


 include/xkbsrv.h |    4 ++++
 xkb/xkb.c        |    3 ++-
 xkb/xkbLEDs.c    |    2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

New commits:
commit ac164e58870d70640381e68b776eb95578c7fbd3
Author: Peter Hutterer <peter.hutterer at who-t.net>
Date:   Wed May 4 20:36:18 2016 +1000

    xkb: after changing the keymap, force an indicator update
    
    When NumLock is on and a new keymap is applied, the next modifier state
    change will turn off that LED (but leave the state enabled). The cause
    for this is a bit convoluted:
    
    * the SLI explicitState is copied from the current state in
      ProcXkbGetKbdByName. Thus, if NumLock is on, that state is 0x2.
    * on the next modifier key press (e.g. Shift), XkbApplyState() calls into
      XkbUpdateIndicators() -> XkbUpdateLedAutoState() to update SLIs (if any)
      for the currently changed modifier. But it does so with a mask only for
      the changed modifier (i.e. for Shift).
    * XkbUpdateLedAutoState() calculates the state based on this mask and
      ends up with 0 because we don't have a Shift LED and we masked out the
      others.
    * XkbUpdateLedAutoState() compares that state with the previous state
      (which is still 0x2) and then proceeds to turn the LED off
    
    This doesn't happen in the normal case because either the mask
    encompasses all modifiers or the state matches of the masked-out
    modifiers matches the old state.
    
    Avoid this issue by forcing an SLI update after changing the keymap.
    This updates the sli->effectiveState and thus restores everything to
    happy working order.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1047151
    
    Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
    Reviewed-by: Daniel Stone <daniels at collabora.com>

diff --git a/include/xkbsrv.h b/include/xkbsrv.h
index cc6307a..7e71089 100644
--- a/include/xkbsrv.h
+++ b/include/xkbsrv.h
@@ -496,6 +496,10 @@ extern _X_EXPORT void XkbUpdateIndicators(DeviceIntPtr /* keybd */ ,
                                           XkbEventCausePtr      /* cause */
     );
 
+extern _X_EXPORT void XkbUpdateAllDeviceIndicators(XkbChangesPtr /* changes */,
+                                                   XkbEventCausePtr /* cause */
+    );
+
 extern _X_EXPORT XkbSrvLedInfoPtr XkbAllocSrvLedInfo(DeviceIntPtr /* dev */ ,
                                                      KbdFeedbackPtr /* kf */ ,
                                                      LedFeedbackPtr /* lf */ ,
diff --git a/xkb/xkb.c b/xkb/xkb.c
index 294cdf8..3a6ad65 100644
--- a/xkb/xkb.c
+++ b/xkb/xkb.c
@@ -5692,7 +5692,6 @@ ProcXkbListComponents(ClientPtr client)
 }
 
 /***====================================================================***/
-
 int
 ProcXkbGetKbdByName(ClientPtr client)
 {
@@ -6017,6 +6016,8 @@ ProcXkbGetKbdByName(ClientPtr client)
         new = NULL;
     }
     XkbFreeComponentNames(&names, FALSE);
+    XkbUpdateAllDeviceIndicators(NULL, NULL);
+
     return Success;
 }
 
diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c
index 4e16002..5792d9f 100644
--- a/xkb/xkbLEDs.c
+++ b/xkb/xkbLEDs.c
@@ -304,7 +304,7 @@ XkbUpdateLedAutoState(DeviceIntPtr dev,
     return;
 }
 
-static void
+void
 XkbUpdateAllDeviceIndicators(XkbChangesPtr changes, XkbEventCausePtr cause)
 {
     DeviceIntPtr edev;


More information about the xorg-commit mailing list