diff options
author | Stephen Kelly <stephen.kelly@kdab.com> | 2012-05-14 16:58:26 +0200 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-06-12 04:30:18 +0200 |
commit | c5665a182db5002afe6dc7c69f343e89de5fca31 (patch) | |
tree | af488d02a88f3de714629303029c77240d697574 | |
parent | c66dc44968f4ae51e01cee7c7605991177d5e081 (diff) |
Only quit if there are no visible widgets or windows.
We need to let the QGuiApplication determine whether quitting is appropriate
based on whether there are visible top level QWindows after the last top-level
QWidget was closed.
This solves the issue raised here: http://thread.gmane.org/gmane.comp.lib.qt.user/1880
The transientParent is the QWindow equivalent of parentWidget on QWidget, so the test
in QGuiApplication::shouldQuit is similar to the one in QApplication::shouldQuit.
Change-Id: I500eff8d5887f24415180134b3a4be3c630a896f
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 2 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 2 | ||||
-rw-r--r-- | tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp | 63 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp | 24 |
5 files changed, 90 insertions, 3 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 3e999bee8d..846b7d01bf 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -2129,7 +2129,7 @@ bool QGuiApplicationPrivate::shouldQuit() QWindowList list = QGuiApplication::topLevelWindows(); for (int i = 0; i < list.size(); ++i) { QWindow *w = list.at(i); - if (w->isVisible()) + if (w->isVisible() && !w->transientParent()) return false; } return true; diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 8fe62bb7fd..f30a794b55 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1708,7 +1708,7 @@ void QWindowPrivate::maybeQuitOnLastWindowClosed() bool lastWindowClosed = true; for (int i = 0; i < list.size(); ++i) { QWindow *w = list.at(i); - if (!w->isVisible()) + if (!w->isVisible() || w->transientParent()) continue; lastWindowClosed = false; break; diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index e9003e8c14..0553dabe51 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2950,7 +2950,7 @@ bool QApplicationPrivate::shouldQuit() if (w->isVisible() && !w->parentWidget() && w->testAttribute(Qt::WA_QuitOnClose)) return false; } - return true; + return QGuiApplicationPrivate::shouldQuit(); } /*! \reimp diff --git a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp index 578ea9f693..372dd65ff4 100644 --- a/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp +++ b/tests/auto/gui/kernel/qguiapplication/tst_qguiapplication.cpp @@ -57,6 +57,7 @@ private slots: void changeFocusWindow(); void keyboardModifiers(); void modalWindow(); + void quitOnLastWindowClosed(); }; class DummyWindow : public QWindow @@ -491,5 +492,67 @@ void tst_QGuiApplication::modalWindow() delete window1; } +void tst_QGuiApplication::quitOnLastWindowClosed() +{ + { + int argc = 0; + QGuiApplication app(argc, 0); + + QTimer timer; + timer.setInterval(100); + + QSignalSpy spy(&app, SIGNAL(aboutToQuit())); + QSignalSpy spy2(&timer, SIGNAL(timeout())); + + QPointer<QWindow> mainWindow = new QWindow; + QPointer<QWindow> dialog = new QWindow; + + dialog->setTransientParent(mainWindow); + + QVERIFY(app.quitOnLastWindowClosed()); + + mainWindow->show(); + dialog->show(); + + timer.start(); + QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should quit the application + QTimer::singleShot(2000, &app, SLOT(quit())); // This makes sure we quit even if it didn't + + app.exec(); + + QCOMPARE(spy.count(), 1); + QVERIFY(spy2.count() < 15); // Should be around 10 if closing caused the quit + } + { + int argc = 0; + QGuiApplication app(argc, 0); + + QTimer timer; + timer.setInterval(100); + + QSignalSpy spy(&app, SIGNAL(aboutToQuit())); + QSignalSpy spy2(&timer, SIGNAL(timeout())); + + QPointer<QWindow> mainWindow = new QWindow; + QPointer<QWindow> dialog = new QWindow; + + QVERIFY(!dialog->transientParent()); + QVERIFY(app.quitOnLastWindowClosed()); + + mainWindow->show(); + dialog->show(); + + timer.start(); + QTimer::singleShot(1000, mainWindow, SLOT(close())); // This should not quit the application + QTimer::singleShot(2000, &app, SLOT(quit())); + + app.exec(); + + QCOMPARE(spy.count(), 1); + QVERIFY(spy2.count() > 15); // Should be around 20 if closing did not cause the quit + } +} + + QTEST_APPLESS_MAIN(tst_QGuiApplication) #include "tst_qguiapplication.moc" diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp index 000eea8555..120ed9127c 100644 --- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp +++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp @@ -718,6 +718,30 @@ void tst_QApplication::quitOnLastWindowClosed() QCOMPARE(timerSpy.count(), 1); QCOMPARE(appSpy.count(), 2); } + { + int argc = 0; + QApplication app(argc, 0, QApplication::GuiServer); + QVERIFY(app.quitOnLastWindowClosed()); + + QTimer timer; + timer.setInterval(100); + QSignalSpy timerSpy(&timer, SIGNAL(timeout())); + + QWindow w; + w.show(); + + QWidget wid; + wid.show(); + + timer.start(); + QTimer::singleShot(1000, &wid, SLOT(close())); // This should NOT quit the application because the + // QWindow is still there. + QTimer::singleShot(2000, &app, SLOT(quit())); // This causes the quit. + + app.exec(); + + QVERIFY(timerSpy.count() > 15); // Should be around 20 if closing did not caused the quit + } } class PromptOnCloseWidget : public QWidget |