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 99734d8a561cf978
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
     1.1 --- a/src/events/SDL_keyboard.c	Sun Dec 27 23:39:43 2015 -0500
     1.2 +++ b/src/events/SDL_keyboard.c	Mon Dec 28 13:07:44 2015 -0500
     1.3 @@ -845,6 +845,19 @@
     1.4      keyboard->modstate = modstate;
     1.5  }
     1.6  
     1.7 +/* Note that SDL_ToggleModState() is not a public API. SDL_SetModState() is. */
     1.8 +void
     1.9 +SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle)
    1.10 +{
    1.11 +    SDL_Keyboard *keyboard = &SDL_keyboard;
    1.12 +    if (toggle) {
    1.13 +        keyboard->modstate |= modstate;
    1.14 +    } else {
    1.15 +        keyboard->modstate &= ~modstate;
    1.16 +    }
    1.17 +}
    1.18 +
    1.19 +
    1.20  SDL_Keycode
    1.21  SDL_GetKeyFromScancode(SDL_Scancode scancode)
    1.22  {
     2.1 --- a/src/events/SDL_keyboard_c.h	Sun Dec 27 23:39:43 2015 -0500
     2.2 +++ b/src/events/SDL_keyboard_c.h	Mon Dec 28 13:07:44 2015 -0500
     2.3 @@ -62,6 +62,9 @@
     2.4  /* Convert to UTF-8 */
     2.5  extern char *SDL_UCS4ToUTF8(Uint32 ch, char *dst);
     2.6  
     2.7 +/* Toggle on or off pieces of the keyboard mod state. */
     2.8 +extern void SDL_ToggleModState(const SDL_Keymod modstate, const SDL_bool toggle);
     2.9 +
    2.10  #endif /* _SDL_keyboard_c_h */
    2.11  
    2.12  /* vi: set ts=4 sw=4 expandtab: */
     3.1 --- a/src/video/cocoa/SDL_cocoakeyboard.m	Sun Dec 27 23:39:43 2015 -0500
     3.2 +++ b/src/video/cocoa/SDL_cocoakeyboard.m	Mon Dec 28 13:07:44 2015 -0500
     3.3 @@ -341,8 +341,7 @@
     3.4      newMask = newMods & NSAlphaShiftKeyMask;
     3.5  
     3.6      if (oldMask != newMask) {
     3.7 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
     3.8 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
     3.9 +        SDL_ToggleModState(KMOD_CAPS, newMask != 0);
    3.10      }
    3.11  }
    3.12  
    3.13 @@ -501,10 +500,7 @@
    3.14      /* On pre-10.6, you might have the initial capslock key state wrong. */
    3.15      if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
    3.16          data->modifierFlags = [NSEvent modifierFlags];
    3.17 -        if (data->modifierFlags & NSAlphaShiftKeyMask) {
    3.18 -            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
    3.19 -            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
    3.20 -        }
    3.21 +        SDL_ToggleModState(KMOD_CAPS, (data->modifierFlags & NSAlphaShiftKeyMask) != 0);
    3.22      }
    3.23  }
    3.24  
     4.1 --- a/src/video/cocoa/SDL_cocoawindow.m	Sun Dec 27 23:39:43 2015 -0500
     4.2 +++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Dec 28 13:07:44 2015 -0500
     4.3 @@ -589,15 +589,11 @@
     4.4          [NSMenu setMenuBarVisible:NO];
     4.5      }
     4.6  
     4.7 -    /* On pre-10.6, you might have the capslock key state wrong now. */
     4.8 +    /* On pre-10.6, you might have the capslock key state wrong now because we can't check here. */
     4.9      if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_6) {
    4.10 -        const unsigned int oldflags = _data->videodata->modifierFlags & NSAlphaShiftKeyMask;
    4.11          const unsigned int newflags = [NSEvent modifierFlags] & NSAlphaShiftKeyMask;
    4.12 -        if (oldflags != newflags) {
    4.13 -            _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
    4.14 -            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
    4.15 -            SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
    4.16 -        }
    4.17 +        _data->videodata->modifierFlags = (_data->videodata->modifierFlags & ~NSAlphaShiftKeyMask) | newflags;
    4.18 +        SDL_ToggleModState(KMOD_CAPS, newflags != 0);
    4.19      }
    4.20  }
    4.21  
     5.1 --- a/src/video/windows/SDL_windowskeyboard.c	Sun Dec 27 23:39:43 2015 -0500
     5.2 +++ b/src/video/windows/SDL_windowskeyboard.c	Mon Dec 28 13:07:44 2015 -0500
     5.3 @@ -104,18 +104,8 @@
     5.4      SDL_SetScancodeName(SDL_SCANCODE_RGUI, "Right Windows");
     5.5  
     5.6      /* Are system caps/num/scroll lock active? Set our state to match. */
     5.7 -    if (GetKeyState(VK_CAPITAL) & 0x0001) {
     5.8 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
     5.9 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
    5.10 -    }
    5.11 -    if (GetKeyState(VK_NUMLOCK) & 0x0001) {
    5.12 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
    5.13 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
    5.14 -    }
    5.15 -    if (GetKeyState(VK_SCROLL) & 0x0001) {
    5.16 -        SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
    5.17 -        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
    5.18 -    }
    5.19 +    SDL_ToggleModState(KMOD_CAPS, (GetKeyState(VK_CAPITAL) & 0x0001) != 0);
    5.20 +    SDL_ToggleModState(KMOD_NUM, (GetKeyState(VK_NUMLOCK) & 0x0001) != 0);
    5.21  }
    5.22  
    5.23  void
     6.1 --- a/src/video/x11/SDL_x11events.c	Sun Dec 27 23:39:43 2015 -0500
     6.2 +++ b/src/video/x11/SDL_x11events.c	Mon Dec 28 13:07:44 2015 -0500
     6.3 @@ -348,27 +348,10 @@
     6.4  
     6.5      X11_XQueryKeymap(display, keys);
     6.6  
     6.7 -    /* Get the keyboard modifier state */
     6.8 +    /* Sync up the keyboard modifier state */
     6.9      if (X11_XQueryPointer(display, DefaultRootWindow(display), &junk_window, &junk_window, &x, &y, &x, &y, &mask)) {
    6.10 -        unsigned num_mask = X11_GetNumLockModifierMask(_this);
    6.11 -        const Uint8 *keystate = SDL_GetKeyboardState(NULL);
    6.12 -        Uint8 capslockState = keystate[SDL_SCANCODE_CAPSLOCK];
    6.13 -        Uint8 numlockState = keystate[SDL_SCANCODE_NUMLOCKCLEAR];
    6.14 -
    6.15 -        /* Toggle key mod state if needed */
    6.16 -        if (!!(mask & LockMask) != !!(SDL_GetModState() & KMOD_CAPS)) {
    6.17 -            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
    6.18 -            if (capslockState == SDL_RELEASED) {
    6.19 -                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
    6.20 -            }
    6.21 -        }
    6.22 -
    6.23 -        if (!!(mask & num_mask) != !!(SDL_GetModState() & KMOD_NUM)) {
    6.24 -            SDL_SendKeyboardKey(SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
    6.25 -            if (numlockState == SDL_RELEASED) {
    6.26 -                SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
    6.27 -            }
    6.28 -        }
    6.29 +        SDL_ToggleModState(KMOD_CAPS, (mask & LockMask) != 0);
    6.30 +        SDL_ToggleModState(KMOD_NUM, (mask & X11_GetNumLockModifierMask(_this)) != 0);
    6.31      }
    6.32  
    6.33      for (keycode = 0; keycode < 256; ++keycode) {