From acb86da793c603991da63ba6ab7c6684518d0cd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 13 Oct 2021 15:36:08 +0200 Subject: Prevent recursive calls to QWindow::close QWidget will call close() in its destructor, which we might end up in if a user deletes the widget in the closeEvent. Pick-to: 6.2 Change-Id: I39684aec0ca130033dad60f2bbf823364a5edcec Reviewed-by: Volker Hilsheimer --- src/gui/kernel/qwindow.cpp | 2 ++ tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 26ad97bc86..561682f65d 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -2257,6 +2257,8 @@ void QWindow::showNormal() bool QWindow::close() { Q_D(QWindow); + if (d->inClose) + return true; // Do not close non top level windows if (!isTopLevel()) diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp index 67ea378c66..9e8e1eac11 100644 --- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp @@ -1602,6 +1602,23 @@ void tst_QWindow::sizes() QCOMPARE(maximumHeightSpy.count(), 1); } +class CloseOnCloseEventWindow : public QWindow +{ +public: + inline static int closeEvents; + CloseOnCloseEventWindow() { closeEvents = 0; } + +protected: + void closeEvent(QCloseEvent *e) override + { + if (++closeEvents > 1) + return; + + close(); + e->accept(); + } +}; + void tst_QWindow::close() { { @@ -1683,6 +1700,16 @@ void tst_QWindow::close() QVERIFY(c.handle()); } } + + { + // A QWidget will call close() from the destructor, and + // we allow widgets deleting itself in the closeEvent, + // so we need to guard against close being called recursively. + CloseOnCloseEventWindow w; + w.create(); + w.close(); + QCOMPARE(CloseOnCloseEventWindow::closeEvents, 1); + } } void tst_QWindow::activateAndClose() -- cgit v1.2.3