SDL2 SDL_GetKeyState() issue

Hello there

I have a Problem with this Function. It does not work properly when the corresponding window gets hidden.

System infos: Windows 7, SDL2.0.9, msys2+mingw_w64.

Issue description:

When a key is pressed while the window gets hidden, SDL_GetKeyState() will keep the state as activated/pressed. Even when the window is shown again, the key still returns as pressed, as long as until it’s really pressed again.
Also, the window itself seems to stay focused on the keyboard (when hidden), at least SDL_GetKeyboardFocus() says so. According to the win32 API, if a window gets hidden, another window should be activated (https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-showwindow SW_HIDE parameter), and I think this should apply in General to SDL aswell?

Expected behaviour:

  • If the window gets hidden, SDL_GetKeyState() should not return any activated keys.
  • The window should loose focus and therefore, SDL_GetKeyboardFocus() should not return the same window.

Workarounds:

I found a workaround, if SDL_MinimizeWindow() followed by SDL_RestoreWindow() are called before hidding the window via SDL_HideWindow(), the keystate is working correctly. However, the window still stays active.

How to reproduce:

For me, it reproduces every time, I wrote a sample to isolate/test it, Keys WASD are defined for testing, W will hide the window (It will be shown again automatically after 3 seconds)

#include <stdio.h>
#include <stdlib.h>

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>

SDL_Window *pWindow;

void updateKeyState(unsigned int *pKeyMap)
{
  const Uint8 *pKeyState;

  SDL_PumpEvents();
  if(SDL_GetKeyboardFocus()!=pWindow)
  {
    puts("Window doesn't have focus!");
    return;
  }

  *pKeyMap=0;
  pKeyState=SDL_GetKeyboardState(NULL);
  if(pKeyState[SDL_SCANCODE_W])
    *pKeyMap|=0x1;
  if(pKeyState[SDL_SCANCODE_A])
    *pKeyMap|=0x2;
  if(pKeyState[SDL_SCANCODE_S])
    *pKeyMap|=0x4;
  if(pKeyState[SDL_SCANCODE_D])
    *pKeyMap|=0x8;
  printf("Keystate: 0x%X\n",*pKeyMap);
}

int main(int argc, char *argv[])
{
  unsigned int keyState=0;
  unsigned int lastState=0;
  int windowVisible;
  Uint32 tmrHidden;

  SDL_Init(SDL_INIT_VIDEO);

  if(!(pWindow=SDL_CreateWindow("TestWindow",200,200,200,200,0)))
  {
    SDL_Quit();
    return(EXIT_FAILURE);
  }
  windowVisible=1;
  while(1)
  {
    lastState=keyState; //Save last state
    updateKeyState(&keyState);
    if((keyState&0x1) && (!(lastState&0x1))) /* W pressed, -> hide window */
    {
      /* Enable the 2 lines below, this will make the Key W reset correctly after window is hidden */
      //SDL_MinimizeWindow(pWindow);
      //SDL_RestoreWindow(pWindow);
      SDL_HideWindow(pWindow);
      windowVisible=0;
      tmrHidden=SDL_GetTicks();
      puts("Window Hidden!");
    }
    /* Bring up window again after 3 seconds.. */
    if((!windowVisible) && (SDL_GetTicks()-tmrHidden>3000))
    {
      puts("Showing window again...");
      SDL_ShowWindow(pWindow);
      windowVisible=1;
    }

    SDL_Delay(20); /* some delay... */
  }
  SDL_DestroyWindow(pWindow);
  SDL_Quit();
  return(0);
}

Is this known issue, or should I open a bug report? Tell me if you need further information.

Regards, XXXBold