summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-06-09 11:32:44 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2021-06-09 16:13:54 +0200
commit8a4e274dcf836f58c7417c11737bdded50a84dbd (patch)
treee0a174d1832be767ca71fe80326bd0a2519bb383 /src/plugins
parent27952957d783034f7eba1133a6c26a351501099c (diff)
macOS: Keep NSWindow alive after handling windowShouldClose callback
Option-clicking the close-button on a window in macOS is a request to batch-close all the windows. When this happens we get an event in through the window that was clicked, which in turn results in AppKit calling windowShouldClose: for each window. We respond to that by explicitly closing each window (instead of just responding YES or NO), which results in the window being released and deallocated. This causes a crash when AppKit then follows up by closing each window after we responded YES to windowShouldClose. We work around this by keeping the window alive in the closest auto release pool, which is typically at the level of the runloop. This ensures that the window is alive for the duration of the logic that AppKit has for batch-closing windows. Fixes: QTBUG-92232 Pick-to: 6.2 6.1 5.15 Change-Id: I68b6138eb8325af0576b438ffa011137fec27926 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm9
1 files changed, 9 insertions, 0 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index 28210c83ed..a7700a9234 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -1305,10 +1305,19 @@ void QCocoaWindow::windowWillClose()
bool QCocoaWindow::windowShouldClose()
{
qCDebug(lcQpaWindow) << "QCocoaWindow::windowShouldClose" << window();
+
// This callback should technically only determine if the window
// should (be allowed to) close, but since our QPA API to determine
// that also involves actually closing the window we do both at the
// same time, instead of doing the latter in windowWillClose.
+
+ // If the window is closed, we will release and deallocate the NSWindow.
+ // But frames higher up in the stack might still expect the window to
+ // be alive, since the windowShouldClose: callback is technically only
+ // supposed to answer YES or NO. To ensure the window is still alive
+ // we put an autorelease in the closest pool (typically the runloop).
+ [[m_view.window retain] autorelease];
+
return QWindowSystemInterface::handleCloseEvent<QWindowSystemInterface::SynchronousDelivery>(window());
}