SDL: Retain mouse focus as long as we're getting mouse events

From 911e53dece1ec7afe1a2d63b38f2023801d9be06 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 21 Feb 2025 15:35:28 -0800
Subject: [PATCH] Retain mouse focus as long as we're getting mouse events

Fixes https://github.com/libsdl-org/SDL/issues/12218
Fixes https://github.com/libsdl-org/SDL/issues/12323
---
 src/video/cocoa/SDL_cocoamouse.m | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/video/cocoa/SDL_cocoamouse.m b/src/video/cocoa/SDL_cocoamouse.m
index 77ebf109d02fa..530ca0c874eea 100644
--- a/src/video/cocoa/SDL_cocoamouse.m
+++ b/src/video/cocoa/SDL_cocoamouse.m
@@ -447,13 +447,23 @@ void Cocoa_HandleMouseEvent(SDL_VideoDevice *_this, NSEvent *event)
     float deltaX, deltaY;
     bool seenWarp;
 
-    switch ([event type]) {
-    case NSEventTypeMouseEntered:
+    // All events except NSEventTypeMouseExited can only happen if the window
+    // has mouse focus, so we'll always set the focus even if we happen to miss
+    // NSEventTypeMouseEntered, which apparently happens if the window is
+    // created under the mouse on macOS 12.7
+    NSEventType event_type = [event type];
+    if (event_type == NSEventTypeMouseExited) {
+        Cocoa_MouseFocus = NULL;
+    } else {
         Cocoa_MouseFocus = [event window];
-        return;
+    }
+
+    switch (event_type) {
+    case NSEventTypeMouseEntered:
     case NSEventTypeMouseExited:
-        Cocoa_MouseFocus = NULL;
+        // Focus is handled above
         return;
+
     case NSEventTypeMouseMoved:
     case NSEventTypeLeftMouseDragged:
     case NSEventTypeRightMouseDragged: