diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 40e9b9723a..d6f9fad070 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1083,6 +1083,11 @@ Qt::WindowState QWindow::windowState() const void QWindow::setTransientParent(QWindow *parent) { Q_D(QWindow); + if (parent && !parent->isTopLevel()) { + qWarning() << Q_FUNC_INFO << parent << "must be a top level window."; + return; + } + d->transientParent = parent; QGuiApplicationPrivate::updateBlockedStatus(this); diff --git a/src/widgets/kernel/qwidget_qpa.cpp b/src/widgets/kernel/qwidget_qpa.cpp index 70d274796b..5a4bd33672 100644 --- a/src/widgets/kernel/qwidget_qpa.cpp +++ b/src/widgets/kernel/qwidget_qpa.cpp @@ -138,7 +138,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO if (QWidget *nativeParent = q->nativeParentWidget()) { if (nativeParent->windowHandle()) { if (flags & Qt::Window) { - win->setTransientParent(nativeParent->windowHandle()); + win->setTransientParent(nativeParent->window()->windowHandle()); win->setParent(0); } else { win->setTransientParent(0); diff --git a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp index c3d2c4a9e7..cd9ff28891 100644 --- a/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp +++ b/tests/auto/widgets/dialogs/qdialog/tst_qdialog.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,8 @@ private slots: void setVisible(); void reject(); void snapToDefaultButton(); + void transientParent_data(); + void transientParent(); private: QDialog *testWidget; @@ -584,5 +587,34 @@ void tst_QDialog::snapToDefaultButton() #endif // !QT_NO_CURSOR } +void tst_QDialog::transientParent_data() +{ + QTest::addColumn("nativewidgets"); + QTest::newRow("Non-native") << false; + QTest::newRow("Native") << true; +} + +void tst_QDialog::transientParent() +{ + QFETCH(bool, nativewidgets); + testWidget->hide(); + QWidget topLevel; + topLevel.resize(200, 200); + topLevel.move(QGuiApplication::primaryScreen()->availableGeometry().center() - QPoint(100, 100)); + QVBoxLayout *layout = new QVBoxLayout(&topLevel); + QWidget *innerWidget = new QWidget(&topLevel); + layout->addWidget(innerWidget); + if (nativewidgets) + innerWidget->winId(); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QDialog dialog(innerWidget); + dialog.show(); + QVERIFY(QTest::qWaitForWindowExposed(&dialog)); + // Transient parent should always be the top level, also when using + // native child widgets. + QCOMPARE(dialog.windowHandle()->transientParent(), topLevel.windowHandle()); +} + QTEST_MAIN(tst_QDialog) #include "tst_qdialog.moc"