SDL: Renamed SDL_Get/SetRelativeMouseMode to SDL_Get/SetWindowRelativeMouseMode()

From 57f9c6f7bb324bf9e0b1fd24d29f1a00968c41c9 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Tue, 6 Aug 2024 07:20:33 -0700
Subject: [PATCH] Renamed SDL_Get/SetRelativeMouseMode to
 SDL_Get/SetWindowRelativeMouseMode()

Fixes https://github.com/libsdl-org/SDL/issues/10041
---
 docs/README-migration.md          |   4 +
 include/SDL3/SDL_mouse.h          |  36 +++----
 include/SDL3/SDL_video.h          |   3 +-
 src/dynapi/SDL_dynapi.sym         |   4 +-
 src/dynapi/SDL_dynapi_overrides.h |   4 +-
 src/dynapi/SDL_dynapi_procs.h     |   4 +-
 src/events/SDL_keyboard.c         |   3 +
 src/events/SDL_mouse.c            |  11 +++
 src/events/SDL_mouse_c.h          |   5 +
 src/test/SDL_test_common.c        |  11 ++-
 src/video/SDL_video.c             |  33 ++++++-
 test/relative_mode.markdown       |   2 +-
 test/testautomation_mouse.c       | 155 +++++++++++++++++-------------
 test/testmanymouse.c              |   6 +-
 test/testrelative.c               |  12 +--
 15 files changed, 184 insertions(+), 109 deletions(-)

diff --git a/docs/README-migration.md b/docs/README-migration.md
index 529dae78a1c25..56e843961c96e 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -1106,6 +1106,10 @@ SDL_SystemCursor's items from SDL2 have been renamed to match CSS cursor names.
 The following functions have been renamed:
 * SDL_FreeCursor() => SDL_DestroyCursor()
 
+The following functions have been removed:
+* SDL_SetRelativeMouseMode() - replaced with SDL_SetWindowRelativeMouseMode()
+* SDL_GetRelativeMouseMode() - replaced with SDL_GetWindowRelativeMouseMode()
+
 The following symbols have been renamed:
 * SDL_SYSTEM_CURSOR_ARROW => SDL_SYSTEM_CURSOR_DEFAULT
 * SDL_SYSTEM_CURSOR_HAND => SDL_SYSTEM_CURSOR_POINTER
diff --git a/include/SDL3/SDL_mouse.h b/include/SDL3/SDL_mouse.h
index 4284eccca141c..814858ea58f89 100644
--- a/include/SDL3/SDL_mouse.h
+++ b/include/SDL3/SDL_mouse.h
@@ -288,23 +288,36 @@ extern SDL_DECLSPEC void SDLCALL SDL_WarpMouseInWindow(SDL_Window * window,
 extern SDL_DECLSPEC int SDLCALL SDL_WarpMouseGlobal(float x, float y);
 
 /**
- * Set relative mouse mode.
+ * Set relative mouse mode for a window.
  *
- * While the mouse is in relative mode, the cursor is hidden, the mouse
+ * While the window has focus and relative mouse mode is enabled, the cursor is hidden, the mouse
  * position is constrained to the window, and SDL will report continuous
  * relative mouse motion even if the mouse is at the edge of the window.
  *
- * This function will flush any pending mouse motion.
+ * This function will flush any pending mouse motion for this window.
  *
+ * \param window the window to change.
  * \param enabled SDL_TRUE to enable relative mode, SDL_FALSE to disable.
  * \returns 0 on success or a negative error code on failure; call
  *          SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_GetRelativeMouseMode
+ * \sa SDL_GetWindowRelativeMouseMode
  */
-extern SDL_DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
+extern SDL_DECLSPEC int SDLCALL SDL_SetWindowRelativeMouseMode(SDL_Window *window, SDL_bool enabled);
+
+/**
+ * Query whether relative mouse mode is enabled for a window.
+ *
+ * \param window the window to query.
+ * \returns SDL_TRUE if relative mode is enabled for a window or SDL_FALSE otherwise.
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_SetWindowRelativeMouseMode
+ */
+extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetWindowRelativeMouseMode(SDL_Window *window);
 
 /**
  * Capture the mouse and to track input outside an SDL window.
@@ -321,7 +334,7 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
  * mouse while the user is dragging something, until the user releases a mouse
  * button. It is not recommended that you capture the mouse for long periods
  * of time, such as the entire time your app is running. For that, you should
- * probably use SDL_SetRelativeMouseMode() or SDL_SetWindowMouseGrab(),
+ * probably use SDL_SetWindowRelativeMouseMode() or SDL_SetWindowMouseGrab(),
  * depending on your goals.
  *
  * While captured, mouse events still report coordinates relative to the
@@ -352,17 +365,6 @@ extern SDL_DECLSPEC int SDLCALL SDL_SetRelativeMouseMode(SDL_bool enabled);
  */
 extern SDL_DECLSPEC int SDLCALL SDL_CaptureMouse(SDL_bool enabled);
 
-/**
- * Query whether relative mouse mode is enabled.
- *
- * \returns SDL_TRUE if relative mode is enabled or SDL_FALSE otherwise.
- *
- * \since This function is available since SDL 3.0.0.
- *
- * \sa SDL_SetRelativeMouseMode
- */
-extern SDL_DECLSPEC SDL_bool SDLCALL SDL_GetRelativeMouseMode(void);
-
 /**
  * Create a cursor using the specified bitmap data and mask (in MSB format).
  *
diff --git a/include/SDL3/SDL_video.h b/include/SDL3/SDL_video.h
index f78a9c16e07cd..97844ef29aaac 100644
--- a/include/SDL3/SDL_video.h
+++ b/include/SDL3/SDL_video.h
@@ -155,7 +155,8 @@ typedef Uint64 SDL_WindowFlags;
 #define SDL_WINDOW_MODAL                SDL_UINT64_C(0x0000000000001000)    /**< window is modal */
 #define SDL_WINDOW_HIGH_PIXEL_DENSITY   SDL_UINT64_C(0x0000000000002000)    /**< window uses high pixel density back buffer if possible */
 #define SDL_WINDOW_MOUSE_CAPTURE        SDL_UINT64_C(0x0000000000004000)    /**< window has mouse captured (unrelated to MOUSE_GRABBED) */
-#define SDL_WINDOW_ALWAYS_ON_TOP        SDL_UINT64_C(0x0000000000008000)    /**< window should always be above others */
+#define SDL_WINDOW_MOUSE_RELATIVE_MODE  SDL_UINT64_C(0x0000000000008000)    /**< window has relative mode enabled */
+#define SDL_WINDOW_ALWAYS_ON_TOP        SDL_UINT64_C(0x0000000000010000)    /**< window should always be above others */
 #define SDL_WINDOW_UTILITY              SDL_UINT64_C(0x0000000000020000)    /**< window should be treated as a utility window, not showing in the task bar and window list */
 #define SDL_WINDOW_TOOLTIP              SDL_UINT64_C(0x0000000000040000)    /**< window should be treated as a tooltip and does not get mouse or keyboard focus, requires a parent window */
 #define SDL_WINDOW_POPUP_MENU           SDL_UINT64_C(0x0000000000080000)    /**< window should be treated as a popup menu, requires a parent window */
diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym
index 572417966d3c5..e9cc39f89228f 100644
--- a/src/dynapi/SDL_dynapi.sym
+++ b/src/dynapi/SDL_dynapi.sym
@@ -386,7 +386,6 @@ SDL3_0.0.0 {
     SDL_GetRectIntersectionFloat;
     SDL_GetRectUnion;
     SDL_GetRectUnionFloat;
-    SDL_GetRelativeMouseMode;
     SDL_GetRelativeMouseState;
     SDL_GetRenderClipRect;
     SDL_GetRenderColorScale;
@@ -485,6 +484,7 @@ SDL3_0.0.0 {
     SDL_GetWindowPixelFormat;
     SDL_GetWindowPosition;
     SDL_GetWindowProperties;
+    SDL_GetWindowRelativeMouseMode;
     SDL_GetWindowSafeArea;
     SDL_GetWindowSize;
     SDL_GetWindowSizeInPixels;
@@ -749,7 +749,6 @@ SDL3_0.0.0 {
     SDL_SetPointerProperty;
     SDL_SetPointerPropertyWithCleanup;
     SDL_SetPrimarySelectionText;
-    SDL_SetRelativeMouseMode;
     SDL_SetRenderClipRect;
     SDL_SetRenderColorScale;
     SDL_SetRenderDrawBlendMode;
@@ -795,6 +794,7 @@ SDL3_0.0.0 {
     SDL_SetWindowMouseRect;
     SDL_SetWindowOpacity;
     SDL_SetWindowPosition;
+    SDL_SetWindowRelativeMouseMode;
     SDL_SetWindowResizable;
     SDL_SetWindowShape;
     SDL_SetWindowSize;
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index 7e8550db84d72..cc28c71b32761 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -411,7 +411,6 @@
 #define SDL_GetRectIntersectionFloat SDL_GetRectIntersectionFloat_REAL
 #define SDL_GetRectUnion SDL_GetRectUnion_REAL
 #define SDL_GetRectUnionFloat SDL_GetRectUnionFloat_REAL
-#define SDL_GetRelativeMouseMode SDL_GetRelativeMouseMode_REAL
 #define SDL_GetRelativeMouseState SDL_GetRelativeMouseState_REAL
 #define SDL_GetRenderClipRect SDL_GetRenderClipRect_REAL
 #define SDL_GetRenderColorScale SDL_GetRenderColorScale_REAL
@@ -510,6 +509,7 @@
 #define SDL_GetWindowPixelFormat SDL_GetWindowPixelFormat_REAL
 #define SDL_GetWindowPosition SDL_GetWindowPosition_REAL
 #define SDL_GetWindowProperties SDL_GetWindowProperties_REAL
+#define SDL_GetWindowRelativeMouseMode SDL_GetWindowRelativeMouseMode_REAL
 #define SDL_GetWindowSafeArea SDL_GetWindowSafeArea_REAL
 #define SDL_GetWindowSize SDL_GetWindowSize_REAL
 #define SDL_GetWindowSizeInPixels SDL_GetWindowSizeInPixels_REAL
@@ -774,7 +774,6 @@
 #define SDL_SetPointerProperty SDL_SetPointerProperty_REAL
 #define SDL_SetPointerPropertyWithCleanup SDL_SetPointerPropertyWithCleanup_REAL
 #define SDL_SetPrimarySelectionText SDL_SetPrimarySelectionText_REAL
-#define SDL_SetRelativeMouseMode SDL_SetRelativeMouseMode_REAL
 #define SDL_SetRenderClipRect SDL_SetRenderClipRect_REAL
 #define SDL_SetRenderColorScale SDL_SetRenderColorScale_REAL
 #define SDL_SetRenderDrawBlendMode SDL_SetRenderDrawBlendMode_REAL
@@ -820,6 +819,7 @@
 #define SDL_SetWindowMouseRect SDL_SetWindowMouseRect_REAL
 #define SDL_SetWindowOpacity SDL_SetWindowOpacity_REAL
 #define SDL_SetWindowPosition SDL_SetWindowPosition_REAL
+#define SDL_SetWindowRelativeMouseMode SDL_SetWindowRelativeMouseMode_REAL
 #define SDL_SetWindowResizable SDL_SetWindowResizable_REAL
 #define SDL_SetWindowShape SDL_SetWindowShape_REAL
 #define SDL_SetWindowSize SDL_SetWindowSize_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 44d96651ae19b..480b38d1c10d9 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -431,7 +431,6 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GetRectIntersection,(const SDL_Rect *a, const SDL_R
 SDL_DYNAPI_PROC(SDL_bool,SDL_GetRectIntersectionFloat,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_GetRectUnion,(const SDL_Rect *a, const SDL_Rect *b, SDL_Rect *c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_GetRectUnionFloat,(const SDL_FRect *a, const SDL_FRect *b, SDL_FRect *c),(a,b,c),return)
-SDL_DYNAPI_PROC(SDL_bool,SDL_GetRelativeMouseMode,(void),(),return)
 SDL_DYNAPI_PROC(SDL_MouseButtonFlags,SDL_GetRelativeMouseState,(float *a, float *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetRenderClipRect,(SDL_Renderer *a, SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetRenderColorScale,(SDL_Renderer *a, float *b),(a,b),return)
@@ -530,6 +529,7 @@ SDL_DYNAPI_PROC(float,SDL_GetWindowPixelDensity,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(SDL_PixelFormat,SDL_GetWindowPixelFormat,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GetWindowPosition,(SDL_Window *a, int *b, int *c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetWindowProperties,(SDL_Window *a),(a),return)
+SDL_DYNAPI_PROC(SDL_bool,SDL_GetWindowRelativeMouseMode,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_GetWindowSafeArea,(SDL_Window *a, SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_GetWindowSize,(SDL_Window *a, int *b, int *c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_GetWindowSizeInPixels,(SDL_Window *a, int *b, int *c),(a,b,c),return)
@@ -784,7 +784,6 @@ SDL_DYNAPI_PROC(int,SDL_SetPaletteColors,(SDL_Palette *a, const SDL_Color *b, in
 SDL_DYNAPI_PROC(int,SDL_SetPointerProperty,(SDL_PropertiesID a, const char *b, void *c),(a,b,c),return)
 SDL_DYNAPI_PROC(int,SDL_SetPointerPropertyWithCleanup,(SDL_PropertiesID a, const char *b, void *c, SDL_CleanupPropertyCallback d, void *e),(a,b,c,d,e),return)
 SDL_DYNAPI_PROC(int,SDL_SetPrimarySelectionText,(const char *a),(a),return)
-SDL_DYNAPI_PROC(int,SDL_SetRelativeMouseMode,(SDL_bool a),(a),return)
 SDL_DYNAPI_PROC(int,SDL_SetRenderClipRect,(SDL_Renderer *a, const SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetRenderColorScale,(SDL_Renderer *a, float b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetRenderDrawBlendMode,(SDL_Renderer *a, SDL_BlendMode b),(a,b),return)
@@ -830,6 +829,7 @@ SDL_DYNAPI_PROC(int,SDL_SetWindowMouseGrab,(SDL_Window *a, SDL_bool b),(a,b),ret
 SDL_DYNAPI_PROC(int,SDL_SetWindowMouseRect,(SDL_Window *a, const SDL_Rect *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowOpacity,(SDL_Window *a, float b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowPosition,(SDL_Window *a, int b, int c),(a,b,c),return)
+SDL_DYNAPI_PROC(int,SDL_SetWindowRelativeMouseMode,(SDL_Window *a, SDL_bool b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowResizable,(SDL_Window *a, SDL_bool b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowShape,(SDL_Window *a, SDL_Surface *b),(a,b),return)
 SDL_DYNAPI_PROC(int,SDL_SetWindowSize,(SDL_Window *a, int b, int c),(a,b,c),return)
diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index ad4bd92010574..45dbdc0e70fcc 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -357,6 +357,9 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
             }
         }
     }
+
+    SDL_UpdateRelativeMouseMode();
+
     return 0;
 }
 
diff --git a/src/events/SDL_mouse.c b/src/events/SDL_mouse.c
index b56fc76434127..7842f2a636283 100644
--- a/src/events/SDL_mouse.c
+++ b/src/events/SDL_mouse.c
@@ -1393,6 +1393,17 @@ SDL_bool SDL_GetRelativeMouseMode(void)
     return mouse->relative_mode;
 }
 
+void SDL_UpdateRelativeMouseMode(void)
+{
+    SDL_Mouse *mouse = SDL_GetMouse();
+    SDL_Window *focus = SDL_GetKeyboardFocus();
+    SDL_bool relative_mode = (focus && (focus->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE));
+
+    if (relative_mode != mouse->relative_mode) {
+        SDL_SetRelativeMouseMode(relative_mode);
+    }
+}
+
 int SDL_UpdateMouseCapture(SDL_bool force_release)
 {
     SDL_Mouse *mouse = SDL_GetMouse();
diff --git a/src/events/SDL_mouse_c.h b/src/events/SDL_mouse_c.h
index acd2e7785b8eb..fd6456f91fe10 100644
--- a/src/events/SDL_mouse_c.h
+++ b/src/events/SDL_mouse_c.h
@@ -179,6 +179,11 @@ extern int SDL_SendMouseWheel(Uint64 timestamp, SDL_Window *window, SDL_MouseID
 /* Warp the mouse within the window, potentially overriding relative mode */
 extern void SDL_PerformWarpMouseInWindow(SDL_Window *window, float x, float y, SDL_bool ignore_relative_mode);
 
+/* Relative mouse mode */
+extern int SDL_SetRelativeMouseMode(SDL_bool enabled);
+extern SDL_bool SDL_GetRelativeMouseMode(void);
+extern void SDL_UpdateRelativeMouseMode(void);
+
 /* TODO RECONNECT: Set mouse state to "zero" */
 #if 0
 extern void SDL_ResetMouse(void);
diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c
index 5f84b36495854..b84e25db21408 100644
--- a/src/test/SDL_test_common.c
+++ b/src/test/SDL_test_common.c
@@ -2353,9 +2353,9 @@ int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event
                 }
             }
             if (withShift) {
-                SDL_Window *current_win = SDL_GetKeyboardFocus();
-                if (current_win) {
-                    const SDL_bool shouldCapture = !(SDL_GetWindowFlags(current_win) & SDL_WINDOW_MOUSE_CAPTURE);
+                SDL_Window *window = SDL_GetWindowFromEvent(event);
+                if (window) {
+                    const SDL_bool shouldCapture = !(SDL_GetWindowFlags(window) & SDL_WINDOW_MOUSE_CAPTURE);
                     const int rc = SDL_CaptureMouse(shouldCapture);
                     SDL_Log("%sapturing mouse %s!\n", shouldCapture ? "C" : "Unc", (rc == 0) ? "succeeded" : "failed");
                 }
@@ -2364,7 +2364,10 @@ int SDLTest_CommonEventMainCallbacks(SDLTest_CommonState *state, const SDL_Event
         case SDLK_R:
             if (withControl) {
                 /* Ctrl-R toggle mouse relative mode */
-                SDL_SetRelativeMouseMode(!SDL_GetRelativeMouseMode());
+                SDL_Window *window = SDL_GetWindowFromEvent(event);
+                if (window) {
+                    SDL_SetWindowRelativeMouseMode(window, !SDL_GetWindowRelativeMouseMode(window));
+                }
             }
             break;
         case SDLK_T:
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index bd8768471a57d..590606eb1e119 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -3780,6 +3780,35 @@ const SDL_Rect *SDL_GetWindowMouseRect(SDL_Window *window)
     }
 }
 
+int SDL_SetWindowRelativeMouseMode(SDL_Window *window, SDL_bool enabled)
+{
+    CHECK_WINDOW_MAGIC(window, -1);
+
+    if (enabled == SDL_GetWindowRelativeMouseMode(window)) {
+        return 0;
+    }
+
+    if (enabled) {
+        window->flags |= SDL_WINDOW_MOUSE_RELATIVE_MODE;
+    } else {
+        window->flags &= ~SDL_WINDOW_MOUSE_RELATIVE_MODE;
+    }
+    SDL_UpdateRelativeMouseMode();
+
+    return 0;
+}
+
+SDL_bool SDL_GetWindowRelativeMouseMode(SDL_Window *window)
+{
+    CHECK_WINDOW_MAGIC(window, SDL_FALSE);
+
+    if (window->flags & SDL_WINDOW_MOUSE_RELATIVE_MODE) {
+        return SDL_TRUE;
+    } else {
+        return SDL_FALSE;
+    }
+}
+
 int SDL_FlashWindow(SDL_Window *window, SDL_FlashOperation operation)
 {
     CHECK_WINDOW_MAGIC(window, -1);
@@ -5389,7 +5418,6 @@ int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
 {
     int dummybutton;
     int retval = -1;
-    SDL_bool relative_mode;
     SDL_bool show_cursor_prev;
     SDL_Window *current_window;
     SDL_MessageBoxData mbdata;
@@ -5403,7 +5431,6 @@ int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
     (void)SDL_AtomicIncRef(&SDL_messagebox_count);
 
     current_window = SDL_GetKeyboardFocus();
-    relative_mode = SDL_GetRelativeMouseMode();
     SDL_UpdateMouseCapture(SDL_FALSE);
     SDL_SetRelativeMouseMode(SDL_FALSE);
     show_cursor_prev = SDL_CursorVisible();
@@ -5477,7 +5504,7 @@ int SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonID)
     if (!show_cursor_prev) {
         SDL_HideCursor();
     }
-    SDL_SetRelativeMouseMode(relative_mode);
+    SDL_UpdateRelativeMouseMode();
     SDL_UpdateMouseCapture(SDL_FALSE);
 
     return retval;
diff --git a/test/relative_mode.markdown b/test/relative_mode.markdown
index 23f04f5fe0a31..bd99c9f0181d5 100644
--- a/test/relative_mode.markdown
+++ b/test/relative_mode.markdown
@@ -42,7 +42,7 @@ Code
         SDL_Init(SDL_INIT_VIDEO);
 
         win = SDL_CreateWindow("Test", 800, 600, 0);
-        SDL_SetRelativeMouseMode(SDL_TRUE);
+        SDL_SetWindowRelativeMouseMode(win, SDL_TRUE);
 
         while (1)
         {
diff --git a/test/testautomation_mouse.c b/test/testautomation_mouse.c
index f24da3a6527bf..fa33f9a1204ed 100644
--- a/test/testautomation_mouse.c
+++ b/test/testautomation_mouse.c
@@ -342,87 +342,97 @@ static int mouse_getCursor(void *arg)
     return TEST_COMPLETED;
 }
 
+#define MOUSE_TESTWINDOW_WIDTH  320
+#define MOUSE_TESTWINDOW_HEIGHT 200
+
+/**
+ * Creates a test window
+ */
+static SDL_Window *createMouseSuiteTestWindow(void)
+{
+    int width = MOUSE_TESTWINDOW_WIDTH, height = MOUSE_TESTWINDOW_HEIGHT;
+    SDL_Window *window;
+    window = SDL_CreateWindow("mousecreateMouseSuiteTestWindow", width, height, 0);
+    SDLTest_AssertPass("SDL_CreateWindow()");
+    SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result");
+    return window;
+}
+
+/**
+ * Destroy test window
+ */
+static void destroyMouseSuiteTestWindow(SDL_Window *window)
+{
+    if (window) {
+        SDL_DestroyWindow(window);
+        window = NULL;
+        SDLTest_AssertPass("SDL_DestroyWindow()");
+    }
+}
+
 /**
- * Check call to SDL_GetRelativeMouseMode and SDL_SetRelativeMouseMode
+ * Check call to SDL_GetWindowRelativeMouseMode and SDL_SetWindowRelativeMouseMode
  *
- * \sa SDL_GetRelativeMouseMode
- * \sa SDL_SetRelativeMouseMode
+ * \sa SDL_GetWindowRelativeMouseMode
+ * \sa SDL_SetWindowRelativeMouseMode
  */
 static int mouse_getSetRelativeMouseMode(void *arg)
 {
+    SDL_Window *window;
     int result;
     int i;
     SDL_bool initialState;
     SDL_bool currentState;
 
+    /* Create test window */
+    window = createMouseSuiteTestWindow();
+    if (!window) {
+        return TEST_ABORTED;
+    }
+
     /* Capture original state so we can revert back to it later */
-    initialState = SDL_GetRelativeMouseMode();
-    SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()");
+    initialState = SDL_GetWindowRelativeMouseMode(window);
+    SDLTest_AssertPass("Call to SDL_GetWindowRelativeMouseMode(window)");
 
     /* Repeat twice to check D->D transition */
     for (i = 0; i < 2; i++) {
         /* Disable - should always be supported */
-        result = SDL_SetRelativeMouseMode(SDL_FALSE);
-        SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)");
-        SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result);
-        currentState = SDL_GetRelativeMouseMode();
-        SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()");
+        result = SDL_SetWindowRelativeMouseMode(window, SDL_FALSE);
+        SDLTest_AssertPass("Call to SDL_SetWindowRelativeMouseMode(window, FALSE)");
+        SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetWindowRelativeMouseMode, expected: 0, got: %i", result);
+        currentState = SDL_GetWindowRelativeMouseMode(window);
+        SDLTest_AssertPass("Call to SDL_GetWindowRelativeMouseMode(window)");
         SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState);
     }
 
     /* Repeat twice to check D->E->E transition */
     for (i = 0; i < 2; i++) {
         /* Enable - may not be supported */
-        result = SDL_SetRelativeMouseMode(SDL_TRUE);
-        SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(TRUE)");
+        result = SDL_SetWindowRelativeMouseMode(window, SDL_TRUE);
+        SDLTest_AssertPass("Call to SDL_SetWindowRelativeMouseMode(window, TRUE)");
         if (result != -1) {
-            SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result);
-            currentState = SDL_GetRelativeMouseMode();
-            SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()");
+            SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetWindowRelativeMouseMode, expected: 0, got: %i", result);
+            currentState = SDL_GetWindowRelativeMouseMode(window);
+            SDLTest_AssertPass("Call to SDL_GetWindowRelativeMouseMode(window)");
             SDLTest_AssertCheck(currentState == SDL_TRUE, "Validate current state is TRUE, got: %i", currentState);
         }
     }
 
     /* Disable to check E->D transition */
-    result = SDL_SetRelativeMouseMode(SDL_FALSE);
-    SDLTest_AssertPass("Call to SDL_SetRelativeMouseMode(FALSE)");
-    SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetRelativeMouseMode, expected: 0, got: %i", result);
-    currentState = SDL_GetRelativeMouseMode();
-    SDLTest_AssertPass("Call to SDL_GetRelativeMouseMode()");
+    result = SDL_SetWindowRelativeMouseMode(window, SDL_FALSE);
+    SDLTest_AssertPass("Call to SDL_SetWindowRelativeMouseMode(window, FALSE)");
+    SDLTest_AssertCheck(result == 0, "Validate result value from SDL_SetWindowRelativeMouseMode, expected: 0, got: %i", result);
+    currentState = SDL_GetWindowRelativeMouseMode(window);
+    SDLTest_AssertPass("Call to SDL_GetWindowRelativeMouseMode(window)");
     SDLTest_AssertCheck(currentState == SDL_FALSE, "Validate current state is FALSE, got: %i", currentState);
 
     /* Revert to original state - ignore result */
-    result = SDL_SetRelativeMouseMode(initialState);
+    result = SDL_SetWindowRelativeMouseMode(window, initialState);
 
-    return TEST_COMPLETED;
-}
-
-#define MOUSE_TESTWINDOW_WIDTH  320
-#define MOUSE_TESTWINDOW_HEIGHT 200
-
-/**
- * Creates a test window
- */
-static SDL_Window *createMouseSuiteTestWindow(void)
-{
-    int width = MOUSE_TESTWINDOW_WIDTH, height = MOUSE_TESTWINDOW_HEIGHT;
-    SDL_Window *window;
-    window = SDL_CreateWindow("mousecreateMouseSuiteTestWindow", width, height, 0);
-    SDLTest_AssertPass("SDL_CreateWindow()");
-    SDLTest_AssertCheck(window != NULL, "Check SDL_CreateWindow result");
-    return window;
-}
+    /* Clean up test window */
+    destroyMouseSuiteTestWindow(window);
 
-/**
- * Destroy test window
- */
-static void destroyMouseSuiteTestWindow(SDL_Window *window)
-{
-    if (window) {
-        SDL_DestroyWindow(window);
-        window = NULL;
-        SDLTest_AssertPass("SDL_DestroyWindow()");
-    }
+    return TEST_COMPLETED;
 }
 
 /**
@@ -598,58 +608,69 @@ static int mouse_getGlobalMouseState(void *arg)
 /* ================= Test References ================== */
 
 /* Mouse test cases */
-static const SDLTest_TestCaseReference mouseTest1 = {
+static const SDLTest_TestCaseReference mouseTestGetMouseState = {
     (SDLTest_TestCaseFp)mouse_getMouseState, "mouse_getMouseState", "Check call to SDL_GetMouseState", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest2 = {
+static const SDLTest_TestCaseReference mouseTestGetRelativeMouseState = {
     (SDLTest_TestCaseFp)mouse_getRelativeMouseState, "mouse_getRelativeMouseState", "Check call to SDL_GetRelativeMouseState", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest3 = {
+static const SDLTest_TestCaseReference mouseTestCreateFreeCursor = {
     (SDLTest_TestCaseFp)mouse_createFreeCursor, "mouse_createFreeCursor", "Check call to SDL_CreateCursor and SDL_DestroyCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest4 = {
+static const SDLTest_TestCaseReference mouseTestShowCursor = {
     (SDLTest_TestCaseFp)mouse_showCursor, "mouse_showCursor", "Check call to SDL_ShowCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest5 = {
+static const SDLTest_TestCaseReference mouseTestSetCursor = {
     (SDLTest_TestCaseFp)mouse_setCursor, "mouse_setCursor", "Check call to SDL_SetCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest6 = {
+static const SDLTest_TestCaseReference mouseTestGetCursor = {
     (SDLTest_TestCaseFp)mouse_getCursor, "mouse_getCursor", "Check call to SDL_GetCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest7 = {
+static const SDLTest_TestCaseReference mouseTestWarpMouseInWindow = {
     (SDLTest_TestCaseFp)mouse_warpMouseInWindow, "mouse_warpMouseInWindow", "Check call to SDL_WarpMouseInWindow", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest8 = {
-    (SDLTest_TestCaseFp)mouse_getMouseFocus, "mouse_getMouseFocus", "Check call to SDL_getMouseFocus", TEST_ENABLED
+static const SDLTest_TestCaseReference mouseTestGetMouseFocus = {
+    (SDLTest_TestCaseFp)mouse_getMouseFocus, "mouse_getMouseFocus", "Check call to SDL_GetMouseFocus", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest9 = {
+static const SDLTest_TestCaseReference mouseTestCreateFreeColorCursor = {
     (SDLTest_TestCaseFp)mouse_createFreeColorCursor, "mouse_createFreeColorCursor", "Check call to SDL_CreateColorCursor and SDL_DestroyCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest10 = {
-    (SDLTest_TestCaseFp)mouse_getSetRelativeMouseMode, "mouse_getSetRelativeMouseMode", "Check call to SDL_GetRelativeMouseMode and SDL_SetRelativeMouseMode", TEST_ENABLED
+static const SDLTest_TestCaseReference mouseTestGetSetRelativeMouseMode = {
+    (SDLTest_TestCaseFp)mouse_getSetRelativeMouseMode, "mouse_getSetRelativeMouseMode", "Check call to SDL_GetWindowRelativeMouseMode and SDL_SetWindowRelativeMouseMode", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest11 = {
-    (SDLTest_TestCaseFp)mouse_getDefaultCursor, "mouse_getDefaultCursor", "Check call to mouse_getDefaultCursor", TEST_ENABLED
+static const SDLTest_TestCaseReference mouseTestGetDefaultCursor = {
+    (SDLTest_TestCaseFp)mouse_getDefaultCursor, "mouse_getDefaultCursor", "Check call to SDL_GetDefaultCursor", TEST_ENABLED
 };
 
-static const SDLTest_TestCaseReference mouseTest12 = {
-    (SDLTest_TestCaseFp)mouse_getGlobalMouseState, "mouse_getGlobalMouseState", "Check call to mouse_getGlobalMouseState", TEST_ENABLED
+static const SDLTest_TestCaseReference mouseTestGetGlobalMouseState = {
+    (SDLTest_TestCaseFp)mouse_getGlobalMouseState, "mouse_getGlobalMouseState", "Check call to SDL_GetGlobalMouseState", TEST_ENABLED
 };
 
 /* Sequence of Mouse test cases */
 static const SDLTest_TestCaseReference *mouseTests[] = {
-    &mouseTest1, &mouseTest2, &mouseTest3, &mouseTest4, &mouseTest5, &mouseTest6,
-    &mouseTest7, &mouseTest8, &mouseTest9, &mouseTest10, &mouseTest11, &mouseTest12, NULL
+    &mouseTestGetMouseState,
+    &mouseTestGetRelativeMouseState,
+    &mouseTestCreateFreeCursor,
+    &mouseTestShowCursor,
+    &mouseTestSetCursor,
+    &mouseTestGetCursor,
+    &mouseTestWarpMouseInWindow,
+    &mouseTestGetMouseFocus,
+    &mouseTestCreateFreeColorCursor,
+    &mouseTestGetSetRelativeMouseMode,
+    &mouseTestGetDefaultCursor,
+    &mouseTestGetGlobalMouseState,
+    NULL
 };
 
 /* Mouse test suite (global) */
diff --git a/test/testmanymouse.c b/test/testmanymouse.c
index 03c672ce3e385..6ee9a7d96d801 100644
--- a/test/testmanymouse.c
+++ b/test/testmanymouse.c
@@ -538,10 +538,10 @@ int main(int argc, char *argv[])
 
         SDL_SetPointerProperty(SDL_GetRendererProperties(renderer), PROP_ARROW_CURSOR_TEXTURE, cursor_arrow);
         SDL_SetPointerProperty(SDL_GetRendererProperties(renderer), PROP_CROSS_CURSOR_TEXTURE, cursor_cross);
-    }
 
-    /* We only get mouse motion for distinct devices when relative mode is enabled */
-    SDL_SetRelativeMouseMode(SDL_TRUE);
+        /* We only get mouse motion for distinct devices when relative mode is enabled */
+        SDL_SetWindowRelativeMouseMode(state->windows[i], SDL_TRUE);
+    }
 
     /* Main render loop */
     done = 0;
diff --git a/test/testrelative.c b/test/testrelative.c
index 1671217dd348a..12e21a9323ba9 100644
--- a/test/testrelative.c
+++ b/test/testrelative.c
@@ -32,11 +32,7 @@ static void DrawRects(SDL_Renderer *renderer)
     SDL_RenderFillRect(renderer, &rect);
 
     SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
-    if (SDL_GetRelativeMouseMode()) {
-        SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Enabled");
-    } else {
-        SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Disabled");
-    }
+    SDLTest_DrawString(renderer, 0.f, 0.f, "Relative Mode: Enabled");
 }
 
 static void CenterMouse()
@@ -196,8 +192,10 @@ int main(int argc, char *argv[])
      */
     if (warp) {
         SDL_HideCursor();
-    } else if (SDL_SetRelativeMouseMode(SDL_TRUE) < 0) {
-        return 3; /* Relative mode failed, just exit. */
+    } else {
+        for (i = 0; i < state->num_windows; ++i) {
+            SDL_SetWindowRelativeMouseMode(state->windows[i], SDL_TRUE);
+        }
     }
 
     rect.x = DEFAULT_WINDOW_WIDTH / 2;