From 257b7af247b9dbda1c69a1dbb88f4438b8631ee7 Mon Sep 17 00:00:00 2001 From: "Ryan C. Gordon" Date: Mon, 28 Dec 2015 13:07:44 -0500 Subject: [PATCH] Sync up the caps/numlock state properly without sending key events. Partially fixes Bugzilla #2736 and #3125. --- src/events/SDL_keyboard.c | 13 +++++++++++++ src/events/SDL_keyboard_c.h | 3 +++ src/video/cocoa/SDL_cocoakeyboard.m | 8 ++------ src/video/cocoa/SDL_cocoawindow.m | 10 +++------- src/video/windows/SDL_windowskeyboard.c | 14 ++------------ src/video/x11/SDL_x11events.c | 23 +++-------------------- 6 files changed, 26 insertions(+), 45 deletions(-) diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c index d4dc0e7bc70ec..97b90f719f4e6 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 50fb06da730f5..2e51052cd99ff 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 f27709e561bc8..95598e718617f 100644 --- a/src/video/cocoa/SDL_cocoakeyboard.m +++ b/src/video/cocoa/SDL_cocoakeyboard.m @@ -341,8 +341,7 @@ - (NSArray *)validAttributesForMarkedText 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 @@ - (NSArray *)validAttributesForMarkedText /* 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 3ed4078532cec..009d15ab5bf1e 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -589,15 +589,11 @@ - (void)windowDidBecomeKey:(NSNotification *)aNotification [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 c98cb3e25307f..1db8bbcd5d88b 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 2f730c440ca6a..c8addca49c36a 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) {