Windows: Unstick shift keys in a timely manner when the OS loses a KEYUP event.
authorRyan C. Gordon <icculus@icculus.org>
Thu, 01 Aug 2013 01:50:02 -0400
changeset 756165f2b183e2aa
parent 7560 1d6717a8b256
child 7562 5287c82340e3
Windows: Unstick shift keys in a timely manner when the OS loses a KEYUP event.

Fixes Bugzilla #1959.
src/video/windows/SDL_windowsevents.c
     1.1 --- a/src/video/windows/SDL_windowsevents.c	Wed Jul 31 21:31:23 2013 -0700
     1.2 +++ b/src/video/windows/SDL_windowsevents.c	Thu Aug 01 01:50:02 2013 -0400
     1.3 @@ -766,11 +766,24 @@
     1.4  void
     1.5  WIN_PumpEvents(_THIS)
     1.6  {
     1.7 +    const Uint8 *keystate;
     1.8      MSG msg;
     1.9      while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
    1.10          TranslateMessage(&msg);
    1.11          DispatchMessage(&msg);
    1.12      }
    1.13 +
    1.14 +    /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
    1.15 +       You won't get a KEYUP until both are released, and that keyup will only be for the second
    1.16 +       key you released. Take heroic measures and check the keystate as of the last handled event,
    1.17 +       and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
    1.18 +    keystate = SDL_GetKeyboardState(NULL);
    1.19 +    if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
    1.20 +        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
    1.21 +    }
    1.22 +    if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
    1.23 +        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
    1.24 +    }
    1.25  }
    1.26  
    1.27  static int app_registered = 0;