diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 0af28e3cfd5..a8bc8e2185a 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -1700,7 +1700,11 @@ void QWidgetPrivate::deleteSysExtra() void QWidgetPrivate::deleteTLSysExtra() { + Q_Q(QWidget); if (extra && extra->topextra) { + if (extra->hasWindowContainer) + QWindowContainer::toplevelAboutToBeDestroyed(q); + delete extra->topextra->window; extra->topextra->window = nullptr; } diff --git a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp index 52aaf094b47..e7d65db550c 100644 --- a/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp +++ b/tests/auto/widgets/kernel/qwindowcontainer/tst_qwindowcontainer.cpp @@ -62,6 +62,7 @@ private slots: void testPlatformSurfaceEvent(); void embedWidgetWindow(); void testFocus(); + void parentDestroyed(); void cleanup(); private: @@ -530,6 +531,36 @@ void tst_QWindowContainer::testFocus() QVERIFY(!lineEdit->hasFocus()); } +class CreateDestroyWidget : public QWidget +{ +public: + void create() { QWidget::create(); } + void destroy() { QWidget::destroy(); } +}; + +void tst_QWindowContainer::parentDestroyed() +{ + CreateDestroyWidget topLevel; + topLevel.setAttribute(Qt::WA_NativeWindow); + QVERIFY(topLevel.windowHandle()); + + QPointer window = new QWindow; + QWidget *container = QWidget::createWindowContainer(window.get()); + container->setParent(&topLevel); + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QCOMPARE(window->parent(), topLevel.windowHandle()); + + // Destroying the widget should not wipe out the contained QWindow + topLevel.destroy(); + QVERIFY(window); + + // Recreating the top level should once again reparent the contained window + topLevel.show(); + QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); + QCOMPARE(window->parent(), topLevel.windowHandle()); +} + QTEST_MAIN(tst_QWindowContainer) #include "tst_qwindowcontainer.moc"