From 945c8bf54dcb14a787966988ebf40cededd321cc Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 1 Nov 2024 14:45:28 +0100 Subject: [PATCH] Cocoa: Use sheetParent to close sheet instead of transientParent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the window that the sheet (as created for a modal dialog) lives in has already been destroyed by the time the sheet is hidden, then we used to trip an assertion. Instead, always use the sheetParent, which is still alive. Add a test case that asserts without the fix. Fixes: QTBUG-128302 Change-Id: I4c399b73e2552bab79358c5505f403efa8e4f80b Reviewed-by: Tor Arne Vestbø (cherry picked from commit 332f49f2d8c5675bab8bde6acfb377d567961d4a) Reviewed-by: Qt Cherry-pick Bot --- src/plugins/platforms/cocoa/qcocoawindow.mm | 10 +++------- .../widgets/dialogs/qdialog/tst_qdialog.cpp | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index e5c643751f6..85f7bbb5c1f 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -472,14 +472,10 @@ void QCocoaWindow::setVisible(bool visible) } else { // Window not visible, hide it if (isContentView()) { - if (eventDispatcher()->hasModalSession()) { + if (eventDispatcher()->hasModalSession()) eventDispatcher()->endModalSession(window()); - } else { - if ([m_view.window isSheet]) { - Q_ASSERT_X(parentCocoaWindow, "QCocoaWindow", "Window modal dialog has no transient parent."); - [parentCocoaWindow->nativeWindow() endSheet:m_view.window]; - } - } + else if ([m_view.window isSheet]) + [m_view.window.sheetParent endSheet:m_view.window]; // Note: We do not guard the order out by checking NSWindow.visible, as AppKit will // in some cases, such as when hiding the application, order out and make a window diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index 13f971f5f05..e970ea2810a 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -66,6 +66,8 @@ private slots: void deleteOnDone(); void quitOnDone(); void focusWidgetAfterOpen(); + + void closeParentOfVisibleDialog(); }; // Testing get/set functions @@ -768,5 +770,23 @@ void tst_QDialog::focusWidgetAfterOpen() QCOMPARE(dialog.focusWidget(), static_cast(pb2)); } +void tst_QDialog::closeParentOfVisibleDialog() +{ + QWidget widget; + widget.show(); + + // On macOS, this dialog becomes a sheet and triggered an assert when + // the widget it lived in was already gone by the time the sheet + // got closed. QTBUG-128302 + QDialog dialog(&widget); + dialog.open(); + + QTimer::singleShot(0, &widget, [&]{ + widget.close(); + }); + + QTRY_VERIFY(!widget.isVisible()); +} + QTEST_MAIN(tst_QDialog) #include "tst_qdialog.moc"