Sync up the caps/numlock state properly without sending key events. Partially fixes Bugzilla #2736 and #3125.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index d4dc0e7..97b90f7 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -845,6 +845,19 @@ SDL_SetModState(SDL_Keymod modstate)
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)
{
diff --git a/src/events/SDL_keyboard_c.h b/src/events/SDL_keyboard_c.h
index 50fb06d..2e51052 100644
--- a/src/events/SDL_keyboard_c.h
+++ b/src/events/SDL_keyboard_c.h
@@ -62,6 +62,9 @@ extern void SDL_KeyboardQuit(void);
/* 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: */
diff --git a/src/video/cocoa/SDL_cocoakeyboard.m b/src/video/cocoa/SDL_cocoakeyboard.m
index f27709e..95598e7 100644
--- a/src/video/cocoa/SDL_cocoakeyboard.m
+++ b/src/video/cocoa/SDL_cocoakeyboard.m
@@ -341,8 +341,7 @@ HandleCapsLock(unsigned short scancode,
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 @@ Cocoa_InitKeyboard(_THIS)
/* 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);
}
}
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 3ed4078..009d15a 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -589,15 +589,11 @@ SetWindowStyle(SDL_Window * window, unsigned int style)
[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);
}
}
diff --git a/src/video/windows/SDL_windowskeyboard.c b/src/video/windows/SDL_windowskeyboard.c
index c98cb3e..1db8bbc 100644
--- a/src/video/windows/SDL_windowskeyboard.c
+++ b/src/video/windows/SDL_windowskeyboard.c
@@ -104,18 +104,8 @@ WIN_InitKeyboard(_THIS)
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
diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c
index 2f730c4..c8addca 100644
--- a/src/video/x11/SDL_x11events.c
+++ b/src/video/x11/SDL_x11events.c
@@ -348,27 +348,10 @@ X11_ReconcileKeyboardState(_THIS)
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) {