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"