diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index d86af94a9c3..99c54b9d987 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -51,6 +51,17 @@ public: widget->setAttribute(Qt::WA_WState_ExplicitShowHide, wasExplicitShowHide); widget->setAttribute(Qt::WA_WState_Hidden, wasHidden); } + + // The call to QWidgetPrivate::setVisible() above will normally + // recurse back into QWidgetWindow::setNativeWindowVisibility() + // to update the QWindow state, but during QWidget::destroy() + // this is not the case, as Qt::WA_WState_Created has been + // unset by the time we check if we should call hide_helper(). + // We don't want to change the QWidget logic, as that has + // other side effects, so as a targeted fix we sync up the + // visibility here if needed. + if (q->isVisible() != visible) + QWindowPrivate::setVisible(visible); } else { QWindowPrivate::setVisible(visible); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 549206875c7..5d19aa3c757 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -433,6 +433,8 @@ private slots: void showFullscreenAndroid(); #endif + void setVisibleDuringDestruction(); + private: const QString m_platform; QSize m_testWidgetSize; @@ -13403,5 +13405,31 @@ void tst_QWidget::showFullscreenAndroid() } #endif // Q_OS_ANDROID +void tst_QWidget::setVisibleDuringDestruction() +{ + CreateDestroyWidget widget; + widget.create(); + QVERIFY(widget.windowHandle()); + + QSignalSpy signalSpy(widget.windowHandle(), &QWindow::visibleChanged); + EventSpy showEventSpy(widget.windowHandle(), QEvent::Show); + widget.show(); + QTRY_COMPARE(showEventSpy.count(), 1); + QTRY_COMPARE(signalSpy.count(), 1); + + EventSpy hideEventSpy(widget.windowHandle(), QEvent::Hide); + widget.hide(); + QTRY_COMPARE(hideEventSpy.count(), 1); + QTRY_COMPARE(signalSpy.count(), 2); + + widget.show(); + QTRY_COMPARE(showEventSpy.count(), 2); + QTRY_COMPARE(signalSpy.count(), 3); + + widget.destroy(); + QTRY_COMPARE(hideEventSpy.count(), 2); + QTRY_COMPARE(signalSpy.count(), 4); +} + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc"