From ec09900997e9b92206938ca5f9fe2e356440e513 Mon Sep 17 00:00:00 2001 From: Doris Verria Date: Wed, 13 Oct 2021 13:35:10 +0200 Subject: [PATCH] Call QWidget close handling in QWidget::close for non-toplevel native widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since commit 7ba75d0 we close the QWindow in QWidget::close for native widgets and trigger the closeEvent in QWidgetWindow. However, if the widget's window handle is not a top level window, QWindow::close() will not close the window, failing in this way to deliver the closeEvent and call the close handling in QWidgetPrivate::handleClose. To fix, call handleClose() from QWidget::close for such widgets. Task-number: QTBUG-74606 Pick-to: 6.2 Change-Id: Ied342eced3340aaf19b5443762935b1a5fc5c27b Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qwindow.cpp | 2 +- src/widgets/kernel/qwidget.cpp | 6 ++++-- .../widgets/kernel/qwidget/tst_qwidget.cpp | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 590c56eab8..61756a3834 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2258,7 +2258,7 @@ bool QWindow::close() Q_D(QWindow); // Do not close non top level windows - if (parent()) + if (!isTopLevel()) return false; if (!d->platformWindow) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 5c42a5da23..2534a7aeba 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -8466,8 +8466,10 @@ bool QWidgetPrivate::close() // Close native widgets via QWindow::close() in order to run QWindow // close code. The QWidget-specific close code in handleClose() will // in this case be called from the Close event handler in QWidgetWindow. - if (QWindow *widgetWindow = windowHandle()) - return widgetWindow->close(); + if (QWindow *widgetWindow = windowHandle()) { + if (widgetWindow->isTopLevel()) + return widgetWindow->close(); + } return handleClose(QWidgetPrivate::CloseWithEvent); } diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index a7c3f86687..00350c3946 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -243,6 +243,7 @@ private slots: void winIdChangeEvent(); void persistentWinId(); void showNativeChild(); + void closeAndShowNativeChild(); void closeAndShowWithNativeChild(); void transientParent(); void qobject_castInDestroyedSlot(); @@ -4776,6 +4777,25 @@ void tst_QWidget::showNativeChild() QVERIFY(QTest::qWaitForWindowExposed(&topLevel)); } +void tst_QWidget::closeAndShowNativeChild() +{ + QWidget topLevel; + QWidget *nativeChild = new QWidget; + nativeChild->winId(); + nativeChild->setFixedSize(200, 200); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(nativeChild); + topLevel.setLayout(layout); + + topLevel.show(); + QVERIFY(!nativeChild->isHidden()); + nativeChild->close(); + QVERIFY(nativeChild->isHidden()); + nativeChild->show(); + QVERIFY(!nativeChild->isHidden()); +} + void tst_QWidget::closeAndShowWithNativeChild() { bool dontCreateNativeWidgetSiblings = QApplication::testAttribute(Qt::AA_DontCreateNativeWidgetSiblings);