diff options
author | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-06-09 11:32:44 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2021-06-09 16:13:54 +0200 |
commit | 8a4e274dcf836f58c7417c11737bdded50a84dbd (patch) | |
tree | e0a174d1832be767ca71fe80326bd0a2519bb383 /src/plugins | |
parent | 27952957d783034f7eba1133a6c26a351501099c (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.mm | 9 |
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()); } |