macOS: Fix reference counts of internal window data. Fixes crashes when destroying or recreating a window (#5664).
diff --git a/src/video/cocoa/SDL_cocoawindow.h b/src/video/cocoa/SDL_cocoawindow.h
index 0fd29ce..6132455 100644
--- a/src/video/cocoa/SDL_cocoawindow.h
+++ b/src/video/cocoa/SDL_cocoawindow.h
@@ -40,7 +40,10 @@ typedef enum
} PendingWindowOperation;
@interface Cocoa_WindowListener : NSResponder <NSWindowDelegate> {
- SDL_WindowData *_data;
+ /* SDL_WindowData owns this Listener and has a strong reference to it.
+ * To avoid reference cycles, we could have either a weak or an
+ * unretained ref to the WindowData. */
+ __weak SDL_WindowData *_data;
BOOL observingVisible;
BOOL wasCtrlLeft;
BOOL wasVisible;
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 7943025..44e9144 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -1653,6 +1653,12 @@ SetupWindowData(_THIS, SDL_Window * window, NSWindow *nswindow, NSView *nsview,
SDL_SetKeyboardFocus(data.window);
}
+ /* SDL_WindowData will be holding a strong reference to the NSWindow, and
+ * it will also call [NSWindow close] in DestroyWindow before releasing the
+ * NSWindow, so the extra release provided by releasedWhenClosed isn't
+ * necessary. */
+ nswindow.releasedWhenClosed = NO;
+
/* Prevents the window's "window device" from being destroyed when it is
* hidden. See http://www.mikeash.com/pyblog/nsopenglcontext-and-one-shot.html
*/