Peter Hutterer 63b1c55
From 0d2fea8a8ce5e1d2693c25dbeff00461c72427a2 Mon Sep 17 00:00:00 2001
Peter Hutterer 63b1c55
From: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer 63b1c55
Date: Fri, 29 Apr 2016 15:56:03 +1000
Peter Hutterer 63b1c55
Subject: [PATCH xserver] xkb: after changing the keymap, force an indicator
Peter Hutterer 63b1c55
 update
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
When NumLock is on and a new keymap is applied, the next modifier state change
Peter Hutterer 63b1c55
will turn off that LED (but leave the state enabled). The cause for this is a
Peter Hutterer 63b1c55
bit convoluted:
Peter Hutterer 63b1c55
* the SLI explicitState is copied from the current state in
Peter Hutterer 63b1c55
  ProcXkbGetKbdByName. Thus, if NumLock is on, that state is 0x2.
Peter Hutterer 63b1c55
* on the next modifier key press (e.g. Shift), XkbApplyState() calls into
Peter Hutterer 63b1c55
  XkbUpdateIndicators() -> XkbUpdateLedAutoState() to update SLIs (if any) for
Peter Hutterer 63b1c55
  the currently changed modifier. But it does so with a mask only for the
Peter Hutterer 63b1c55
  changed modifier (i.e. for Shift).
Peter Hutterer 63b1c55
* XkbUpdateLedAutoState() calculates the state based on this mask and
Peter Hutterer 63b1c55
  ends up with 0 because we don't have a Shift LED and we masked out the
Peter Hutterer 63b1c55
  others.
Peter Hutterer 63b1c55
* XkbUpdateLedAutoState() compares that state with the previous state (which
Peter Hutterer 63b1c55
  is still 0x2) and then proceeds to turn the LED off
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
This doesn't happen in the normal case because either the mask encompasses all
Peter Hutterer 63b1c55
modifiers or the state matches of the masked-out modifiers matches the old
Peter Hutterer 63b1c55
state.
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
Avoid this issue by forcing an SLI update after changing the keymap. This
Peter Hutterer 63b1c55
updates the sli->effectiveState and thus restores everything to happy working
Peter Hutterer 63b1c55
order.
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
https://bugzilla.redhat.com/show_bug.cgi?id=1047151
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Peter Hutterer 63b1c55
---
Peter Hutterer 63b1c55
 include/xkbsrv.h | 4 ++++
Peter Hutterer 63b1c55
 xkb/xkb.c        | 3 ++-
Peter Hutterer 63b1c55
 xkb/xkbLEDs.c    | 2 +-
Peter Hutterer 63b1c55
 3 files changed, 7 insertions(+), 2 deletions(-)
Peter Hutterer 63b1c55
Peter Hutterer 63b1c55
diff --git a/include/xkbsrv.h b/include/xkbsrv.h
Peter Hutterer 63b1c55
index cc6307a..7e71089 100644
Peter Hutterer 63b1c55
--- a/include/xkbsrv.h
Peter Hutterer 63b1c55
+++ b/include/xkbsrv.h
Peter Hutterer 63b1c55
@@ -496,6 +496,10 @@ extern _X_EXPORT void XkbUpdateIndicators(DeviceIntPtr /* keybd */ ,
Peter Hutterer 63b1c55
                                           XkbEventCausePtr      /* cause */
Peter Hutterer 63b1c55
     );
Peter Hutterer 63b1c55
 
Peter Hutterer 63b1c55
+extern _X_EXPORT void XkbUpdateAllDeviceIndicators(XkbChangesPtr /* changes */,
Peter Hutterer 63b1c55
+                                                   XkbEventCausePtr /* cause */
Peter Hutterer 63b1c55
+    );
Peter Hutterer 63b1c55
+
Peter Hutterer 63b1c55
 extern _X_EXPORT XkbSrvLedInfoPtr XkbAllocSrvLedInfo(DeviceIntPtr /* dev */ ,
Peter Hutterer 63b1c55
                                                      KbdFeedbackPtr /* kf */ ,
Peter Hutterer 63b1c55
                                                      LedFeedbackPtr /* lf */ ,
Peter Hutterer 63b1c55
diff --git a/xkb/xkb.c b/xkb/xkb.c
Peter Hutterer 63b1c55
index 294cdf8..3a6ad65 100644
Peter Hutterer 63b1c55
--- a/xkb/xkb.c
Peter Hutterer 63b1c55
+++ b/xkb/xkb.c
Peter Hutterer 63b1c55
@@ -5692,7 +5692,6 @@ ProcXkbListComponents(ClientPtr client)
Peter Hutterer 63b1c55
 }
Peter Hutterer 63b1c55
 
Peter Hutterer 63b1c55
 /***====================================================================***/
Peter Hutterer 63b1c55
-
Peter Hutterer 63b1c55
 int
Peter Hutterer 63b1c55
 ProcXkbGetKbdByName(ClientPtr client)
Peter Hutterer 63b1c55
 {
Peter Hutterer 63b1c55
@@ -6017,6 +6016,8 @@ ProcXkbGetKbdByName(ClientPtr client)
Peter Hutterer 63b1c55
         new = NULL;
Peter Hutterer 63b1c55
     }
Peter Hutterer 63b1c55
     XkbFreeComponentNames(&names, FALSE);
Peter Hutterer 63b1c55
+    XkbUpdateAllDeviceIndicators(NULL, NULL);
Peter Hutterer 63b1c55
+
Peter Hutterer 63b1c55
     return Success;
Peter Hutterer 63b1c55
 }
Peter Hutterer 63b1c55
 
Peter Hutterer 63b1c55
diff --git a/xkb/xkbLEDs.c b/xkb/xkbLEDs.c
Peter Hutterer 63b1c55
index 4e16002..5792d9f 100644
Peter Hutterer 63b1c55
--- a/xkb/xkbLEDs.c
Peter Hutterer 63b1c55
+++ b/xkb/xkbLEDs.c
Peter Hutterer 63b1c55
@@ -304,7 +304,7 @@ XkbUpdateLedAutoState(DeviceIntPtr dev,
Peter Hutterer 63b1c55
     return;
Peter Hutterer 63b1c55
 }
Peter Hutterer 63b1c55
 
Peter Hutterer 63b1c55
-static void
Peter Hutterer 63b1c55
+void
Peter Hutterer 63b1c55
 XkbUpdateAllDeviceIndicators(XkbChangesPtr changes, XkbEventCausePtr cause)
Peter Hutterer 63b1c55
 {
Peter Hutterer 63b1c55
     DeviceIntPtr edev;
Peter Hutterer 63b1c55
-- 
Peter Hutterer 63b1c55
2.7.4
Peter Hutterer 63b1c55