Sync up the caps/numlock state properly without sending key events.
authorRyan C. Gordon <icculus@icculus.org>
Mon, 28 Dec 2015 13:07:44 -0500
changeset 9973 4d8a561cf978
parent 9972 734c90ea9990
child 9974 05770dc93c95
Sync up the caps/numlock state properly without sending key events. Partially fixes Bugzilla #2736 and #3125.
src/events/SDL_keyboard.c
src/events/SDL_keyboard_c.h
src/video/cocoa/SDL_cocoakeyboard.m
src/video/cocoa/SDL_cocoawindow.m
src/video/windows/SDL_windowskeyboard.c
src/video/x11/SDL_x11events.c
--- a/src/events/SDL_keyboard.c	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/events/SDL_keyboard.c	Mon Dec 28 13:07:44 2015 -0500
@@ -845,6 +845,19 @@
     keyboard->modstate = modstate;
 }
 
+/* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */
+void
+SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
+{
+    SDL_Keyboard *keyboard = &SDL_keyboard;
+    if (toggle) {
+        keyboard->modstate |= modstate;
+    } else {
+        keyboard->modstate &= ~modstate;
+    }
+}
+
+
 SDL_Keycode
 SDL_GetKeyFromScancode(SDL_Scancode scancode)
 {
--- a/src/events/SDL_keyboard_c.h	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/events/SDL_keyboard_c.h	Mon Dec 28 13:07:44 2015 -0500
@@ -62,6 +62,9 @@
 /* Convert to UTF-8 */
 extern char *SDL_UCS4ToUTF8(Uint32 ch, char *dst);
 
+/* Toggle on or off pieces of the keyboard mod state. */
+extern void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle);
+
 #endif /* _SDL_keyboard_c_h */
 
 /* vi: set ts=4 sw=4 expandtab: */
--- a/src/video/cocoa/SDL_cocoakeyboard.m	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/video/cocoa/SDL_cocoakeyboard.m	Mon Dec 28 13:07:44 2015 -0500
@@ -341,8 +341,7 @@
     newMask = newMods & NSAlphaShiftKeyMask;
 
     if (oldMask != newMask) {
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
+        SDL_ToggleModState(KMOD_CAPS, newMask != 0);
     }
 }
 
@@ -501,10 +500,7 @@
     /* On pre-10.6, you might have the initial capslock key state wrong. */
     if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
         data->modifierFlags = [NSEvent modifierFlags];
-        if (data->modifierFlags & NSAlphaShiftKeyMask) {
-            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-        }
+        SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
     }
 }
 
--- a/src/video/cocoa/SDL_cocoawindow.m	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Dec 28 13:07:44 2015 -0500
@@ -589,15 +589,11 @@
         [NSMenu setMenuBarVisible:NO];
     }
 
-    /* On pre-10.6, you might have the capslock key state wrong now. */
+    /* On pre-10.6, you might have the capslock key state wrong now because we can't check here. */
     if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
-        const unsigned int oldflags = _data->videodata->modifierFlags & NSAlphaShiftKeyMask;
         const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
-        if (oldflags != newflags) {
-            _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
-            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-        }
+        _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
+        SDL_ToggleModState(KMOD_CAPS, newflags != 0);
     }
 }
 
--- a/src/video/windows/SDL_windowskeyboard.c	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/video/windows/SDL_windowskeyboard.c	Mon Dec 28 13:07:44 2015 -0500
@@ -104,18 +104,8 @@
     SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows");
 
     /* Are system caps/num/scroll lock active? Set our state to match. */
-    if (GetKeyState(VK_CAPITAL) & 0x0001) {
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-    }
-    if (GetKeyState(VK_NUMLOCK) & 0x0001) {
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
-    }
-    if (GetKeyState(VK_SCROLL) & 0x0001) {
-        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
-        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
-    }
+    SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
+    SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
 }
 
 void
--- a/src/video/x11/SDL_x11events.c	Sun Dec 27 23:39:43 2015 -0500
+++ b/src/video/x11/SDL_x11events.c	Mon Dec 28 13:07:44 2015 -0500
@@ -348,27 +348,10 @@
 
     X11_XQueryKeymap(display, keys);
 
-    /* Get the keyboard modifier state */
+    /* Sync up the keyboard modifier state */
     if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) {
-        unsigned num_mask = X11_GetNumLockModifierMask(_this);
-        const Uint8 *keystate = SDL_GetKeyboardState(NULL);
-        Uint8 capslockState = keystate[SDL_SCANCODE_CAPSLOCK];
-        Uint8 numlockState = keystate[SDL_SCANCODE_NUMLOCKCLEAR];
-
-        /* Toggle key mod state if needed */
-        if (!!(mask & LockMask) != !!(SDL_GetModState() & KMOD_CAPS)) {
-            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
-            if (capslockState == SDL_RELEASED) {
-                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
-            }
-        }
-
-        if (!!(mask & num_mask) != !!(SDL_GetModState() & KMOD_NUM)) {
-            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
-            if (numlockState == SDL_RELEASED) {
-                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
-            }
-        }
+        SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0);
+        SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0);
     }
 
     for (keycode = 0; keycode < 256; ++keycode) {