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 7561 65f2b183e2aa
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
--- a/src/video/windows/SDL_windowsevents.c	Wed Jul 31 21:31:23 2013 -0700
+++ b/src/video/windows/SDL_windowsevents.c	Thu Aug 01 01:50:02 2013 -0400
@@ -766,11 +766,24 @@
 void
 WIN_PumpEvents(_THIS)
 {
+    const Uint8 *keystate;
     MSG msg;
     while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
     }
+
+    /* Windows loses a shift KEYUP event when you have both pressed at once and let go of one.
+       You won't get a KEYUP until both are released, and that keyup will only be for the second
+       key you released. Take heroic measures and check the keystate as of the last handled event,
+       and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
+    keystate = SDL_GetKeyboardState(NULL);
+    if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
+        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_LSHIFT);
+    }
+    if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
+        SDL_SendKeyboardKey(SDL_RELEASED, SDL_SCANCODE_RSHIFT);
+    }
 }
 
 static int app_registered = 0;