From cc8ec6cf189da048e5f46b1e63b8e07c8660f006 Mon Sep 17 00:00:00 2001 From: Temdog007 <37945129+Temdog007@users.noreply.github.com> Date: Wed, 2 Apr 2025 07:21:21 -0700 Subject: [PATCH] Handle global mouse state for Emscripten (#12669) --- src/video/emscripten/SDL_emscriptenmouse.c | 60 ++++++++++++++++++++++ test/testmouse.c | 6 +++ 2 files changed, 66 insertions(+) diff --git a/src/video/emscripten/SDL_emscriptenmouse.c b/src/video/emscripten/SDL_emscriptenmouse.c index c959804dca..56938ca206 100644 --- a/src/video/emscripten/SDL_emscriptenmouse.c +++ b/src/video/emscripten/SDL_emscriptenmouse.c @@ -196,6 +196,26 @@ static bool Emscripten_SetRelativeMouseMode(bool enabled) return false; } +static SDL_MouseButtonFlags Emscripten_GetGlobalMouseState(float *x, float *y) +{ + *x = MAIN_THREAD_EM_ASM_DOUBLE({ + return Module['SDL3']['mouse_x']; + }); + *y = MAIN_THREAD_EM_ASM_DOUBLE({ + return Module['SDL3']['mouse_y']; + }); + SDL_MouseButtonFlags flags = 0; + for (int i = 0; i < 5; ++i) { + const bool button_down = MAIN_THREAD_EM_ASM_INT({ + return Module['SDL3']['mouse_buttons'][$0]; + }, i); + if (button_down) { + flags |= 1 << i; + } + } + return flags; +} + void Emscripten_InitMouse(void) { SDL_Mouse *mouse = SDL_GetMouse(); @@ -206,6 +226,46 @@ void Emscripten_InitMouse(void) mouse->CreateSystemCursor = Emscripten_CreateSystemCursor; mouse->SetRelativeMouseMode = Emscripten_SetRelativeMouseMode; + // Add event listeners to track mouse events on the document + MAIN_THREAD_EM_ASM({ + if (!Module['SDL3']) { + Module['SDL3'] = {}; + } + var SDL3 = Module['SDL3']; + SDL3['mouse_x'] = 0; + SDL3['mouse_y'] = 0; + /* + Based on https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button + Possible value for button in the event object is [0, 5) + NOTE: Some browsers do not allow handling the forwards and backwards buttons + */ + SDL3['mouse_buttons'] = []; + for (var i = 0; i < 5; ++i) { + SDL3['mouse_buttons'][i] = false; + } + document.addEventListener('mousemove', function(e) { + // Reacquire from object in case it changed for some reason + var SDL3 = Module['SDL3']; + SDL3['mouse_x'] = e.clientX; + SDL3['mouse_y'] = e.clientY; + }); + document.addEventListener('mousedown', function(e) { + // Reacquire from object in case it changed for some reason + var SDL3 = Module['SDL3']; + if (0 <= e.button && e.button < SDL3['mouse_buttons'].length) { + SDL3['mouse_buttons'][e.button] = true; + } + }); + document.addEventListener('mouseup', function(e) { + // Reacquire from object in case it changed for some reason + var SDL3 = Module['SDL3']; + if (0 <= e.button && e.button < SDL3['mouse_buttons'].length) { + SDL3['mouse_buttons'][e.button] = false; + } + }); + }); + mouse->GetGlobalMouseState = Emscripten_GetGlobalMouseState; + SDL_SetDefaultCursor(Emscripten_CreateDefaultCursor()); } diff --git a/test/testmouse.c b/test/testmouse.c index bc839c09a9..05e15eacf5 100644 --- a/test/testmouse.c +++ b/test/testmouse.c @@ -117,6 +117,8 @@ static void loop(void *arg) struct mouse_loop_data *loop_data = (struct mouse_loop_data *)arg; SDL_Event event; SDL_Renderer *renderer = loop_data->renderer; + float fx, fy; + SDL_MouseButtonFlags flags; /* Check for events */ while (SDL_PollEvent(&event)) { @@ -265,6 +267,10 @@ static void loop(void *arg) DrawObject(renderer, active); } + flags = SDL_GetGlobalMouseState(&fx, &fy); + SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); + SDL_RenderDebugTextFormat(renderer, 0, 0, "Global Mouse State: x=%f y=%f flags=%" SDL_PRIu32, fx, fy, flags); + SDL_RenderPresent(renderer); #ifdef SDL_PLATFORM_EMSCRIPTEN