578ea9f693436119b4205b5f1c42088e7848acd2
[profile/ivi/qtbase.git] / tests / auto / gui / kernel / qguiapplication / tst_qguiapplication.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
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.
16 **
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.
20 **
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.
28 **
29 ** Other Usage
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.
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42
43 #include <QtTest/QtTest>
44 #include <QtGui/QGuiApplication>
45 #include <QtGui/QWindow>
46 #include <QDebug>
47
48 class tst_QGuiApplication: public QObject
49 {
50     Q_OBJECT
51
52 private slots:
53     void focusObject();
54     void allWindows();
55     void topLevelWindows();
56     void abortQuitOnShow();
57     void changeFocusWindow();
58     void keyboardModifiers();
59     void modalWindow();
60 };
61
62 class DummyWindow : public QWindow
63 {
64 public:
65     DummyWindow() : m_focusObject(0) {}
66
67     virtual QObject *focusObject() const
68     {
69         return m_focusObject;
70     }
71
72     void setFocusObject(QObject *object)
73     {
74         m_focusObject = object;
75         emit focusObjectChanged(object);
76     }
77
78     QObject *m_focusObject;
79 };
80
81
82 void tst_QGuiApplication::focusObject()
83 {
84     int argc = 0;
85     QGuiApplication app(argc, 0);
86
87     QObject obj1, obj2, obj3;
88     DummyWindow window1;
89     DummyWindow window2;
90     window1.show();
91
92     QSignalSpy spy(&app, SIGNAL(focusObjectChanged(QObject *)));
93
94
95     // verify active window focus propagates to qguiapplication
96     QTest::qWaitForWindowShown(&window1);
97     window1.requestActivateWindow();
98     QTRY_COMPARE(app.focusWindow(), &window1);
99
100     window1.setFocusObject(&obj1);
101     QCOMPARE(app.focusObject(), &obj1);
102     QCOMPARE(spy.count(), 1);
103
104     spy.clear();
105     window1.setFocusObject(&obj2);
106     QCOMPARE(app.focusObject(), &obj2);
107     QCOMPARE(spy.count(), 1);
108
109     spy.clear();
110     window2.setFocusObject(&obj3);
111     QCOMPARE(app.focusObject(), &obj2); // not yet changed
112     window2.show();
113     QTest::qWaitForWindowShown(&window2);
114     QTRY_COMPARE(app.focusWindow(), &window2);
115     QCOMPARE(app.focusObject(), &obj3);
116     QCOMPARE(spy.count(), 1);
117
118     // focus change on unfocused window does not show
119     spy.clear();
120     window1.setFocusObject(&obj1);
121     QCOMPARE(spy.count(), 0);
122     QCOMPARE(app.focusObject(), &obj3);
123 }
124
125 void tst_QGuiApplication::allWindows()
126 {
127     int argc = 0;
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);
134     delete window1;
135     window1 = 0;
136     window2 = 0;
137     QVERIFY(!app.allWindows().contains(window2));
138     QVERIFY(!app.allWindows().contains(window1));
139     QCOMPARE(app.allWindows().count(), 0);
140 }
141
142 void tst_QGuiApplication::topLevelWindows()
143 {
144     int argc = 0;
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);
151     delete window1;
152     window1 = 0;
153     window2 = 0;
154     QVERIFY(!app.topLevelWindows().contains(window2));
155     QVERIFY(!app.topLevelWindows().contains(window1));
156     QCOMPARE(app.topLevelWindows().count(), 0);
157 }
158
159 class ShowCloseShowWindow : public QWindow
160 {
161     Q_OBJECT
162 public:
163     ShowCloseShowWindow(bool showAgain, QWindow *parent = 0)
164       : QWindow(parent), showAgain(showAgain)
165     {
166         QTimer::singleShot(0, this, SLOT(doClose()));
167         QTimer::singleShot(500, this, SLOT(exitApp()));
168     }
169
170 private slots:
171     void doClose() {
172         close();
173         if (showAgain)
174             show();
175     }
176
177     void exitApp() {
178       qApp->exit(1);
179     }
180
181 private:
182     bool showAgain;
183 };
184
185 void tst_QGuiApplication::abortQuitOnShow()
186 {
187     int argc = 0;
188     QGuiApplication app(argc, 0);
189     QWindow *window1 = new ShowCloseShowWindow(false);
190     window1->show();
191     QCOMPARE(app.exec(), 0);
192
193     QWindow *window2 = new ShowCloseShowWindow(true);
194     window2->show();
195     QCOMPARE(app.exec(), 1);
196 }
197
198
199 class FocusChangeWindow: public QWindow
200 {
201 protected:
202     virtual bool event(QEvent *ev)
203     {
204         if (ev->type() == QEvent::FocusAboutToChange)
205             windowDuringFocusAboutToChange = qGuiApp->focusWindow();
206         return QWindow::event(ev);
207     }
208
209     virtual void focusOutEvent(QFocusEvent *)
210     {
211         windowDuringFocusOut = qGuiApp->focusWindow();
212     }
213
214 public:
215     FocusChangeWindow() : QWindow(), windowDuringFocusAboutToChange(0), windowDuringFocusOut(0) {}
216
217     QWindow *windowDuringFocusAboutToChange;
218     QWindow *windowDuringFocusOut;
219 };
220
221 void tst_QGuiApplication::changeFocusWindow()
222 {
223     int argc = 0;
224     QGuiApplication app(argc, 0);
225
226     // focus is changed between FocusAboutToChange and FocusChanged
227     FocusChangeWindow window1, window2;
228     window1.show();
229     window2.show();
230     QTest::qWaitForWindowShown(&window1);
231     QTest::qWaitForWindowShown(&window2);
232     window1.requestActivateWindow();
233     QTRY_COMPARE(app.focusWindow(), &window1);
234
235     window2.requestActivateWindow();
236     QTRY_COMPARE(app.focusWindow(), &window2);
237     QCOMPARE(window1.windowDuringFocusAboutToChange, &window1);
238     QCOMPARE(window1.windowDuringFocusOut, &window2);
239 }
240
241 void tst_QGuiApplication::keyboardModifiers()
242 {
243     int argc = 0;
244     QGuiApplication app(argc, 0);
245
246     QWindow *window = new QWindow;
247     window->show();
248     QTest::qWaitForWindowShown(window);
249     QCOMPARE(QGuiApplication::keyboardModifiers(), Qt::NoModifier);
250
251     // mouse events
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);
261
262     // shortcut events
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);
269
270     // key events
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);
275
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);
280
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);
285
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);
290
291     // wheel events
292     QPoint global = window->mapToGlobal(center);
293     QPoint delta(0, 1);
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);
303
304     // touch events
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);
310     }
311
312     window->close();
313     delete window;
314 }
315
316 class BlockableWindow : public QWindow
317 {
318     Q_OBJECT
319 public:
320     int blocked;
321
322     inline BlockableWindow()
323         : QWindow()
324     {
325         blocked = false;
326     }
327
328     bool event(QEvent *e)
329     {
330         switch (e->type()) {
331         case QEvent::WindowBlocked:
332             ++blocked;
333             break;
334         case QEvent::WindowUnblocked:
335             --blocked;
336             break;
337         default:
338             break;
339         }
340         return QWindow::event(e);
341     }
342 };
343
344 void tst_QGuiApplication::modalWindow()
345 {
346     int argc = 0;
347     QGuiApplication app(argc, 0);
348
349     BlockableWindow *window1 = new BlockableWindow;
350
351     BlockableWindow *window2 = new BlockableWindow;
352
353     BlockableWindow *windowModalWindow1 = new BlockableWindow;
354     windowModalWindow1->setTransientParent(window1);
355     windowModalWindow1->setWindowModality(Qt::WindowModal);
356
357     BlockableWindow *windowModalWindow2 = new BlockableWindow;
358     windowModalWindow2->setTransientParent(windowModalWindow1);
359     windowModalWindow2->setWindowModality(Qt::WindowModal);
360
361     BlockableWindow *applicationModalWindow1 = new BlockableWindow;
362     applicationModalWindow1->setWindowModality(Qt::ApplicationModal);
363
364     // show the 2 windows, nothing is blocked
365     window1->show();
366     window2->show();
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);
375
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);
384
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);
393
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);
402
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);
411
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);
420
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);
429
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);
438
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);
447
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);
456
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);
465
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);
474
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);
483
484     window2->hide();
485     window1->hide();
486
487     delete applicationModalWindow1;
488     delete windowModalWindow2;
489     delete windowModalWindow1;
490     delete window2;
491     delete window1;
492 }
493
494 QTEST_APPLESS_MAIN(tst_QGuiApplication)
495 #include "tst_qguiapplication.moc"