Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/video/emscripten/SDL_emscriptenevents.c
Original file line number Diff line number Diff line change
Expand Up @@ -1327,11 +1327,33 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data)

keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element);
if (keyElement) {
// Emscripten's HTML5 helpers do not deduplicate `addEventListener` calls:
// see `registerOrRemoveHandler` in `emscripten/src/lib/libhtml5.js`.
//
// If a previous SDL window already registered keyboard handlers on the same
// target, the new registration would *stack* a second listener, causing every
// browser keydown to fire `Emscripten_HandleKey` twice.
//
// The duplicate calls then produce two `SDL_EVENT_KEY_DOWN` events per physical
// keypress (the second one with `repeat=true`, due to the keystate-based repeat
// detection in `SDL_SendKeyboardKeyInternal`).
//
// We must clear any prior handler on this target before installing ours:
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({
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.

// Remove any prior listener first -- `addEventListener` does not deduplicate either.
if (document.sdlEventHandlerLockKeysCheck) {
document.removeEventListener("keydown", document.sdlEventHandlerLockKeysCheck);
}

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"))
Expand Down
Loading