From e7bb3a8bd345d9ff73cd214a64d1ace6b002f0a3 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Mon, 27 Sep 2021 12:27:55 +0200 Subject: [PATCH] Fix crash if receiver destroys itself in closeEvent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We allow QWidget::closeEvent to "delete this", and verify that this works in the tst_QWidget::testDeletionInEventHandlers test function. Sadly, that test didn't reliably catch the issue introduced in 28b14b966fe8535d7a81914b70759546b694e31b, where the receiver is accessed after the delivery of QEvent::Close. Handle the QWindow event delivery explicitly so that we don't need to access the receiver after the event has been delivered. There's nothing we can do to make the test fail more reliably in CI. A QWindow deleting itself in closeEvent will still crash; perhaps we don't want to allow that anyway. Change-Id: I2b5c2d11ded71c4f22ae9862cdc459e1f93b3374 Reviewed-by: Tor Arne Vestbø --- src/widgets/kernel/qapplication.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 74868077b3..0bc0647835 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2746,7 +2746,12 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } bool res = false; - if (!receiver->isWidgetType()) { + if (receiver->isWindowType()) { + res = d->notify_helper(receiver, e); + // We don't call QGuiApplication::notify here, so we need to duplicate the logic + if (res && e->type() == QEvent::Close) + d->maybeQuitOnLastWindowClosed(static_cast(receiver)); + } else if (!receiver->isWidgetType()) { res = d->notify_helper(receiver, e); } else switch (e->type()) { case QEvent::ShortcutOverride: @@ -3342,10 +3347,6 @@ bool QApplication::notify(QObject *receiver, QEvent *e) break; } - // We don't call QGuiApplication::notify here, so we need to duplicate the logic - if (e->type() == QEvent::Close && receiver->isWindowType() && res) - d->maybeQuitOnLastWindowClosed(static_cast(receiver)); - return res; }