mirror of
https://github.com/encounter/SDL.git
synced 2025-12-21 10:49:12 +00:00
Implement keyboard grab support for Windows
This is implemented via a low-level keyboard hook. Unfortunately, this is rather invasive, but it's how Microsoft recommends that it be done [0]. We want to do as little as possible in the hook, so we only intercept a few crucial modifier keys there, while leaving other keys to the normal event processing flow. We will only install this hook if SDL_HINT_GRAB_KEYBOARD=1, which is not the default. This will reduce any compatibility concerns to just the SDL applications that explicitly ask for this behavior. We also remove the hook when the grab is terminated to ensure that we're not unnecessarily staying involved in key event processing when it's not required anymore. [0]: https://docs.microsoft.com/en-us/windows/win32/dxtecharts/disabling-shortcut-keys-in-games
This commit is contained in:
@@ -428,6 +428,47 @@ static SDL_MOUSE_EVENT_SOURCE GetMouseMessageSource()
|
||||
return SDL_MOUSE_EVENT_SOURCE_MOUSE;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (nCode < 0 || nCode != HC_ACTION) {
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
KBDLLHOOKSTRUCT* hookData = (KBDLLHOOKSTRUCT*)lParam;
|
||||
SDL_Scancode scanCode;
|
||||
switch (hookData->vkCode) {
|
||||
case VK_LWIN:
|
||||
scanCode = SDL_SCANCODE_LGUI;
|
||||
break;
|
||||
case VK_RWIN:
|
||||
scanCode = SDL_SCANCODE_RGUI;
|
||||
break;
|
||||
case VK_LMENU:
|
||||
scanCode = SDL_SCANCODE_LALT;
|
||||
break;
|
||||
case VK_RMENU:
|
||||
scanCode = SDL_SCANCODE_RALT;
|
||||
break;
|
||||
case VK_LCONTROL:
|
||||
scanCode = SDL_SCANCODE_LCTRL;
|
||||
break;
|
||||
case VK_RCONTROL:
|
||||
scanCode = SDL_SCANCODE_RCTRL;
|
||||
break;
|
||||
default:
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
}
|
||||
|
||||
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
|
||||
SDL_SendKeyboardKey(SDL_PRESSED, scanCode);
|
||||
} else {
|
||||
SDL_SendKeyboardKey(SDL_RELEASED, scanCode);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK
|
||||
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user