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