From 6aedc488d3f4b2c1c42dd486f634eeb9ea403a5a Mon Sep 17 00:00:00 2001 From: Josh Dowell 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. --- src/video/windows/SDL_windowsevents.c | 4 ++++ src/video/windows/SDL_windowsgameinput.cpp | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index ad55c6711f..58fafd38e5 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -701,6 +701,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.cpp b/src/video/windows/SDL_windowsgameinput.cpp index 084b93c34e..265cb6dd25 100644 --- a/src/video/windows/SDL_windowsgameinput.cpp +++ b/src/video/windows/SDL_windowsgameinput.cpp @@ -279,6 +279,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; } } @@ -308,6 +311,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;