SDL: Leave mouse relative mode when losing focus

From 49610fd1e8d0c2824ab2bd8a42ebcf455179294a Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 23 Dec 2024 15:22:50 -0800
Subject: [PATCH] Leave mouse relative mode when losing focus

Fixes https://github.com/libsdl-org/SDL/issues/7892
---
 src/events/SDL_keyboard.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/events/SDL_keyboard.c b/src/events/SDL_keyboard.c
index 3a96d5ab21af4..a7f5c08451d11 100644
--- a/src/events/SDL_keyboard.c
+++ b/src/events/SDL_keyboard.c
@@ -322,6 +322,7 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
 {
     SDL_VideoDevice *video = SDL_GetVideoDevice();
     SDL_Keyboard *keyboard = &SDL_keyboard;
+    SDL_Mouse *mouse = SDL_GetMouse();
 
     if (window) {
         if (!SDL_ObjectValid(window, SDL_OBJECT_TYPE_WINDOW) || window->is_destroying) {
@@ -332,6 +333,19 @@ bool SDL_SetKeyboardFocus(SDL_Window *window)
     if (keyboard->focus && !window) {
         // We won't get anymore keyboard messages, so reset keyboard state
         SDL_ResetKeyboard();
+
+        // Also leave mouse relative mode
+        if (mouse->relative_mode) {
+            SDL_SetRelativeMouseMode(false);
+
+            SDL_Window *focus = keyboard->focus;
+            if ((focus->flags & SDL_WINDOW_MINIMIZED) != 0) {
+                // We can't warp the mouse within minimized windows, so manually restore the position
+                float x = focus->x + mouse->x;
+                float y = focus->y + mouse->y;
+                SDL_WarpMouseGlobal(x, y);
+            }
+        }
     }
 
     // See if the current window has lost focus