From b718753ebf9e9113d8bee97ccd659cd7d61f8233 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 18 May 2022 08:50:59 -0700
Subject: [PATCH] Don't send mouse events when warping in relative mode
This fixes games which set relative mode and then did mouse warping at the same time
Reference https://github.com/libsdl-org/SDL/issues/5609
---
src/events/SDL_mouse.c | 31 ++++++++++++++++++++++++++-----
1 file changed, 26 insertions(+), 5 deletions(-)
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index 254182cc5ac..e6ad53065cf 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -866,8 +866,8 @@ SDL_GetGlobalMouseState(int *x, int *y)
}
}
-void
-SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
+static void
+SDL_PerformWarpMouseInWindow(SDL_Window *window, int x, int y, SDL_bool ignore_relative_mode)
{
SDL_Mouse *mouse = SDL_GetMouse();
@@ -883,6 +883,20 @@ SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
return;
}
+ if (mouse->relative_mode && !ignore_relative_mode) {
+ /* 2.0.22 made warping in relative mode actually functional, which
+ * surprised many applications that weren't expecting the additional
+ * mouse motion.
+ *
+ * So for now, warping in relative mode adjusts the absolution position
+ * but doesn't generate motion events.
+ */
+ mouse->x = x;
+ mouse->y = y;
+ mouse->has_position = SDL_TRUE;
+ return;
+ }
+
/* Ignore the previous position when we warp */
mouse->has_position = SDL_FALSE;
@@ -894,6 +908,12 @@ SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
}
}
+void
+SDL_WarpMouseInWindow(SDL_Window * window, int x, int y)
+{
+ SDL_PerformWarpMouseInWindow(window, x, y, SDL_FALSE);
+}
+
int
SDL_WarpMouseGlobal(int x, int y)
{
@@ -953,8 +973,9 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
if (enabled && focusWindow) {
SDL_SetMouseFocus(focusWindow);
- if (mouse->relative_mode_warp)
- SDL_WarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2);
+ if (mouse->relative_mode_warp) {
+ SDL_PerformWarpMouseInWindow(focusWindow, focusWindow->w/2, focusWindow->h/2, SDL_TRUE);
+ }
}
if (focusWindow) {
@@ -962,7 +983,7 @@ SDL_SetRelativeMouseMode(SDL_bool enabled)
/* Put the cursor back to where the application expects it */
if (!enabled) {
- SDL_WarpMouseInWindow(focusWindow, mouse->x, mouse->y);
+ SDL_PerformWarpMouseInWindow(focusWindow, mouse->x, mouse->y, SDL_TRUE);
}
SDL_UpdateMouseCapture(SDL_FALSE);