From cc8ec6cf189da048e5f46b1e63b8e07c8660f006 Mon Sep 17 00:00:00 2001
From: Temdog007 <[EMAIL REDACTED]>
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 c959804dca527..56938ca2067d0 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 bc839c09a9d01..05e15eacf565e 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