Say hello to QtQuick module
[profile/ivi/qtdeclarative.git] / tests / auto / qtquick2 / qquickfocusscope / tst_qquickfocusscope.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the test suite of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 #include <qtest.h>
42 #include <QSignalSpy>
43 #include <QtDeclarative/qdeclarativeengine.h>
44 #include <QtDeclarative/qdeclarativecomponent.h>
45 #include <QtQuick/qquickview.h>
46 #include <QtQuick/private/qquickrectangle_p.h>
47 #include <private/qquicktextedit_p.h>
48 #include <QtQuick/private/qquicktext_p.h>
49 #include <QtQuick/private/qquickfocusscope_p.h>
50 #include "../../shared/util.h"
51
52 class tst_qquickfocusscope : public QObject
53 {
54     Q_OBJECT
55 public:
56     tst_qquickfocusscope() {}
57
58     template<typename T>
59     T *findItem(QQuickItem *parent, const QString &id);
60
61 private slots:
62     void initTestCase();
63     void cleanupTestCase();
64     void basic();
65     void nested();
66     void noFocus();
67     void textEdit();
68     void forceFocus();
69     void noParentFocus();
70     void signalEmission();
71     void qtBug13380();
72     void forceActiveFocus();
73     void canvasFocus();
74 };
75 void tst_qquickfocusscope::initTestCase()
76 {
77 }
78
79 void tst_qquickfocusscope::cleanupTestCase()
80 {
81
82 }
83
84 /*
85    Find an item with the specified id.
86 */
87 template<typename T>
88 T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName)
89 {
90     const QMetaObject &mo = T::staticMetaObject;
91     QList<QQuickItem *> children = parent->childItems();
92     for (int i = 0; i < children.count(); ++i) {
93         QQuickItem *item = children.at(i);
94         if (item) {
95             if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
96                 return static_cast<T*>(item);
97             }
98             item = findItem<T>(item, objectName);
99             if (item)
100                 return static_cast<T*>(item);
101         }
102     }
103     return 0;
104 }
105
106 void tst_qquickfocusscope::basic()
107 {
108     QQuickView *view = new QQuickView;
109     view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml")));
110
111     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
112     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
113     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
114     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
115     QVERIFY(item0 != 0);
116     QVERIFY(item1 != 0);
117     QVERIFY(item2 != 0);
118     QVERIFY(item3 != 0);
119
120     view->show();
121     view->requestActivateWindow();
122
123     QTest::qWaitForWindowShown(view);
124     QTRY_VERIFY(view == qGuiApp->focusWindow());
125
126     QVERIFY(view->isTopLevel());
127     QVERIFY(item0->hasActiveFocus() == true);
128     QVERIFY(item1->hasActiveFocus() == true);
129     QVERIFY(item2->hasActiveFocus() == false);
130     QVERIFY(item3->hasActiveFocus() == false);
131
132     QTest::keyClick(view, Qt::Key_Right);
133     QTest::qWait(50);
134     QVERIFY(item0->hasActiveFocus() == true);
135     QVERIFY(item1->hasActiveFocus() == false);
136     QVERIFY(item2->hasActiveFocus() == true);
137     QVERIFY(item3->hasActiveFocus() == false);
138
139     QTest::keyClick(view, Qt::Key_Down);
140     QTest::qWait(50);
141     QVERIFY(item0->hasActiveFocus() == false);
142     QVERIFY(item1->hasActiveFocus() == false);
143     QVERIFY(item2->hasActiveFocus() == false);
144     QVERIFY(item3->hasActiveFocus() == true);
145
146     delete view;
147 }
148
149 void tst_qquickfocusscope::nested()
150 {
151     QQuickView *view = new QQuickView;
152     view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml")));
153
154     QQuickFocusScope *item1 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item1"));
155     QQuickFocusScope *item2 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item2"));
156     QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
157     QQuickFocusScope *item4 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item4"));
158     QQuickFocusScope *item5 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item5"));
159     QVERIFY(item1 != 0);
160     QVERIFY(item2 != 0);
161     QVERIFY(item3 != 0);
162     QVERIFY(item4 != 0);
163     QVERIFY(item5 != 0);
164
165     view->show();
166     view->requestActivateWindow();
167
168     QTest::qWaitForWindowShown(view);
169     QTRY_VERIFY(view == qGuiApp->focusWindow());
170
171     QVERIFY(item1->hasActiveFocus() == true);
172     QVERIFY(item2->hasActiveFocus() == true);
173     QVERIFY(item3->hasActiveFocus() == true);
174     QVERIFY(item4->hasActiveFocus() == true);
175     QVERIFY(item5->hasActiveFocus() == true);
176     delete view;
177 }
178
179 void tst_qquickfocusscope::noFocus()
180 {
181     QQuickView *view = new QQuickView;
182     view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml")));
183
184     QQuickRectangle *item0 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item0"));
185     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
186     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
187     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
188     QVERIFY(item0 != 0);
189     QVERIFY(item1 != 0);
190     QVERIFY(item2 != 0);
191     QVERIFY(item3 != 0);
192
193     view->show();
194     view->requestActivateWindow();
195     QTest::qWaitForWindowShown(view);
196     QTRY_VERIFY(view == qGuiApp->focusWindow());
197
198     QVERIFY(item0->hasActiveFocus() == false);
199     QVERIFY(item1->hasActiveFocus() == false);
200     QVERIFY(item2->hasActiveFocus() == false);
201     QVERIFY(item3->hasActiveFocus() == false);
202
203     QTest::keyClick(view, Qt::Key_Right);
204     QVERIFY(item0->hasActiveFocus() == false);
205     QVERIFY(item1->hasActiveFocus() == false);
206     QVERIFY(item2->hasActiveFocus() == false);
207     QVERIFY(item3->hasActiveFocus() == false);
208
209     QTest::keyClick(view, Qt::Key_Down);
210     QVERIFY(item0->hasActiveFocus() == false);
211     QVERIFY(item1->hasActiveFocus() == false);
212     QVERIFY(item2->hasActiveFocus() == false);
213     QVERIFY(item3->hasActiveFocus() == false);
214
215     delete view;
216 }
217
218 void tst_qquickfocusscope::textEdit()
219 {
220     QQuickView *view = new QQuickView;
221     view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml")));
222
223     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
224     QQuickTextEdit *item1 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item1"));
225     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
226     QQuickTextEdit *item3 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item3"));
227     QVERIFY(item0 != 0);
228     QVERIFY(item1 != 0);
229     QVERIFY(item2 != 0);
230     QVERIFY(item3 != 0);
231
232     view->show();
233     view->requestActivateWindow();
234
235     QTest::qWaitForWindowShown(view);
236
237     QTRY_VERIFY(view == qGuiApp->focusWindow());
238     QVERIFY(item0->hasActiveFocus() == true);
239     QVERIFY(item1->hasActiveFocus() == true);
240     QVERIFY(item2->hasActiveFocus() == false);
241     QVERIFY(item3->hasActiveFocus() == false);
242
243     QTest::keyClick(view, Qt::Key_Right);
244     QVERIFY(item0->hasActiveFocus() == true);
245     QVERIFY(item1->hasActiveFocus() == true);
246     QVERIFY(item2->hasActiveFocus() == false);
247     QVERIFY(item3->hasActiveFocus() == false);
248
249     QTest::keyClick(view, Qt::Key_Right);
250     QTest::keyClick(view, Qt::Key_Right);
251     QTest::keyClick(view, Qt::Key_Right);
252     QTest::keyClick(view, Qt::Key_Right);
253     QTest::keyClick(view, Qt::Key_Right);
254     QVERIFY(item0->hasActiveFocus() == true);
255     QVERIFY(item1->hasActiveFocus() == false);
256     QVERIFY(item2->hasActiveFocus() == true);
257     QVERIFY(item3->hasActiveFocus() == false);
258
259     QTest::keyClick(view, Qt::Key_Down);
260     QVERIFY(item0->hasActiveFocus() == false);
261     QVERIFY(item1->hasActiveFocus() == false);
262     QVERIFY(item2->hasActiveFocus() == false);
263     QVERIFY(item3->hasActiveFocus() == true);
264
265     delete view;
266 }
267
268 void tst_qquickfocusscope::forceFocus()
269 {
270     QQuickView *view = new QQuickView;
271     view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml")));
272
273     QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0"));
274     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
275     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
276     QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3"));
277     QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
278     QQuickRectangle *item5 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item5"));
279     QVERIFY(item0 != 0);
280     QVERIFY(item1 != 0);
281     QVERIFY(item2 != 0);
282     QVERIFY(item3 != 0);
283     QVERIFY(item4 != 0);
284     QVERIFY(item5 != 0);
285
286     view->show();
287     view->requestActivateWindow();
288     QTest::qWaitForWindowShown(view);
289     QTRY_VERIFY(view == qGuiApp->focusWindow());
290
291     QVERIFY(item0->hasActiveFocus() == true);
292     QVERIFY(item1->hasActiveFocus() == true);
293     QVERIFY(item2->hasActiveFocus() == false);
294     QVERIFY(item3->hasActiveFocus() == false);
295     QVERIFY(item4->hasActiveFocus() == false);
296     QVERIFY(item5->hasActiveFocus() == false);
297
298     QTest::keyClick(view, Qt::Key_4);
299     QVERIFY(item0->hasActiveFocus() == true);
300     QVERIFY(item1->hasActiveFocus() == true);
301     QVERIFY(item2->hasActiveFocus() == false);
302     QVERIFY(item3->hasActiveFocus() == false);
303     QVERIFY(item4->hasActiveFocus() == false);
304     QVERIFY(item5->hasActiveFocus() == false);
305
306     QTest::keyClick(view, Qt::Key_5);
307     QVERIFY(item0->hasActiveFocus() == false);
308     QVERIFY(item1->hasActiveFocus() == false);
309     QVERIFY(item2->hasActiveFocus() == false);
310     QVERIFY(item3->hasActiveFocus() == true);
311     QVERIFY(item4->hasActiveFocus() == false);
312     QVERIFY(item5->hasActiveFocus() == true);
313
314     delete view;
315 }
316
317 void tst_qquickfocusscope::noParentFocus()
318 {
319     QQuickView *view = new QQuickView;
320     view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml")));
321     QVERIFY(view->rootObject());
322
323     view->show();
324     view->requestActivateWindow();
325     QTest::qWaitForWindowShown(view);
326     QTRY_VERIFY(view == qGuiApp->focusWindow());
327
328     QVERIFY(view->rootObject()->property("focus1") == false);
329     QVERIFY(view->rootObject()->property("focus2") == false);
330     QVERIFY(view->rootObject()->property("focus3") == true);
331     QVERIFY(view->rootObject()->property("focus4") == true);
332     QVERIFY(view->rootObject()->property("focus5") == true);
333
334     delete view;
335 }
336
337 void tst_qquickfocusscope::signalEmission()
338 {
339     QQuickView *view = new QQuickView;
340     view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml")));
341
342     QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1"));
343     QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2"));
344     QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3"));
345     QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4"));
346     QVERIFY(item1 != 0);
347     QVERIFY(item2 != 0);
348     QVERIFY(item3 != 0);
349     QVERIFY(item4 != 0);
350
351     view->show();
352     view->requestActivateWindow();
353
354     QTest::qWaitForWindowShown(view);
355     QTRY_VERIFY(view == qGuiApp->focusWindow());
356
357     QVariant blue(QColor("blue"));
358     QVariant red(QColor("red"));
359
360     item1->setFocus(true);
361     QCOMPARE(item1->property("color"), red);
362     QCOMPARE(item2->property("color"), blue);
363     QCOMPARE(item3->property("color"), blue);
364     QCOMPARE(item4->property("color"), blue);
365
366     item2->setFocus(true);
367     QCOMPARE(item1->property("color"), blue);
368     QCOMPARE(item2->property("color"), red);
369     QCOMPARE(item3->property("color"), blue);
370     QCOMPARE(item4->property("color"), blue);
371
372     item3->setFocus(true);
373     QCOMPARE(item1->property("color"), blue);
374     QCOMPARE(item2->property("color"), red);
375     QCOMPARE(item3->property("color"), red);
376     QCOMPARE(item4->property("color"), blue);
377
378     item4->setFocus(true);
379     QCOMPARE(item1->property("color"), blue);
380     QCOMPARE(item2->property("color"), red);
381     QCOMPARE(item3->property("color"), blue);
382     QCOMPARE(item4->property("color"), red);
383
384     item4->setFocus(false);
385     QCOMPARE(item1->property("color"), blue);
386     QCOMPARE(item2->property("color"), red);
387     QCOMPARE(item3->property("color"), blue);
388     QCOMPARE(item4->property("color"), blue);
389
390     delete view;
391 }
392
393 void tst_qquickfocusscope::qtBug13380()
394 {
395     QQuickView *view = new QQuickView;
396     view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml")));
397
398     view->show();
399     QVERIFY(view->rootObject());
400     view->requestActivateWindow();
401     qApp->processEvents();
402
403     QTest::qWaitForWindowShown(view);
404
405     QTRY_VERIFY(view == qGuiApp->focusWindow());
406     QVERIFY(view->rootObject()->property("noFocus").toBool());
407
408     view->rootObject()->setProperty("showRect", true);
409     QVERIFY(view->rootObject()->property("noFocus").toBool());
410
411     delete view;
412 }
413
414 void tst_qquickfocusscope::forceActiveFocus()
415 {
416     QQuickView *view = new QQuickView;
417     view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml")));
418
419     view->show();
420     view->requestActivateWindow();
421     QTest::qWaitForWindowShown(view);
422     QTRY_VERIFY(view == qGuiApp->focusWindow());
423
424     QQuickItem *rootObject = view->rootObject();
425     QVERIFY(rootObject);
426
427     QQuickItem *scope = findItem<QQuickItem>(rootObject, QLatin1String("scope"));
428     QQuickItem *itemA1 = findItem<QQuickItem>(rootObject, QLatin1String("item-a1"));
429     QQuickItem *scopeA = findItem<QQuickItem>(rootObject, QLatin1String("scope-a"));
430     QQuickItem *itemA2 = findItem<QQuickItem>(rootObject, QLatin1String("item-a2"));
431     QQuickItem *itemB1 = findItem<QQuickItem>(rootObject, QLatin1String("item-b1"));
432     QQuickItem *scopeB = findItem<QQuickItem>(rootObject, QLatin1String("scope-b"));
433     QQuickItem *itemB2 = findItem<QQuickItem>(rootObject, QLatin1String("item-b2"));
434
435     QVERIFY(scope);
436     QVERIFY(itemA1);
437     QVERIFY(scopeA);
438     QVERIFY(itemA2);
439     QVERIFY(itemB1);
440     QVERIFY(scopeB);
441     QVERIFY(itemB2);
442
443     QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool)));
444     QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool)));
445     QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool)));
446     QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool)));
447
448     // First, walk the focus from item-a1 down to item-a2 and back again
449     itemA1->forceActiveFocus();
450     QVERIFY(itemA1->hasActiveFocus());
451     QVERIFY(!rootObject->hasActiveFocus());
452     QCOMPARE(rootSpy.count(), 0);
453     QCOMPARE(scopeSpy.count(), 1);
454
455     scopeA->forceActiveFocus();
456     QVERIFY(!itemA1->hasActiveFocus());
457     QVERIFY(scopeA->hasActiveFocus());
458     QCOMPARE(scopeASpy.count(), 1);
459     QCOMPARE(rootSpy.count(), 0);
460     QCOMPARE(scopeSpy.count(), 1);
461
462     itemA2->forceActiveFocus();
463     QVERIFY(!itemA1->hasActiveFocus());
464     QVERIFY(itemA2->hasActiveFocus());
465     QVERIFY(scopeA->hasActiveFocus());
466     QCOMPARE(scopeASpy.count(), 1);
467     QCOMPARE(rootSpy.count(), 0);
468     QCOMPARE(scopeSpy.count(), 1);
469
470     scopeA->forceActiveFocus();
471     QVERIFY(!itemA1->hasActiveFocus());
472     QVERIFY(itemA2->hasActiveFocus());
473     QVERIFY(scopeA->hasActiveFocus());
474     QCOMPARE(scopeASpy.count(), 1);
475     QCOMPARE(rootSpy.count(), 0);
476     QCOMPARE(scopeSpy.count(), 1);
477
478     itemA1->forceActiveFocus();
479     QVERIFY(itemA1->hasActiveFocus());
480     QVERIFY(!scopeA->hasActiveFocus());
481     QVERIFY(!itemA2->hasActiveFocus());
482     QCOMPARE(scopeASpy.count(), 2);
483     QCOMPARE(rootSpy.count(), 0);
484     QCOMPARE(scopeSpy.count(), 1);
485
486     // Then jump back and forth between branch 'a' and 'b'
487     itemB1->forceActiveFocus();
488     QVERIFY(itemB1->hasActiveFocus());
489     QCOMPARE(rootSpy.count(), 0);
490     QCOMPARE(scopeSpy.count(), 1);
491
492     scopeA->forceActiveFocus();
493     QVERIFY(!itemA1->hasActiveFocus());
494     QVERIFY(!itemB1->hasActiveFocus());
495     QVERIFY(scopeA->hasActiveFocus());
496     QCOMPARE(scopeASpy.count(), 3);
497     QCOMPARE(rootSpy.count(), 0);
498     QCOMPARE(scopeSpy.count(), 1);
499
500     scopeB->forceActiveFocus();
501     QVERIFY(!scopeA->hasActiveFocus());
502     QVERIFY(!itemB1->hasActiveFocus());
503     QVERIFY(scopeB->hasActiveFocus());
504     QCOMPARE(scopeASpy.count(), 4);
505     QCOMPARE(scopeBSpy.count(), 1);
506     QCOMPARE(rootSpy.count(), 0);
507     QCOMPARE(scopeSpy.count(), 1);
508
509     itemA2->forceActiveFocus();
510     QVERIFY(!scopeB->hasActiveFocus());
511     QVERIFY(itemA2->hasActiveFocus());
512     QCOMPARE(scopeASpy.count(), 5);
513     QCOMPARE(scopeBSpy.count(), 2);
514     QCOMPARE(rootSpy.count(), 0);
515     QCOMPARE(scopeSpy.count(), 1);
516
517     itemB2->forceActiveFocus();
518     QVERIFY(!itemA2->hasActiveFocus());
519     QVERIFY(itemB2->hasActiveFocus());
520     QCOMPARE(scopeASpy.count(), 6);
521     QCOMPARE(scopeBSpy.count(), 3);
522     QCOMPARE(rootSpy.count(), 0);
523     QCOMPARE(scopeSpy.count(), 1);
524
525     delete view;
526 }
527
528 void tst_qquickfocusscope::canvasFocus()
529 {
530     QQuickView *view = new QQuickView;
531     view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml")));
532
533     QQuickView alternateView;
534
535     QQuickItem *rootObject = view->rootObject();
536     QVERIFY(rootObject);
537
538     QQuickItem *rootItem = view->rootItem();
539     QQuickItem *scope1 = findItem<QQuickItem>(rootObject, QLatin1String("scope1"));
540     QQuickItem *item1 = findItem<QQuickItem>(rootObject, QLatin1String("item1"));
541     QQuickItem *scope2 = findItem<QQuickItem>(rootObject, QLatin1String("scope2"));
542     QQuickItem *item2 = findItem<QQuickItem>(rootObject, QLatin1String("item2"));
543
544     QVERIFY(scope1);
545     QVERIFY(item1);
546     QVERIFY(scope2);
547     QVERIFY(item2);
548
549     QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool)));
550     QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool)));
551     QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool)));
552     QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool)));
553     QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool)));
554     QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool)));
555     QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool)));
556     QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool)));
557     QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool)));
558     QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool)));
559
560     QEXPECT_FAIL("", "QTBUG-22415", Abort);
561     QCOMPARE(rootItem->hasFocus(), false);
562     QCOMPARE(rootItem->hasActiveFocus(), false);
563     QCOMPARE(scope1->hasFocus(), true);
564     QCOMPARE(scope1->hasActiveFocus(), false);
565     QCOMPARE(item1->hasFocus(), true);
566     QCOMPARE(item1->hasActiveFocus(), false);
567     QCOMPARE(scope2->hasFocus(), false);
568     QCOMPARE(scope2->hasActiveFocus(), false);
569     QCOMPARE(item2->hasFocus(), false);
570     QCOMPARE(item2->hasActiveFocus(), false);
571
572     view->show();
573     view->requestActivateWindow();
574
575     QTest::qWaitForWindowShown(view);
576     QTRY_VERIFY(view == qGuiApp->focusWindow());
577
578     // Now the canvas has focus, active focus given to item1
579     QCOMPARE(rootItem->hasFocus(), true);
580     QCOMPARE(rootItem->hasActiveFocus(), true);
581     QCOMPARE(scope1->hasFocus(), true);
582     QCOMPARE(scope1->hasActiveFocus(), true);
583     QCOMPARE(item1->hasFocus(), true);
584     QCOMPARE(item1->hasActiveFocus(), true);
585     QCOMPARE(scope2->hasFocus(), false);
586     QCOMPARE(scope2->hasActiveFocus(), false);
587     QCOMPARE(item2->hasFocus(), false);
588     QCOMPARE(item2->hasActiveFocus(), false);
589
590     QCOMPARE(rootFocusSpy.count(), 1);
591     QCOMPARE(rootActiveFocusSpy.count(), 1);
592     QCOMPARE(scope1FocusSpy.count(), 0);
593     QCOMPARE(scope1ActiveFocusSpy.count(), 1);
594     QCOMPARE(item1FocusSpy.count(), 0);
595     QCOMPARE(item1ActiveFocusSpy.count(), 1);
596
597
598     //    view->hide(); // seemingly doesn't remove focus, so have an another view steal it.
599     alternateView.show();
600     alternateView.requestActivateWindow();
601     QTest::qWaitForWindowShown(&alternateView);
602     QTRY_VERIFY(QGuiApplication::focusWindow() == &alternateView);
603
604     QCOMPARE(rootItem->hasFocus(), false);
605     QCOMPARE(rootItem->hasActiveFocus(), false);
606     QCOMPARE(scope1->hasFocus(), true);
607     QCOMPARE(scope1->hasActiveFocus(), false);
608     QCOMPARE(item1->hasFocus(), true);
609     QCOMPARE(item1->hasActiveFocus(), false);
610
611     QCOMPARE(rootFocusSpy.count(), 2);
612     QCOMPARE(rootActiveFocusSpy.count(), 2);
613     QCOMPARE(scope1FocusSpy.count(), 0);
614     QCOMPARE(scope1ActiveFocusSpy.count(), 2);
615     QCOMPARE(item1FocusSpy.count(), 0);
616     QCOMPARE(item1ActiveFocusSpy.count(), 2);
617
618
619     // canvas does not have focus, so item2 will not get active focus
620     item2->forceActiveFocus();
621
622     QCOMPARE(rootItem->hasFocus(), false);
623     QCOMPARE(rootItem->hasActiveFocus(), false);
624     QCOMPARE(scope1->hasFocus(), false);
625     QCOMPARE(scope1->hasActiveFocus(), false);
626     QCOMPARE(item1->hasFocus(), true);
627     QCOMPARE(item1->hasActiveFocus(), false);
628     QCOMPARE(scope2->hasFocus(), true);
629     QCOMPARE(scope2->hasActiveFocus(), false);
630     QCOMPARE(item2->hasFocus(), true);
631     QCOMPARE(item2->hasActiveFocus(), false);
632
633     QCOMPARE(rootFocusSpy.count(), 2);
634     QCOMPARE(rootActiveFocusSpy.count(), 2);
635     QCOMPARE(scope1FocusSpy.count(), 1);
636     QCOMPARE(scope1ActiveFocusSpy.count(), 2);
637     QCOMPARE(item1FocusSpy.count(), 0);
638     QCOMPARE(item1ActiveFocusSpy.count(), 2);
639     QCOMPARE(scope2FocusSpy.count(), 1);
640     QCOMPARE(scope2ActiveFocusSpy.count(), 0);
641     QCOMPARE(item2FocusSpy.count(), 1);
642     QCOMPARE(item2ActiveFocusSpy.count(), 0);
643
644     // give the canvas focus, and item2 will get active focus
645     view->show();
646     view->requestActivateWindow();
647     QTest::qWaitForWindowShown(view);
648     QTRY_VERIFY(QGuiApplication::focusWindow() == view);
649
650     QCOMPARE(rootItem->hasFocus(), true);
651     QCOMPARE(rootItem->hasActiveFocus(), true);
652     QCOMPARE(scope2->hasFocus(), true);
653     QCOMPARE(scope2->hasActiveFocus(), true);
654     QCOMPARE(item2->hasFocus(), true);
655     QCOMPARE(item2->hasActiveFocus(), true);
656     QCOMPARE(rootFocusSpy.count(), 3);
657     QCOMPARE(rootActiveFocusSpy.count(), 3);
658     QCOMPARE(scope2FocusSpy.count(), 1);
659     QCOMPARE(scope2ActiveFocusSpy.count(), 1);
660     QCOMPARE(item2FocusSpy.count(), 1);
661     QCOMPARE(item2ActiveFocusSpy.count(), 1);
662
663     delete view;
664 }
665
666 QTEST_MAIN(tst_qquickfocusscope)
667
668 #include "tst_qquickfocusscope.moc"