summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorStephen Kelly <stephen.kelly@kdab.com>2012-02-11 01:33:55 +0100
committerQt by Nokia <qt-info@nokia.com>2012-02-16 01:56:27 +0100
commit66603985f2de74ac5f3bd5d259f0e65f710f62d7 (patch)
tree65049a5d31f1e8a978f60f5fc12d1dd26be73284 /tests/auto
parent90feedb6429df225b81bc279093ae1ca1278b391 (diff)
Fix ref counted window close handling.
Instead of refcounting QWindow visibility, we ask the Application subclass whether quitting is appropriate. Task-Id: QTBUG-24120 Change-Id: Idd19cc1a3e5742fddded89c7638aaaa5e47c568d Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com> Reviewed-by: Robin Burchell <robin+qt@viroteck.net>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp513
1 files changed, 14 insertions, 499 deletions
diff --git a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
index c600956912..fcb6b93e99 100644
--- a/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
+++ b/tests/auto/widgets/kernel/qapplication/tst_qapplication.cpp
@@ -137,16 +137,7 @@ private slots:
void touchEventPropagation();
void qtbug_12673();
-
- void testQuitLockRef();
- void testQuitLock1();
- void testQuitLock2();
- void testQuitLock3();
- void testQuitLock4();
- void testQuitLock5();
- void testQuitLock6();
- void testQuitLock7();
- void testQuitLock8();
+ void noQuitOnHide();
void globalStaticObjectDestruction(); // run this last
@@ -2060,506 +2051,30 @@ void tst_QApplication::qtbug_12673()
QCOMPARE(testProcess.exitStatus(), QProcess::NormalExit);
}
-class JobObject : public QObject
-{
- Q_OBJECT
-public:
- JobObject(int milliseconds, QObject *parent = 0)
- : QObject(parent)
- {
- QTimer::singleShot(milliseconds, this, SLOT(timeout()));
- }
-
- JobObject(QObject *parent = 0)
- : QObject(parent)
- {
- QTimer::singleShot(1000, this, SLOT(timeout()));
- }
-
-private slots:
- void timeout()
- {
- emit done();
- deleteLater();
- }
-
-signals:
- void done();
-
-private:
- QEventLoopLocker locker;
-};
-
-class QuitLockRefTester : public QObject
-{
- Q_OBJECT
-public:
- QuitLockRefTester(QObject *parent = 0)
- : QObject(parent)
- {
- QTimer::singleShot(0, this, SLOT(doTest()));
- }
-
-private slots:
- void doTest()
- {
- QApplicationPrivate *privateClass = static_cast<QApplicationPrivate*>(QObjectPrivate::get(qApp));
-
- {
- QDialog *win1 = new QDialog;
-
- // Test with a lock active so that the refcount doesn't drop to zero during these tests, causing a quit.
- // (until we exit the scope)
- QEventLoopLocker locker;
-
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- win1->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QDialog *win2 = new QDialog;
-
- win2->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 3);
-
- delete win1;
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- delete win2;
-
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- win1 = new QDialog;
-
- win1->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- JobObject *job1 = new JobObject(this);
-
- QCOMPARE(privateClass->quitLockRef.load(), 3);
-
- delete win1;
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- delete job1;
-
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- QWidget *w1 = new QWidget;
-
- w1->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *w2 = new QMainWindow;
-
- w2->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 3);
-
- QWidget *w3 = new QWidget(0, Qt::Dialog);
-
- w3->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 4);
-
- delete w3;
-
- QCOMPARE(privateClass->quitLockRef.load(), 3);
-
- delete w2;
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *subWidget1 = new QWidget(w1, Qt::Window);
-
- // Even though We create a new widget and show it,
- // the ref count does not go up because it is a child of
- // w1, which is the top-level, and what we are actually
- // refcounting.
- subWidget1->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- // When we use setParent(0) and re-show, the
- // ref count does increase:
- QCOMPARE(subWidget1->isVisible(), true);
- subWidget1->setParent(0);
- QCOMPARE(subWidget1->isVisible(), false);
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- subWidget1->show();
- QCOMPARE(subWidget1->isVisible(), true);
- QCOMPARE(privateClass->quitLockRef.load(), 3);
-
- subWidget1->setParent(w1);
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *subWidget2 = new QWidget(w1);
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- subWidget2->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- delete subWidget2;
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *subWidget3 = new QWidget(w1);
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- subWidget3->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- subWidget3->hide();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- delete subWidget3;
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *subWidget4 = new QWidget(subWidget1);
- QWidget *subWidget5 = new QWidget(subWidget1);
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- QWidget *subWidget6 = new QWidget(subWidget4, Qt::Window);
-
- subWidget6->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- delete w1;
-
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- w1 = new QWidget;
- w2 = new QWidget;
- w3 = new QWidget;
-
- QHBoxLayout *layout = new QHBoxLayout(w1);
-
- layout->addWidget(w2);
- layout->addWidget(w3);
-
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- w1->show();
-
- QCOMPARE(privateClass->quitLockRef.load(), 2);
-
- w1->hide();
- QCOMPARE(privateClass->quitLockRef.load(), 1);
-
- delete w1;
-
- }
- QCOMPARE(privateClass->quitLockRef.load(), 0);
- }
-};
-
-void tst_QApplication::testQuitLockRef()
-{
- int argc = 1;
- char *argv[] = { "tst_qapplication" };
- QApplication app(argc, argv);
-
- QuitLockRefTester tester;
-
- app.exec();
-}
-
-void tst_QApplication::testQuitLock1()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- QWidget *w = new QWidget;
-
- w->show();
-
- QMetaObject::invokeMethod(w, "close", Qt::QueuedConnection);
-
- app.exec();
-
- // No hang = pass.
-}
-
-void tst_QApplication::testQuitLock2()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- QWidget *w1 = new QWidget;
-
- w1->show();
-
- QWidget *w2 = new QWidget;
-
- w2->show();
-
- QMetaObject::invokeMethod(w1, "deleteLater", Qt::QueuedConnection);
- QMetaObject::invokeMethod(w2, "hide", Qt::QueuedConnection);
-
- app.exec();
-
- // No hang = pass.
-}
-
-class Result : public QObject
+class NoQuitOnHideWidget : public QWidget
{
Q_OBJECT
public:
- Result(QObject *parent = 0)
- : QObject(parent), m_passes(false)
+ NoQuitOnHideWidget(QWidget *parent = 0)
+ : QWidget(parent)
{
-
- }
-
- bool result() const
- {
- return m_passes;
- }
-
-public slots:
-
- void setPasses()
- {
- setResult(true);
- }
-
- void setFails()
- {
- setResult(false);
- }
-
- void setResult(bool result)
- {
- m_passes = result;
- }
-
-private:
- bool m_passes;
-};
-
-void tst_QApplication::testQuitLock3()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- Result *result = new Result(&app);
-
- JobObject *job = new JobObject(&app);
-
- QObject::connect(job, SIGNAL(done()), result, SLOT(setPasses()));
-
- app.exec();
-
- QVERIFY(result->result());
-}
-
-void tst_QApplication::testQuitLock4()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- QWidget *w = new QWidget;
-
- w->show();
-
- Result *result = new Result(&app);
- JobObject *job = new JobObject(1000, &app);
-
- QTimer::singleShot(500, w, SLOT(deleteLater()));
-
- QObject::connect(w, SIGNAL(destroyed()), result, SLOT(setFails()));
- QObject::connect(job, SIGNAL(done()), result, SLOT(setPasses()));
-
- app.exec();
-
- QVERIFY(result->result());
-}
-
-class JobBeforeWindowRunner : public QObject
-{
- Q_OBJECT
-public:
- JobBeforeWindowRunner(QObject *parent = 0)
- : QObject(parent), m_result(new Result(this))
- {
-
- }
-
- void start()
- {
- JobObject *job = new JobObject(this);
- connect(job, SIGNAL(done()), m_result, SLOT(setFails()));
- connect(job, SIGNAL(destroyed()), SLOT(showWindowDelayed()), Qt::QueuedConnection);
+ QTimer::singleShot(0, this, SLOT(hide()));
+ QTimer::singleShot(500, this, SLOT(exitApp()));
}
- bool result() const { return m_result->result(); }
-
private slots:
- void showWindowDelayed()
- {
- qApp->setQuitLockEnabled(true);
- QTimer::singleShot(500, this, SLOT(showWindow()));
- }
-
- void showWindow()
- {
- QWidget *w = new QWidget;
- w->show();
- w->deleteLater();
- connect(w, SIGNAL(destroyed()), m_result, SLOT(setPasses()));
- }
-
-private:
- Result * const m_result;
-};
-
-void tst_QApplication::testQuitLock5()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
- app.setQuitLockEnabled(false);
- // Run a job before showing a window, and only enable the refcounting
- // after doing so.
- // Although the job brings the refcount to zero, the app does not exit
- // until setQuitLockEnabled is called and the feature re-enabled.
-
- JobBeforeWindowRunner *eventRunner = new JobBeforeWindowRunner(&app);
-
- eventRunner->start();
-
- app.exec();
-
- QVERIFY(eventRunner->result());
-}
-
-class JobDuringWindowRunner : public QObject
-{
- Q_OBJECT
-public:
- JobDuringWindowRunner(QObject *parent = 0)
- : QObject(parent), m_result(new Result(this))
- {
-
- }
-
- void start()
- {
- JobObject *job = new JobObject(this);
-
- QWidget *w = new QWidget;
- w->show();
- w->deleteLater();
-
- QObject::connect(w, SIGNAL(destroyed()), m_result, SLOT(setFails()));
- QObject::connect(job, SIGNAL(done()), m_result, SLOT(setPasses()));
- }
-
- bool result() const { return m_result->result(); }
-
-private:
- Result * const m_result;
-};
-
-void tst_QApplication::testQuitLock6()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- // A job runs, and while it is running, a window is shown and closed,
- // then the job ends, which causes the quit.
-
- JobDuringWindowRunner *eventRunner = new JobDuringWindowRunner(&app);
-
- eventRunner->start();
-
- app.exec();
-
- QVERIFY(eventRunner->result());
-}
-class JobWindowJobWindowRunner : public QObject
-{
- Q_OBJECT
-public:
- JobWindowJobWindowRunner(QObject *parent = 0)
- : QObject(parent), m_result(new Result(this))
- {
-
- }
-
- void start()
- {
- JobObject *job = new JobObject(500, this);
-
- QWidget *w = new QWidget;
- w->show();
- QTimer::singleShot(1000, w, SLOT(deleteLater()));
-
- QObject::connect(w, SIGNAL(destroyed()), m_result, SLOT(setPasses()));
- QObject::connect(job, SIGNAL(done()), m_result, SLOT(setFails()));
+ void exitApp() {
+ qApp->exit(1);
}
-
- bool result() const { return m_result->result(); }
-private:
- Result * const m_result;
};
-void tst_QApplication::testQuitLock7()
+void tst_QApplication::noQuitOnHide()
{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- // A job runs, and while it is running, a window is shown
- // then the job ends, then the window is closed, which causes the quit.
-
- JobWindowJobWindowRunner *eventRunner = new JobWindowJobWindowRunner(&app);
-
- eventRunner->start();
-
- app.exec();
-
- QVERIFY(eventRunner->result());
-}
-
-void tst_QApplication::testQuitLock8()
-{
- int argc = 1;
- char *argv[] = { "tst_qcoreapplication" };
- QApplication app(argc, argv);
-
- QMainWindow *mw1 = new QMainWindow;
- mw1->show();
- QMainWindow *mw2 = new QMainWindow;
- mw2->show();
-
- QMetaObject::invokeMethod(mw1, "close", Qt::QueuedConnection);
- QMetaObject::invokeMethod(mw2, "close", Qt::QueuedConnection);
-
- app.exec();
-
- // No hang = pass
+ int argc = 0;
+ QApplication app(argc, 0);
+ QWidget *window1 = new NoQuitOnHideWidget(false);
+ window1->show();
+ QCOMPARE(app.exec(), 1);
}
class ShowCloseShowWidget : public QWidget