From caaaf525833f844a5ca9c2f7984057ae27f8c54e Mon Sep 17 00:00:00 2001
From: Josh Dowell <[EMAIL REDACTED]>
Date: Sat, 21 Jun 2025 09:57:34 +0100
Subject: [PATCH] win32: Invalidate window message mouse button flags when
reading buttons from raw input or GameInput
SDL2 would set a high bit in the mouse button flags to indicate when raw input had been read from, without this, if you hold down a mouse button and left raw input mode (leaving relative mode) the button would remain partially stuck, and would require two clicks to start producing mouse down events again.
SDL3's raw input code was refactored to not use the mouse button flags, but forgot to invalidate the flags, causing this bug to manifest.
(cherry picked from commit 6aedc488d3f4b2c1c42dd486f634eeb9ea403a5a)
---
src/video/windows/SDL_windowsevents.c | 4 ++++
src/video/windows/SDL_windowsgameinput.c | 6 ++++++
2 files changed, 10 insertions(+)
diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c
index 837e0eb26c3cd..274aff1e0830f 100644
--- a/src/video/windows/SDL_windowsevents.c
+++ b/src/video/windows/SDL_windowsevents.c
@@ -732,6 +732,10 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_VideoData *data, HANDL
float fAmount = (float)amount / WHEEL_DELTA;
SDL_SendMouseWheel(WIN_GetEventTimestamp(), window, mouseID, fAmount, 0.0f, SDL_MOUSEWHEEL_NORMAL);
}
+
+ /* Invalidate the mouse button flags. If we don't do this then disabling raw input
+ will cause held down mouse buttons to persist when released. */
+ windowdata->mouse_button_flags = (WPARAM)-1;
}
}
diff --git a/src/video/windows/SDL_windowsgameinput.c b/src/video/windows/SDL_windowsgameinput.c
index 183733a380470..3f4ad804ea20b 100644
--- a/src/video/windows/SDL_windowsgameinput.c
+++ b/src/video/windows/SDL_windowsgameinput.c
@@ -277,6 +277,9 @@ static void GAMEINPUT_InitialMouseReading(WIN_GameInputData *data, SDL_Window *w
bool down = ((state.buttons & mask) != 0);
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
+
+ // Invalidate mouse button flags
+ window->internal->mouse_button_flags = (WPARAM)-1;
}
}
@@ -307,6 +310,9 @@ static void GAMEINPUT_HandleMouseDelta(WIN_GameInputData *data, SDL_Window *wind
SDL_SendMouseButton(timestamp, window, mouseID, GAMEINPUT_button_map[i], down);
}
}
+
+ // Invalidate mouse button flags
+ window->internal->mouse_button_flags = (WPARAM)-1;
}
if (delta.wheelX || delta.wheelY) {
float fAmountX = (float)delta.wheelX / WHEEL_DELTA;