diff options
author | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-05-20 08:52:16 (GMT) |
---|---|---|
committer | Bradley T. Hughes <bradley.hughes@nokia.com> | 2010-05-20 10:01:51 (GMT) |
commit | 16f44ee07db46ad362a464afc2c6e6567c933870 (patch) | |
tree | 9343457968535bd69b96a9e61568b725cd9ff576 | |
parent | a41534cbabd0aee90c38b9a1a133835863a7f54b (diff) | |
download | Qt-16f44ee07db46ad362a464afc2c6e6567c933870.zip Qt-16f44ee07db46ad362a464afc2c6e6567c933870.tar.gz Qt-16f44ee07db46ad362a464afc2c6e6567c933870.tar.bz2 |
QApplication::closeAllWindows() should ignore windows being closed
It is very common to display a dialog in response to a close event.
Closing the window again will result in QWidget::close() returning true.
This confuses QApplication::closeAllWindows(), since the window is still
visible even though it was closed (or is closing). Solve this by
ignoring windows that have the is_closing flag set in their widget data.
Task-number: QTBUG-7635
Reviewed-by: Denis Dzyubenko
-rw-r--r-- | src/gui/kernel/qapplication.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qapplication/tst_qapplication.cpp | 78 |
2 files changed, 83 insertions, 3 deletions
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 7b62de1..b805a72 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -2218,15 +2218,17 @@ void QApplication::closeAllWindows() { bool did_close = true; QWidget *w; - while((w = activeModalWidget()) && did_close) { - if(!w->isVisible()) + while ((w = activeModalWidget()) && did_close) { + if (!w->isVisible() || w->data->is_closing) break; did_close = w->close(); } QWidgetList list = QApplication::topLevelWidgets(); for (int i = 0; did_close && i < list.size(); ++i) { w = list.at(i); - if (w->isVisible() && w->windowType() != Qt::Desktop) { + if (w->isVisible() + && w->windowType() != Qt::Desktop + && !w->data->is_closing) { did_close = w->close(); list = QApplication::topLevelWidgets(); i = -1; diff --git a/tests/auto/qapplication/tst_qapplication.cpp b/tests/auto/qapplication/tst_qapplication.cpp index 459ac2b..43fbba1 100644 --- a/tests/auto/qapplication/tst_qapplication.cpp +++ b/tests/auto/qapplication/tst_qapplication.cpp @@ -106,6 +106,7 @@ private slots: void lastWindowClosed(); void quitOnLastWindowClosed(); + void closeAllWindows(); void testDeleteLater(); void testDeleteLaterProcessEvents(); @@ -745,6 +746,83 @@ void tst_QApplication::quitOnLastWindowClosed() } } +class PromptOnCloseWidget : public QWidget +{ +public: + void closeEvent(QCloseEvent *event) + { + QMessageBox *messageBox = new QMessageBox(this); + messageBox->setWindowTitle("Unsaved data"); + messageBox->setText("Would you like to save or discard your current data?"); + messageBox->setStandardButtons(QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel); + messageBox->setDefaultButton(QMessageBox::Save); + + messageBox->show(); + QTest::qWaitForWindowShown(messageBox); + + // verify that all windows are visible + foreach (QWidget *w, qApp->topLevelWidgets()) + QVERIFY(w->isVisible()); + // flush event queue + qApp->processEvents(); + // close all windows + qApp->closeAllWindows(); + + if (messageBox->standardButton(messageBox->clickedButton()) == QMessageBox::Cancel) + event->ignore(); + else + event->accept(); + + delete messageBox; + } +}; + +void tst_QApplication::closeAllWindows() +{ + int argc = 0; + QApplication app(argc, 0, QApplication::GuiServer); + + // create some windows + new QWidget; + new QWidget; + new QWidget; + + // show all windows + foreach (QWidget *w, app.topLevelWidgets()) { + w->show(); + QTest::qWaitForWindowShown(w); + } + // verify that they are visible + foreach (QWidget *w, app.topLevelWidgets()) + QVERIFY(w->isVisible()); + // empty event queue + app.processEvents(); + // close all windows + app.closeAllWindows(); + // all windows should no longer be visible + foreach (QWidget *w, app.topLevelWidgets()) + QVERIFY(!w->isVisible()); + + // add a window that prompts the user when closed + PromptOnCloseWidget *promptOnCloseWidget = new PromptOnCloseWidget; + // show all windows + foreach (QWidget *w, app.topLevelWidgets()) { + w->show(); + QTest::qWaitForWindowShown(w); + } + // close the last window to open the prompt (eventloop recurses) + promptOnCloseWidget->close(); + // all windows should not be visible, except the one that opened the prompt + foreach (QWidget *w, app.topLevelWidgets()) { + if (w == promptOnCloseWidget) + QVERIFY(w->isVisible()); + else + QVERIFY(!w->isVisible()); + } + + qDeleteAll(app.topLevelWidgets()); +} + bool isPathListIncluded(const QStringList &l, const QStringList &r) { int size = r.count(); |