Browse Source

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)
Ryan C. Gordon 2 months ago
parent
commit
cb662b6730
1 changed files with 17 additions and 0 deletions
  1. 17 0
      src/video/cocoa/SDL_cocoawindow.m

+ 17 - 0
src/video/cocoa/SDL_cocoawindow.m

@@ -2022,6 +2022,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
 @interface SDL3View : NSView
 @interface SDL3View : NSView
 {
 {
     SDL_Window *_sdlWindow;
     SDL_Window *_sdlWindow;
+    NSTrackingArea *_trackingArea;   // only used on macOS <= 11.0
 }
 }
 
 
 - (void)setSDLWindow:(SDL_Window *)window;
 - (void)setSDLWindow:(SDL_Window *)window;
@@ -2033,6 +2034,7 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
 - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent;
 - (BOOL)wantsUpdateLayer;
 - (BOOL)wantsUpdateLayer;
 - (void)updateLayer;
 - (void)updateLayer;
+- (void)updateTrackingAreas;
 @end
 @end
 
 
 @implementation SDL3View
 @implementation SDL3View
@@ -2113,6 +2115,21 @@ static void Cocoa_SendMouseButtonClicks(SDL_Mouse *mouse, NSEvent *theEvent, SDL
     }
     }
 }
 }
 
 
+- (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
 @end
 
 
 static void Cocoa_UpdateMouseFocus()
 static void Cocoa_UpdateMouseFocus()