diff options
Diffstat (limited to 'tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp')
-rw-r--r-- | tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp | 668 |
1 files changed, 668 insertions, 0 deletions
diff --git a/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp b/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp new file mode 100644 index 0000000000..11cc7a15e0 --- /dev/null +++ b/tests/auto/qtquick2/qquickfocusscope/tst_qquickfocusscope.cpp @@ -0,0 +1,668 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include <qtest.h> +#include <QSignalSpy> +#include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativecomponent.h> +#include <QtQuick/qquickview.h> +#include <QtQuick/private/qquickrectangle_p.h> +#include <private/qquicktextedit_p.h> +#include <QtQuick/private/qquicktext_p.h> +#include <QtQuick/private/qquickfocusscope_p.h> +#include "../../shared/util.h" + +class tst_qquickfocusscope : public QObject +{ + Q_OBJECT +public: + tst_qquickfocusscope() {} + + template<typename T> + T *findItem(QQuickItem *parent, const QString &id); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void basic(); + void nested(); + void noFocus(); + void textEdit(); + void forceFocus(); + void noParentFocus(); + void signalEmission(); + void qtBug13380(); + void forceActiveFocus(); + void canvasFocus(); +}; +void tst_qquickfocusscope::initTestCase() +{ +} + +void tst_qquickfocusscope::cleanupTestCase() +{ + +} + +/* + Find an item with the specified id. +*/ +template<typename T> +T *tst_qquickfocusscope::findItem(QQuickItem *parent, const QString &objectName) +{ + const QMetaObject &mo = T::staticMetaObject; + QList<QQuickItem *> children = parent->childItems(); + for (int i = 0; i < children.count(); ++i) { + QQuickItem *item = children.at(i); + if (item) { + if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) { + return static_cast<T*>(item); + } + item = findItem<T>(item, objectName); + if (item) + return static_cast<T*>(item); + } + } + return 0; +} + +void tst_qquickfocusscope::basic() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test.qml"))); + + QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(view->isTopLevel()); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QTest::qWait(50); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QTest::qWait(50); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::nested() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test2.qml"))); + + QQuickFocusScope *item1 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item1")); + QQuickFocusScope *item2 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item2")); + QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3")); + QQuickFocusScope *item4 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item4")); + QQuickFocusScope *item5 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item5")); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + QVERIFY(item5 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(item4->hasActiveFocus() == true); + QVERIFY(item5->hasActiveFocus() == true); + delete view; +} + +void tst_qquickfocusscope::noFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test4.qml"))); + + QQuickRectangle *item0 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + delete view; +} + +void tst_qquickfocusscope::textEdit() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("test5.qml"))); + + QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0")); + QQuickTextEdit *item1 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2")); + QQuickTextEdit *item3 = findItem<QQuickTextEdit>(view->rootObject(), QLatin1String("item3")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + + QTRY_VERIFY(view == qGuiApp->focusWindow()); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QTest::keyClick(view, Qt::Key_Right); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == true); + QVERIFY(item3->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_Down); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::forceFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("forcefocus.qml"))); + + QQuickFocusScope *item0 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item0")); + QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2")); + QQuickFocusScope *item3 = findItem<QQuickFocusScope>(view->rootObject(), QLatin1String("item3")); + QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4")); + QQuickRectangle *item5 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item5")); + QVERIFY(item0 != 0); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + QVERIFY(item5 != 0); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_4); + QVERIFY(item0->hasActiveFocus() == true); + QVERIFY(item1->hasActiveFocus() == true); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == false); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == false); + + QTest::keyClick(view, Qt::Key_5); + QVERIFY(item0->hasActiveFocus() == false); + QVERIFY(item1->hasActiveFocus() == false); + QVERIFY(item2->hasActiveFocus() == false); + QVERIFY(item3->hasActiveFocus() == true); + QVERIFY(item4->hasActiveFocus() == false); + QVERIFY(item5->hasActiveFocus() == true); + + delete view; +} + +void tst_qquickfocusscope::noParentFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("chain.qml"))); + QVERIFY(view->rootObject()); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVERIFY(view->rootObject()->property("focus1") == false); + QVERIFY(view->rootObject()->property("focus2") == false); + QVERIFY(view->rootObject()->property("focus3") == true); + QVERIFY(view->rootObject()->property("focus4") == true); + QVERIFY(view->rootObject()->property("focus5") == true); + + delete view; +} + +void tst_qquickfocusscope::signalEmission() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("signalEmission.qml"))); + + QQuickRectangle *item1 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item1")); + QQuickRectangle *item2 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item2")); + QQuickRectangle *item3 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item3")); + QQuickRectangle *item4 = findItem<QQuickRectangle>(view->rootObject(), QLatin1String("item4")); + QVERIFY(item1 != 0); + QVERIFY(item2 != 0); + QVERIFY(item3 != 0); + QVERIFY(item4 != 0); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QVariant blue(QColor("blue")); + QVariant red(QColor("red")); + + item1->setFocus(true); + QCOMPARE(item1->property("color"), red); + QCOMPARE(item2->property("color"), blue); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + item2->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + item3->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), red); + QCOMPARE(item4->property("color"), blue); + + item4->setFocus(true); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), red); + + item4->setFocus(false); + QCOMPARE(item1->property("color"), blue); + QCOMPARE(item2->property("color"), red); + QCOMPARE(item3->property("color"), blue); + QCOMPARE(item4->property("color"), blue); + + delete view; +} + +void tst_qquickfocusscope::qtBug13380() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("qtBug13380.qml"))); + + view->show(); + QVERIFY(view->rootObject()); + view->requestActivateWindow(); + qApp->processEvents(); + + QTest::qWaitForWindowShown(view); + + QTRY_VERIFY(view == qGuiApp->focusWindow()); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + view->rootObject()->setProperty("showRect", true); + QVERIFY(view->rootObject()->property("noFocus").toBool()); + + delete view; +} + +void tst_qquickfocusscope::forceActiveFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("forceActiveFocus.qml"))); + + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + QQuickItem *rootObject = view->rootObject(); + QVERIFY(rootObject); + + QQuickItem *scope = findItem<QQuickItem>(rootObject, QLatin1String("scope")); + QQuickItem *itemA1 = findItem<QQuickItem>(rootObject, QLatin1String("item-a1")); + QQuickItem *scopeA = findItem<QQuickItem>(rootObject, QLatin1String("scope-a")); + QQuickItem *itemA2 = findItem<QQuickItem>(rootObject, QLatin1String("item-a2")); + QQuickItem *itemB1 = findItem<QQuickItem>(rootObject, QLatin1String("item-b1")); + QQuickItem *scopeB = findItem<QQuickItem>(rootObject, QLatin1String("scope-b")); + QQuickItem *itemB2 = findItem<QQuickItem>(rootObject, QLatin1String("item-b2")); + + QVERIFY(scope); + QVERIFY(itemA1); + QVERIFY(scopeA); + QVERIFY(itemA2); + QVERIFY(itemB1); + QVERIFY(scopeB); + QVERIFY(itemB2); + + QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scopeBSpy(scopeB, SIGNAL(activeFocusChanged(bool))); + + // First, walk the focus from item-a1 down to item-a2 and back again + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QVERIFY(!rootObject->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA1->forceActiveFocus(); + QVERIFY(itemA1->hasActiveFocus()); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 2); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + // Then jump back and forth between branch 'a' and 'b' + itemB1->forceActiveFocus(); + QVERIFY(itemB1->hasActiveFocus()); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeA->forceActiveFocus(); + QVERIFY(!itemA1->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeA->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 3); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + scopeB->forceActiveFocus(); + QVERIFY(!scopeA->hasActiveFocus()); + QVERIFY(!itemB1->hasActiveFocus()); + QVERIFY(scopeB->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 4); + QCOMPARE(scopeBSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemA2->forceActiveFocus(); + QVERIFY(!scopeB->hasActiveFocus()); + QVERIFY(itemA2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 5); + QCOMPARE(scopeBSpy.count(), 2); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + itemB2->forceActiveFocus(); + QVERIFY(!itemA2->hasActiveFocus()); + QVERIFY(itemB2->hasActiveFocus()); + QCOMPARE(scopeASpy.count(), 6); + QCOMPARE(scopeBSpy.count(), 3); + QCOMPARE(rootSpy.count(), 0); + QCOMPARE(scopeSpy.count(), 1); + + delete view; +} + +void tst_qquickfocusscope::canvasFocus() +{ + QQuickView *view = new QQuickView; + view->setSource(QUrl::fromLocalFile(TESTDATA("canvasFocus.qml"))); + + QQuickView alternateView; + + QQuickItem *rootObject = view->rootObject(); + QVERIFY(rootObject); + + QQuickItem *rootItem = view->rootItem(); + QQuickItem *scope1 = findItem<QQuickItem>(rootObject, QLatin1String("scope1")); + QQuickItem *item1 = findItem<QQuickItem>(rootObject, QLatin1String("item1")); + QQuickItem *scope2 = findItem<QQuickItem>(rootObject, QLatin1String("scope2")); + QQuickItem *item2 = findItem<QQuickItem>(rootObject, QLatin1String("item2")); + + QVERIFY(scope1); + QVERIFY(item1); + QVERIFY(scope2); + QVERIFY(item2); + + QSignalSpy rootFocusSpy(rootItem, SIGNAL(focusChanged(bool))); + QSignalSpy scope1FocusSpy(scope1, SIGNAL(focusChanged(bool))); + QSignalSpy item1FocusSpy(item1, SIGNAL(focusChanged(bool))); + QSignalSpy scope2FocusSpy(scope2, SIGNAL(focusChanged(bool))); + QSignalSpy item2FocusSpy(item2, SIGNAL(focusChanged(bool))); + QSignalSpy rootActiveFocusSpy(rootItem, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scope1ActiveFocusSpy(scope1, SIGNAL(activeFocusChanged(bool))); + QSignalSpy item1ActiveFocusSpy(item1, SIGNAL(activeFocusChanged(bool))); + QSignalSpy scope2ActiveFocusSpy(scope2, SIGNAL(activeFocusChanged(bool))); + QSignalSpy item2ActiveFocusSpy(item2, SIGNAL(activeFocusChanged(bool))); + + QEXPECT_FAIL("", "QTBUG-22415", Abort); + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + QCOMPARE(scope2->hasFocus(), false); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), false); + QCOMPARE(item2->hasActiveFocus(), false); + + view->show(); + view->requestActivateWindow(); + + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(view == qGuiApp->focusWindow()); + + // Now the canvas has focus, active focus given to item1 + QCOMPARE(rootItem->hasFocus(), true); + QCOMPARE(rootItem->hasActiveFocus(), true); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), true); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), true); + QCOMPARE(scope2->hasFocus(), false); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), false); + QCOMPARE(item2->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 1); + QCOMPARE(rootActiveFocusSpy.count(), 1); + QCOMPARE(scope1FocusSpy.count(), 0); + QCOMPARE(scope1ActiveFocusSpy.count(), 1); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 1); + + + // view->hide(); // seemingly doesn't remove focus, so have an another view steal it. + alternateView.show(); + alternateView.requestActivateWindow(); + QTest::qWaitForWindowShown(&alternateView); + QTRY_VERIFY(QGuiApplication::focusWindow() == &alternateView); + + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), true); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 2); + QCOMPARE(rootActiveFocusSpy.count(), 2); + QCOMPARE(scope1FocusSpy.count(), 0); + QCOMPARE(scope1ActiveFocusSpy.count(), 2); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 2); + + + // canvas does not have focus, so item2 will not get active focus + item2->forceActiveFocus(); + + QCOMPARE(rootItem->hasFocus(), false); + QCOMPARE(rootItem->hasActiveFocus(), false); + QCOMPARE(scope1->hasFocus(), false); + QCOMPARE(scope1->hasActiveFocus(), false); + QCOMPARE(item1->hasFocus(), true); + QCOMPARE(item1->hasActiveFocus(), false); + QCOMPARE(scope2->hasFocus(), true); + QCOMPARE(scope2->hasActiveFocus(), false); + QCOMPARE(item2->hasFocus(), true); + QCOMPARE(item2->hasActiveFocus(), false); + + QCOMPARE(rootFocusSpy.count(), 2); + QCOMPARE(rootActiveFocusSpy.count(), 2); + QCOMPARE(scope1FocusSpy.count(), 1); + QCOMPARE(scope1ActiveFocusSpy.count(), 2); + QCOMPARE(item1FocusSpy.count(), 0); + QCOMPARE(item1ActiveFocusSpy.count(), 2); + QCOMPARE(scope2FocusSpy.count(), 1); + QCOMPARE(scope2ActiveFocusSpy.count(), 0); + QCOMPARE(item2FocusSpy.count(), 1); + QCOMPARE(item2ActiveFocusSpy.count(), 0); + + // give the canvas focus, and item2 will get active focus + view->show(); + view->requestActivateWindow(); + QTest::qWaitForWindowShown(view); + QTRY_VERIFY(QGuiApplication::focusWindow() == view); + + QCOMPARE(rootItem->hasFocus(), true); + QCOMPARE(rootItem->hasActiveFocus(), true); + QCOMPARE(scope2->hasFocus(), true); + QCOMPARE(scope2->hasActiveFocus(), true); + QCOMPARE(item2->hasFocus(), true); + QCOMPARE(item2->hasActiveFocus(), true); + QCOMPARE(rootFocusSpy.count(), 3); + QCOMPARE(rootActiveFocusSpy.count(), 3); + QCOMPARE(scope2FocusSpy.count(), 1); + QCOMPARE(scope2ActiveFocusSpy.count(), 1); + QCOMPARE(item2FocusSpy.count(), 1); + QCOMPARE(item2ActiveFocusSpy.count(), 1); + + delete view; +} + +QTEST_MAIN(tst_qquickfocusscope) + +#include "tst_qquickfocusscope.moc" |