Commit 20ec1377638e698a994a0a71aaa41c343c869b4b

Ryan C. Gordon 2015-06-30T14:41:17

X11: Call XRefreshKeyboardMapping() when we get various MappingNotify events. According to the Xlib docs, you need to do this or Xlib's internal state gets out of sync.

diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index e826c4b..309c380 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -649,9 +649,15 @@ X11_DispatchEvent(_THIS)
             }
         } else if (xevent.type == MappingNotify) {
             /* Has the keyboard layout changed? */
+            const int request = xevent.xmapping.request;
+
 #ifdef DEBUG_XEVENTS
             printf("window %p: MappingNotify!\n", data);
 #endif
+            if ((request == MappingKeyboard) || (request == MappingModifier)) {
+                X11_XRefreshKeyboardMapping(&xevent.xmapping);
+            }
+
             X11_UpdateKeymap(_this);
         }
         return;
diff --git a/src/video/x11/SDL_x11sym.h b/src/video/x11/SDL_x11sym.h
index d5bcdc2..9245f19 100644
--- a/src/video/x11/SDL_x11sym.h
+++ b/src/video/x11/SDL_x11sym.h
@@ -152,6 +152,7 @@ SDL_X11_SYM(unsigned long,_XSetLastRequestRead,(Display* a,xGenericReply* b),(a,
 SDL_X11_SYM(SDL_X11_XSynchronizeRetType,XSynchronize,(Display* a,Bool b),(a,b),return)
 SDL_X11_SYM(SDL_X11_XESetWireToEventRetType,XESetWireToEvent,(Display* a,int b,SDL_X11_XESetWireToEventRetType c),(a,b,c),return)
 SDL_X11_SYM(SDL_X11_XESetEventToWireRetType,XESetEventToWire,(Display* a,int b,SDL_X11_XESetEventToWireRetType c),(a,b,c),return)
+SDL_X11_SYM(void,XRefreshKeyboardMapping,(XMappingEvent *a),(a),)
 
 #if SDL_VIDEO_DRIVER_X11_SUPPORTS_GENERIC_EVENTS
 SDL_X11_SYM(Bool,XGetEventData,(Display* a,XGenericEventCookie* b),(a,b),return)