1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
43 #include <QtTest/QtTest>
44 #include <QtGui/QGuiApplication>
45 #include <QtGui/QWindow>
48 class tst_QGuiApplication: public QObject
55 void topLevelWindows();
56 void abortQuitOnShow();
57 void changeFocusWindow();
58 void keyboardModifiers();
62 class DummyWindow : public QWindow
65 DummyWindow() : m_focusObject(0) {}
67 virtual QObject *focusObject() const
72 void setFocusObject(QObject *object)
74 m_focusObject = object;
75 emit focusObjectChanged(object);
78 QObject *m_focusObject;
82 void tst_QGuiApplication::focusObject()
85 QGuiApplication app(argc, 0);
87 QObject obj1, obj2, obj3;
92 QSignalSpy spy(&app, SIGNAL(focusObjectChanged(QObject *)));
95 // verify active window focus propagates to qguiapplication
96 QTest::qWaitForWindowShown(&window1);
97 window1.requestActivateWindow();
98 QTRY_COMPARE(app.focusWindow(), &window1);
100 window1.setFocusObject(&obj1);
101 QCOMPARE(app.focusObject(), &obj1);
102 QCOMPARE(spy.count(), 1);
105 window1.setFocusObject(&obj2);
106 QCOMPARE(app.focusObject(), &obj2);
107 QCOMPARE(spy.count(), 1);
110 window2.setFocusObject(&obj3);
111 QCOMPARE(app.focusObject(), &obj2); // not yet changed
113 QTest::qWaitForWindowShown(&window2);
114 QTRY_COMPARE(app.focusWindow(), &window2);
115 QCOMPARE(app.focusObject(), &obj3);
116 QCOMPARE(spy.count(), 1);
118 // focus change on unfocused window does not show
120 window1.setFocusObject(&obj1);
121 QCOMPARE(spy.count(), 0);
122 QCOMPARE(app.focusObject(), &obj3);
125 void tst_QGuiApplication::allWindows()
128 QGuiApplication app(argc, 0);
129 QWindow *window1 = new QWindow;
130 QWindow *window2 = new QWindow(window1);
131 QVERIFY(app.allWindows().contains(window1));
132 QVERIFY(app.allWindows().contains(window2));
133 QCOMPARE(app.allWindows().count(), 2);
137 QVERIFY(!app.allWindows().contains(window2));
138 QVERIFY(!app.allWindows().contains(window1));
139 QCOMPARE(app.allWindows().count(), 0);
142 void tst_QGuiApplication::topLevelWindows()
145 QGuiApplication app(argc, 0);
146 QWindow *window1 = new QWindow;
147 QWindow *window2 = new QWindow(window1);
148 QVERIFY(app.topLevelWindows().contains(window1));
149 QVERIFY(!app.topLevelWindows().contains(window2));
150 QCOMPARE(app.topLevelWindows().count(), 1);
154 QVERIFY(!app.topLevelWindows().contains(window2));
155 QVERIFY(!app.topLevelWindows().contains(window1));
156 QCOMPARE(app.topLevelWindows().count(), 0);
159 class ShowCloseShowWindow : public QWindow
163 ShowCloseShowWindow(bool showAgain, QWindow *parent = 0)
164 : QWindow(parent), showAgain(showAgain)
166 QTimer::singleShot(0, this, SLOT(doClose()));
167 QTimer::singleShot(500, this, SLOT(exitApp()));
185 void tst_QGuiApplication::abortQuitOnShow()
188 QGuiApplication app(argc, 0);
189 QWindow *window1 = new ShowCloseShowWindow(false);
191 QCOMPARE(app.exec(), 0);
193 QWindow *window2 = new ShowCloseShowWindow(true);
195 QCOMPARE(app.exec(), 1);
199 class FocusChangeWindow: public QWindow
202 virtual bool event(QEvent *ev)
204 if (ev->type() == QEvent::FocusAboutToChange)
205 windowDuringFocusAboutToChange = qGuiApp->focusWindow();
206 return QWindow::event(ev);
209 virtual void focusOutEvent(QFocusEvent *)
211 windowDuringFocusOut = qGuiApp->focusWindow();
215 FocusChangeWindow() : QWindow(), windowDuringFocusAboutToChange(0), windowDuringFocusOut(0) {}
217 QWindow *windowDuringFocusAboutToChange;
218 QWindow *windowDuringFocusOut;
221 void tst_QGuiApplication::changeFocusWindow()
224 QGuiApplication app(argc, 0);
226 // focus is changed between FocusAboutToChange and FocusChanged
227 FocusChangeWindow window1, window2;
230 QTest::qWaitForWindowShown(&window1);
231 QTest::qWaitForWindowShown(&window2);
232 window1.requestActivateWindow();
233 QTRY_COMPARE(app.focusWindow(), &window1);
235 window2.requestActivateWindow();
236 QTRY_COMPARE(app.focusWindow(), &window2);
237 QCOMPARE(window1.windowDuringFocusAboutToChange, &window1);
238 QCOMPARE(window1.windowDuringFocusOut, &window2);
241 void tst_QGuiApplication::keyboardModifiers()
244 QGuiApplication app(argc, 0);
246 QWindow *window = new QWindow;
248 QTest::qWaitForWindowShown(window);
249 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
252 QPoint center = window->geometry().center();
253 QTest::mouseEvent(QTest::MousePress, window, Qt::LeftButton, Qt::NoModifier, center);
254 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
255 QTest::mouseEvent(QTest::MouseRelease, window, Qt::LeftButton, Qt::NoModifier, center);
256 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
257 QTest::mouseEvent(QTest::MousePress, window, Qt::RightButton, Qt::ControlModifier, center);
258 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
259 QTest::mouseEvent(QTest::MouseRelease, window, Qt::RightButton, Qt::ControlModifier, center);
260 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
263 QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_5, Qt::MetaModifier);
264 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::MetaModifier);
265 QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_Period, Qt::NoModifier);
266 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
267 QWindowSystemInterface::tryHandleSynchronousShortcutEvent(window, Qt::Key_0, Qt::ControlModifier);
268 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
271 QTest::keyEvent(QTest::Press, window, Qt::Key_C);
272 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
273 QTest::keyEvent(QTest::Release, window, Qt::Key_C);
274 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
276 QTest::keyEvent(QTest::Press, window, Qt::Key_U, Qt::ControlModifier);
277 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
278 QTest::keyEvent(QTest::Release, window, Qt::Key_U, Qt::ControlModifier);
279 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
281 QTest::keyEvent(QTest::Press, window, Qt::Key_T);
282 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
283 QTest::keyEvent(QTest::Release, window, Qt::Key_T);
284 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
286 QTest::keyEvent(QTest::Press, window, Qt::Key_E, Qt::ControlModifier);
287 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
288 QTest::keyEvent(QTest::Release, window, Qt::Key_E, Qt::ControlModifier);
289 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
292 QPoint global = window->mapToGlobal(center);
294 QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::NoModifier);
295 QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
296 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
297 QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::AltModifier);
298 QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
299 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::AltModifier);
300 QWindowSystemInterface::handleWheelEvent(window, center, global, delta, delta, Qt::ControlModifier);
301 QWindowSystemInterface::sendWindowSystemEvents(app.eventDispatcher(), QEventLoop::AllEvents);
302 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::ControlModifier);
305 QList<const QTouchDevice *> touchDevices = QTouchDevice::devices();
306 if (!touchDevices.isEmpty()) {
307 QTouchDevice *touchDevice = const_cast<QTouchDevice *>(touchDevices.first());
308 QTest::touchEvent(window, touchDevice).press(1, center).release(1, center);
309 QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
316 class BlockableWindow : public QWindow
322 inline BlockableWindow()
328 bool event(QEvent *e)
331 case QEvent::WindowBlocked:
334 case QEvent::WindowUnblocked:
340 return QWindow::event(e);
344 void tst_QGuiApplication::modalWindow()
347 QGuiApplication app(argc, 0);
349 BlockableWindow *window1 = new BlockableWindow;
351 BlockableWindow *window2 = new BlockableWindow;
353 BlockableWindow *windowModalWindow1 = new BlockableWindow;
354 windowModalWindow1->setTransientParent(window1);
355 windowModalWindow1->setWindowModality(Qt::WindowModal);
357 BlockableWindow *windowModalWindow2 = new BlockableWindow;
358 windowModalWindow2->setTransientParent(windowModalWindow1);
359 windowModalWindow2->setWindowModality(Qt::WindowModal);
361 BlockableWindow *applicationModalWindow1 = new BlockableWindow;
362 applicationModalWindow1->setWindowModality(Qt::ApplicationModal);
364 // show the 2 windows, nothing is blocked
367 QTest::qWaitForWindowShown(window1);
368 QTest::qWaitForWindowShown(window2);
369 QCOMPARE(app.modalWindow(), static_cast<QWindow *>(0));
370 QCOMPARE(window1->blocked, 0);
371 QCOMPARE(window2->blocked, 0);
372 QCOMPARE(windowModalWindow1->blocked, 0);
373 QCOMPARE(windowModalWindow2->blocked, 0);
374 QCOMPARE(applicationModalWindow1->blocked, 0);
376 // show applicationModalWindow1, everything is blocked
377 applicationModalWindow1->show();
378 QCOMPARE(app.modalWindow(), applicationModalWindow1);
379 QCOMPARE(window1->blocked, 1);
380 QCOMPARE(window2->blocked, 1);
381 QCOMPARE(windowModalWindow1->blocked, 1);
382 QCOMPARE(windowModalWindow2->blocked, 1);
383 QCOMPARE(applicationModalWindow1->blocked, 0);
385 // everything is unblocked when applicationModalWindow1 is hidden
386 applicationModalWindow1->hide();
387 QCOMPARE(app.modalWindow(), static_cast<QWindow *>(0));
388 QCOMPARE(window1->blocked, 0);
389 QCOMPARE(window2->blocked, 0);
390 QCOMPARE(windowModalWindow1->blocked, 0);
391 QCOMPARE(windowModalWindow2->blocked, 0);
392 QCOMPARE(applicationModalWindow1->blocked, 0);
394 // show the windowModalWindow1, only window1 is blocked
395 windowModalWindow1->show();
396 QCOMPARE(app.modalWindow(), windowModalWindow1);
397 QCOMPARE(window1->blocked, 1);
398 QCOMPARE(window2->blocked, 0);
399 QCOMPARE(windowModalWindow1->blocked, 0);
400 QCOMPARE(windowModalWindow2->blocked, 0);
401 QCOMPARE(applicationModalWindow1->blocked, 0);
403 // show the windowModalWindow2, windowModalWindow1 is blocked as well
404 windowModalWindow2->show();
405 QCOMPARE(app.modalWindow(), windowModalWindow2);
406 QCOMPARE(window1->blocked, 1);
407 QCOMPARE(window2->blocked, 0);
408 QCOMPARE(windowModalWindow1->blocked, 1);
409 QCOMPARE(windowModalWindow2->blocked, 0);
410 QCOMPARE(applicationModalWindow1->blocked, 0);
412 // hide windowModalWindow1, nothing is unblocked
413 windowModalWindow1->hide();
414 QCOMPARE(app.modalWindow(), windowModalWindow2);
415 QCOMPARE(window1->blocked, 1);
416 QCOMPARE(window2->blocked, 0);
417 QCOMPARE(windowModalWindow1->blocked, 1);
418 QCOMPARE(windowModalWindow2->blocked, 0);
419 QCOMPARE(applicationModalWindow1->blocked, 0);
421 // hide windowModalWindow2, windowModalWindow1 and window1 are unblocked
422 windowModalWindow2->hide();
423 QCOMPARE(app.modalWindow(), static_cast<QWindow *>(0));
424 QCOMPARE(window1->blocked, 0);
425 QCOMPARE(window2->blocked, 0);
426 QCOMPARE(windowModalWindow1->blocked, 0);
427 QCOMPARE(windowModalWindow2->blocked, 0);
428 QCOMPARE(applicationModalWindow1->blocked, 0);
430 // show windowModalWindow1 again, window1 is blocked
431 windowModalWindow1->show();
432 QCOMPARE(app.modalWindow(), windowModalWindow1);
433 QCOMPARE(window1->blocked, 1);
434 QCOMPARE(window2->blocked, 0);
435 QCOMPARE(windowModalWindow1->blocked, 0);
436 QCOMPARE(windowModalWindow2->blocked, 0);
437 QCOMPARE(applicationModalWindow1->blocked, 0);
439 // show windowModalWindow2 again, windowModalWindow1 is also blocked
440 windowModalWindow2->show();
441 QCOMPARE(app.modalWindow(), windowModalWindow2);
442 QCOMPARE(window1->blocked, 1);
443 QCOMPARE(window2->blocked, 0);
444 QCOMPARE(windowModalWindow1->blocked, 1);
445 QCOMPARE(windowModalWindow2->blocked, 0);
446 QCOMPARE(applicationModalWindow1->blocked, 0);
448 // show applicationModalWindow1, everything is blocked
449 applicationModalWindow1->show();
450 QCOMPARE(app.modalWindow(), applicationModalWindow1);
451 QCOMPARE(window1->blocked, 1);
452 QCOMPARE(window2->blocked, 1);
453 QCOMPARE(windowModalWindow1->blocked, 1);
454 QCOMPARE(windowModalWindow2->blocked, 1);
455 QCOMPARE(applicationModalWindow1->blocked, 0);
457 // hide applicationModalWindow1, windowModalWindow1 and window1 are blocked
458 applicationModalWindow1->hide();
459 QCOMPARE(app.modalWindow(), windowModalWindow2);
460 QCOMPARE(window1->blocked, 1);
461 QCOMPARE(window2->blocked, 0);
462 QCOMPARE(windowModalWindow1->blocked, 1);
463 QCOMPARE(windowModalWindow2->blocked, 0);
464 QCOMPARE(applicationModalWindow1->blocked, 0);
466 // hide windowModalWindow2, window1 is blocked
467 windowModalWindow2->hide();
468 QCOMPARE(app.modalWindow(), windowModalWindow1);
469 QCOMPARE(window1->blocked, 1);
470 QCOMPARE(window2->blocked, 0);
471 QCOMPARE(windowModalWindow1->blocked, 0);
472 QCOMPARE(windowModalWindow2->blocked, 0);
473 QCOMPARE(applicationModalWindow1->blocked, 0);
475 // hide windowModalWindow1, everything is unblocked
476 windowModalWindow1->hide();
477 QCOMPARE(app.modalWindow(), static_cast<QWindow *>(0));
478 QCOMPARE(window1->blocked, 0);
479 QCOMPARE(window2->blocked, 0);
480 QCOMPARE(windowModalWindow1->blocked, 0);
481 QCOMPARE(windowModalWindow2->blocked, 0);
482 QCOMPARE(applicationModalWindow1->blocked, 0);
487 delete applicationModalWindow1;
488 delete windowModalWindow2;
489 delete windowModalWindow1;
494 QTEST_APPLESS_MAIN(tst_QGuiApplication)
495 #include "tst_qguiapplication.moc"