diff --git a/src/video/emscripten/SDL_emscriptenevents.c b/src/video/emscripten/SDL_emscriptenevents.c index ad8cf913a..94268eaf0 100644 --- a/src/video/emscripten/SDL_emscriptenevents.c +++ b/src/video/emscripten/SDL_emscriptenevents.c @@ -297,13 +297,23 @@ Emscripten_ConvertUTF32toUTF8(Uint32 codepoint, char * text) return SDL_TRUE; } +static EM_BOOL +Emscripten_HandlePointerLockChange(int eventType, const EmscriptenPointerlockChangeEvent *changeEvent, void *userData) +{ + SDL_WindowData *window_data = (SDL_WindowData *) userData; + /* keep track of lock losses, so we can regrab if/when appropriate. */ + window_data->has_pointer_lock = changeEvent->isActive; + return 0; +} + + EM_BOOL Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent, void *userData) { SDL_WindowData *window_data = userData; + const int isPointerLocked = window_data->has_pointer_lock; int mx, my; static double residualx = 0, residualy = 0; - EmscriptenPointerlockChangeEvent pointerlock_status; /* rescale (in case canvas is being scaled)*/ double client_w, client_h, xscale, yscale; @@ -311,10 +321,6 @@ Emscripten_HandleMouseMove(int eventType, const EmscriptenMouseEvent *mouseEvent xscale = window_data->window->w / client_w; yscale = window_data->window->h / client_h; - /* check for pointer lock */ - int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status); - int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE; - if (isPointerLocked) { residualx += mouseEvent->movementX * xscale; residualy += mouseEvent->movementY * yscale; @@ -355,6 +361,9 @@ Emscripten_HandleMouseButton(int eventType, const EmscriptenMouseEvent *mouseEve } if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN) { + if (SDL_GetMouse()->relative_mode && !window_data->has_pointer_lock) { + emscripten_request_pointerlock(NULL, 0); /* try to regrab lost pointer lock. */ + } sdl_button_state = SDL_PRESSED; sdl_event_type = SDL_MOUSEBUTTONDOWN; } else { @@ -371,11 +380,7 @@ Emscripten_HandleMouseFocus(int eventType, const EmscriptenMouseEvent *mouseEven SDL_WindowData *window_data = userData; int mx = mouseEvent->canvasX, my = mouseEvent->canvasY; - EmscriptenPointerlockChangeEvent pointerlock_status; - - /* check for pointer lock */ - int isPointerLockSupported = emscripten_get_pointerlock_status(&pointerlock_status); - int isPointerLocked = isPointerLockSupported == EMSCRIPTEN_RESULT_SUCCESS ? pointerlock_status.isActive : SDL_FALSE; + const int isPointerLocked = window_data->has_pointer_lock; if (!isPointerLocked) { /* rescale (in case canvas is being scaled)*/ @@ -632,6 +637,8 @@ Emscripten_RegisterEventHandlers(SDL_WindowData *data) emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch); emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch); + emscripten_set_pointerlockchange_callback(NULL, data, 0, Emscripten_HandlePointerLockChange); + /* Keyboard events are awkward */ const char *keyElement = SDL_GetHint(SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT); if (!keyElement) keyElement = "#window"; diff --git a/src/video/emscripten/SDL_emscriptenvideo.h b/src/video/emscripten/SDL_emscriptenvideo.h index 024e9c4c7..3e8a1e32b 100644 --- a/src/video/emscripten/SDL_emscriptenvideo.h +++ b/src/video/emscripten/SDL_emscriptenvideo.h @@ -47,6 +47,8 @@ typedef struct SDL_WindowData SDL_bool finger_touching; /* for mapping touch events to mice */ SDL_FingerID first_finger; + + SDL_bool has_pointer_lock; } SDL_WindowData; #endif /* _SDL_emscriptenvideo_h */