SDL: cocoa: add explicit tracking areas to the window. (cb662)

From cb662b6730abba43b57c8f1490412f9435643de4 Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Sat, 31 May 2025 14:40:12 -0400
Subject: [PATCH] cocoa: add explicit tracking areas to the window.

This makes sure we get reliable mouse enter/exit events from the system on
older macOS releases.

Newer releases don't have this problem--my assumption is that Cocoa has a
more aggressive default tracking area installed for some newer UI feature.

For 3.2.16, we'll use the explicit tracking area on older macOSes only, but
I'll remove that check in revision control for newer OSes and see what
happens.

Fixes #12725.

(cherry picked from commit f61d956a0445640ecd381921c2ca1eb63a42017e)
---
 src/video/cocoa/SDL_cocoawindow.m | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 3e9642a3c01e1..7be564af0fbf5 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -2022,6 +2022,7 @@ - (void)tabletPoint:(NSEvent *)theEvent
 @interface SDL3View : NSView
 {
     SDL_Window *_sdlWindow;
+    NSTrackingArea *_trackingArea;   // only used on macOS <= 11.0
 }
 
 - (void)setSDLWindow:(SDL_Window *)window;
@@ -2033,6 +2034,7 @@ - (void)drawRect:(NSRect)dirtyRect;
 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
 - (BOOL)wantsUpdateLayer;
 - (void)updateLayer;
+- (void)updateTrackingAreas;
 @end
 
 @implementation SDL3View
@@ -2113,6 +2115,21 @@ - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent
     }
 }
 
+- (void)updateTrackingAreas
+{
+    [super updateTrackingAreas];
+
+    if (@available(macOS 12.0, *)) {
+        // we (currently) use the tracking areas as a workaround for older macOSes, but we might be safe everywhere...
+    } else {
+        SDL_CocoaWindowData *windata = (__bridge SDL_CocoaWindowData *)_sdlWindow->internal;
+        if (_trackingArea) {
+            [self removeTrackingArea:_trackingArea];
+        }
+        _trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:NSTrackingMouseEnteredAndExited|NSTrackingActiveAlways owner:windata.listener userInfo:nil];
+        [self addTrackingArea:_trackingArea];
+    }
+}
 @end
 
 static void Cocoa_UpdateMouseFocus()