From e7370d0583ea8a50b0d5c15bb2b1afee2efc6a7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Tue, 5 Jan 2021 12:54:03 +0100 Subject: [PATCH] Skip already closing widgets when checking whether application can quit QApplication tries to close all windows on quit using closeAllWindows, but closeAllWindows skips windows that are already closing. This can happen when calling quit() from a close event for example. QApplication then tries to verify that all windows have been closed, and that logic should skip the same kind of windows as closeAllWindows does. The fact that these two logics diverge was identified earlier in 5af73cd9db52, but aligning them required further work. As that commit notes, the right fix to align them is building on top of tryCloseAllWidgetWindows(), which already returns true/false based on whether it could close all windows or not. But, unlike the existing logic in QApplication::event(), it doesn't skip Popups or Dialogs, so that discrepancy needs further research. Pick-to: 6.0 Fixes: QTBUG-89580 Change-Id: I87bff56f2eb8a539f1c859c957f5f239dc1eb93d Reviewed-by: Andy Shaw Reviewed-by: Kai Koehne Reviewed-by: Volker Hilsheimer --- src/widgets/kernel/qapplication.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 3eb7efd443..dfd7402e0d 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -1660,8 +1660,14 @@ bool QApplication::event(QEvent *e) { Q_D(QApplication); if (e->type() == QEvent::Quit) { + // FIXME: This logic first tries to close all windows, and then + // checks whether it was successful, but the conditions used in + // closeAllWindows() differ from the verification logic below. + // We should build on the logic in tryCloseAllWidgetWindows(). closeAllWindows(); for (auto *w : topLevelWidgets()) { + if (w->data->is_closing) + continue; if (w->isVisible() && !(w->windowType() == Qt::Desktop) && !(w->windowType() == Qt::Popup) && (!(w->windowType() == Qt::Dialog) || !w->parentWidget()) && !w->testAttribute(Qt::WA_DontShowOnScreen)) { e->ignore();