emscripten: Do a little better at tracking Caps/Num/Scroll Lock state.

Fixes #5447.
This commit is contained in:
Ryan C. Gordon
2025-09-13 01:48:21 -04:00
parent 2ea1ea1011
commit 98e22213da

View File

@@ -1239,6 +1239,17 @@ void Emscripten_UnregisterGlobalEventHandlers(SDL_VideoDevice *device)
emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL);
}
EMSCRIPTEN_KEEPALIVE void Emscripten_HandleLockKeysCheck(SDL_WindowData *window_data, EM_BOOL capslock, EM_BOOL numlock, EM_BOOL scrolllock)
{
const SDL_Keymod new_mods = (capslock ? SDL_KMOD_CAPS : 0) | (numlock ? SDL_KMOD_NUM : 0) | (scrolllock ? SDL_KMOD_SCROLL : 0);
SDL_Keymod modstate = SDL_GetModState();
if ((modstate & (SDL_KMOD_CAPS|SDL_KMOD_NUM|SDL_KMOD_SCROLL)) != new_mods) {
modstate &= ~(SDL_KMOD_CAPS|SDL_KMOD_NUM|SDL_KMOD_SCROLL);
modstate |= new_mods;
SDL_SetModState(modstate);
}
}
void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
{
const char *keyElement;
@@ -1250,6 +1261,19 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element);
if (keyElement) {
MAIN_THREAD_EM_ASM_INT({
var data = $0;
// our keymod state can get confused in various ways (changed capslock when browser didn't have focus, etc), and you can't query the current
// state from the DOM, outside of a keyboard event, so catch keypresses globally and reset mod state if it's unexpectedly wrong. Best we can do.
// Note that this thing _only_ adjusts the lock keys if necessary; the real SDL keypress handling happens elsewhere.
document.sdlEventHandlerLockKeysCheck = function(event) {
// don't try to adjust the state on the actual lock key presses; the normal key handler will catch that and adjust.
if ((event.key != "CapsLock") && (event.key != "NumLock") && (event.key != "ScrollLock")) {
_Emscripten_HandleLockKeysCheck(data, event.getModifierState("CapsLock"), event.getModifierState("NumLock"), event.getModifierState("ScrollLock"));
}
};
document.addEventListener("keydown", document.sdlEventHandlerLockKeysCheck);
}, data);
emscripten_set_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
@@ -1288,6 +1312,9 @@ void Emscripten_UnregisterEventHandlers(SDL_WindowData *data)
emscripten_set_keydown_callback(keyElement, NULL, 0, NULL);
emscripten_set_keyup_callback(keyElement, NULL, 0, NULL);
emscripten_set_keypress_callback(keyElement, NULL, 0, NULL);
MAIN_THREAD_EM_ASM_INT({
document.removeEventListener("keydown", document.sdlEventHandlerLockKeysCheck);
});
}
emscripten_set_visibilitychange_callback(NULL, 0, NULL);