浏览代码

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

Fixes #5447.
Ryan C. Gordon 1 天之前
父节点
当前提交
98e22213da
共有 1 个文件被更改,包括 27 次插入0 次删除
  1. 27 0
      src/video/emscripten/SDL_emscriptenevents.c

+ 27 - 0
src/video/emscripten/SDL_emscriptenevents.c

@@ -1239,6 +1239,17 @@ void Emscripten_UnregisterGlobalEventHandlers(SDL_VideoDevice *device)
     emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, NULL, 0, NULL);
     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)
 void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
 {
 {
     const char *keyElement;
     const char *keyElement;
@@ -1250,6 +1261,19 @@ void Emscripten_RegisterEventHandlers(SDL_WindowData *data)
 
 
     keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element);
     keyElement = Emscripten_GetKeyboardTargetElement(data->keyboard_element);
     if (keyElement) {
     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_keydown_callback(keyElement, data, 0, Emscripten_HandleKey);
         emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
         emscripten_set_keyup_callback(keyElement, data, 0, Emscripten_HandleKey);
         emscripten_set_keypress_callback(keyElement, data, 0, Emscripten_HandleKeyPress);
         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_keydown_callback(keyElement, NULL, 0, NULL);
         emscripten_set_keyup_callback(keyElement, NULL, 0, NULL);
         emscripten_set_keyup_callback(keyElement, NULL, 0, NULL);
         emscripten_set_keypress_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);
     emscripten_set_visibilitychange_callback(NULL, 0, NULL);