From 1554c778f4445e73b1ff4761126fe4813b6b6e3e Mon Sep 17 00:00:00 2001 From: Brian Smith Date: Sat, 30 Nov 2024 17:53:28 -0600 Subject: [PATCH] No Issue - Make nsCocoaWindow hold a death grip on its native window until its destructor. https://bugzilla.mozilla.org/show_bug.cgi?id=1880582 --- widget/cocoa/nsCocoaWindow.h | 7 ++++++- widget/cocoa/nsCocoaWindow.mm | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 1913696b8c..9b3fa21886 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -384,8 +384,13 @@ protected: nsIWidget* mParent; // if we're a popup, this is our parent [WEAK] nsIWidget* mAncestorLink; // link to traverse ancestors [WEAK] BaseWindow* mWindow; // our cocoa window [STRONG] + BaseWindow* mClosedRetainedWindow; // a second strong reference to our + // window upon closing it, held through our destructor. This is useful + // to ensure that macOS run loops which reference the window will still + // have something to point to even if they don't use proper retain and + // release patterns. WindowDelegate* mDelegate; // our delegate for processing window msgs [STRONG] - RefPtr mMenuBar; + RefPtr mMenuBar; NSWindow* mSheetWindowParent; // if this is a sheet, this is the NSWindow it's attached to nsChildView* mPopupContentView; // if this is a popup, this is its content widget // if this is a toplevel window, and there is any ongoing fullscreen diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 870e5f2647..40b357a056 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -110,6 +110,7 @@ nsCocoaWindow::nsCocoaWindow() : mParent(nullptr) , mAncestorLink(nullptr) , mWindow(nil) +, mClosedRetainedWindow(nil) , mDelegate(nil) , mSheetWindowParent(nil) , mPopupContentView(nil) @@ -148,6 +149,12 @@ void nsCocoaWindow::DestroyNativeWindow() // We want to unhook the delegate here because we don't want events // sent to it after this object has been destroyed. [mWindow setDelegate:nil]; + // Closing the window will also release it. Our second reference will + // keep it alive through our destructor. Release any reference we might + // have from an earlier call to DestroyNativeWindow, then create a new + // one. + [mClosedRetainedWindow autorelease]; + mClosedRetainedWindow = [mWindow retain]; [mWindow close]; mWindow = nil; [mDelegate autorelease]; @@ -182,6 +189,8 @@ nsCocoaWindow::~nsCocoaWindow() DestroyNativeWindow(); } + [mClosedRetainedWindow release]; + NS_IF_RELEASE(mPopupContentView); // Deal with the possiblity that we're being destroyed while running modal.