diff options
author | Andrew den Exter <andrew.den.exter@jollamobile.com> | 2013-02-25 17:01:16 +1000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-02-27 01:35:58 +0100 |
commit | c520a69f06317fb90d37324bf284ef9614cb5dbf (patch) | |
tree | 5dfddec914698dd0630bb50d73b92f3c1e94d902 /tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp | |
parent | e8ca72d484c0e56f030e4742bb5f92b6f0555146 (diff) |
Improve emission of FocusScope focusChanged signals.
Emit activeFocusChanged up the focus tree when an item receives a focus
event, rather than when the focusItem changes which happens before
internal state is sufficiently updated for hasFocus and hasActiveFocus
to return the correct values from within a changed signal handler.
There are some limitions to this. First the signals are not emitted
reliably when the scene is not active which makes sense for activeFocus
but not for focus. The second is in some instances the focus and
activeFocus can update unnecessarily while the focus chain sorts itself
out.
QDeclarativeItem tests by Andreas Aardal Hanssen <andreas@hanssen.name>
Task-number: QTBUG-28288
Task-number: QTBUG-25644
Change-Id: Ib3d17c42754c15a08b34c3388f50b45cc1d2a831
Reviewed-by: Andreas Aardal Hanssen <andreas@hanssen.name>
Reviewed-by: Alan Alpert <aalpert@rim.com>
Diffstat (limited to 'tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp')
-rw-r--r-- | tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp | 293 |
1 files changed, 282 insertions, 11 deletions
diff --git a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp index 64c8d210..f7099ba2 100644 --- a/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp +++ b/tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp @@ -68,6 +68,10 @@ private slots: void signalEmission(); void qtBug13380(); void forceActiveFocus(); + void notifications(); + void notifications_data(); + void notificationsInScope(); + void notificationsInScope_data(); }; /* @@ -396,8 +400,11 @@ void tst_qdeclarativefocusscope::forceActiveFocus() { QDeclarativeView *view = new QDeclarativeView; view->setSource(QUrl::fromLocalFile(SRCDIR "/data/forceActiveFocus.qml")); + view->show(); + view->activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(view)); - QGraphicsObject *rootObject = view->rootObject(); + QDeclarativeItem *rootObject = qobject_cast<QDeclarativeItem *>(view->rootObject()); QVERIFY(rootObject); QDeclarativeItem *scope = findItem<QDeclarativeItem>(rootObject, QLatin1String("scope")); @@ -416,6 +423,11 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(scopeB); QVERIFY(itemB2); + QCOMPARE(rootObject->hasActiveFocus(), false); + QCOMPARE(scope->hasActiveFocus(), false); + QCOMPARE(scopeA->hasActiveFocus(), false); + QCOMPARE(scopeB->hasActiveFocus(), false); + QSignalSpy rootSpy(rootObject, SIGNAL(activeFocusChanged(bool))); QSignalSpy scopeSpy(scope, SIGNAL(activeFocusChanged(bool))); QSignalSpy scopeASpy(scopeA, SIGNAL(activeFocusChanged(bool))); @@ -424,22 +436,34 @@ void tst_qdeclarativefocusscope::forceActiveFocus() // First, walk the focus from item-a1 down to item-a2 and back again itemA1->forceActiveFocus(); QVERIFY(itemA1->hasActiveFocus()); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); scopeA->forceActiveFocus(); QVERIFY(!itemA1->hasActiveFocus()); QVERIFY(scopeA->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); itemA2->forceActiveFocus(); QVERIFY(!itemA1->hasActiveFocus()); QVERIFY(itemA2->hasActiveFocus()); QVERIFY(scopeA->hasActiveFocus()); + if (scopeASpy.count() == 3) { + qWarning() << "ignoring spurious changed signals"; + QCOMPARE(scopeASpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeASpy.takeFirst().first().toBool(), false); + QCOMPARE(scopeASpy.first().first().toBool(), true); + } QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); + if (scopeSpy.count() == 3) { + qWarning() << "ignoring spurious changed signals"; + QCOMPARE(scopeSpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeSpy.takeFirst().first().toBool(), false); + QCOMPARE(scopeSpy.first().first().toBool(), true); + } QCOMPARE(scopeSpy.count(), 1); scopeA->forceActiveFocus(); @@ -447,7 +471,7 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(itemA2->hasActiveFocus()); QVERIFY(scopeA->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 1); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); itemA1->forceActiveFocus(); @@ -455,13 +479,13 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(!scopeA->hasActiveFocus()); QVERIFY(!itemA2->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 2); - QCOMPARE(rootSpy.count(), 1); + 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(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); scopeA->forceActiveFocus(); @@ -469,7 +493,7 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(!itemB1->hasActiveFocus()); QVERIFY(scopeA->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 3); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); scopeB->forceActiveFocus(); @@ -478,7 +502,7 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(scopeB->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 4); QCOMPARE(scopeBSpy.count(), 1); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); itemA2->forceActiveFocus(); @@ -486,7 +510,7 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(itemA2->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 5); QCOMPARE(scopeBSpy.count(), 2); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); itemB2->forceActiveFocus(); @@ -494,12 +518,259 @@ void tst_qdeclarativefocusscope::forceActiveFocus() QVERIFY(itemB2->hasActiveFocus()); QCOMPARE(scopeASpy.count(), 6); QCOMPARE(scopeBSpy.count(), 3); - QCOMPARE(rootSpy.count(), 1); + QCOMPARE(rootSpy.count(), 0); QCOMPARE(scopeSpy.count(), 1); delete view; } + +void tst_qdeclarativefocusscope::notifications_data() +{ + QTest::addColumn<QString>("objectName"); + + QTest::newRow("rootItem") << ""; + QTest::newRow("item1") << "item1"; + QTest::newRow("item3") << "item3"; + QTest::newRow("focusScope") << "scope1"; +} + +void tst_qdeclarativefocusscope::notifications() +{ + QFETCH(QString, objectName); + QDeclarativeView canvas; + canvas.setSource(QUrl::fromLocalFile(SRCDIR "/data/notifications.qml")); + canvas.show(); + canvas.activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(&canvas)); + + QGraphicsScene *scene = canvas.scene(); + + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(canvas.rootObject()); + QVERIFY(item); + + item = objectName.isEmpty() ? item : item->findChild<QDeclarativeItem *>(objectName); + QVERIFY(item); + + QSignalSpy focusSpy(item, SIGNAL(focusChanged(bool))); + QSignalSpy activeFocusSpy(item, SIGNAL(activeFocusChanged(bool))); + + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + + item->setFocus(true); + + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), true); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), true); + + item->setFocus(false); + + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), false); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + + item->QGraphicsItem::setFocus(); + + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), true); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), true); + + item->clearFocus(); + + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), false); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + + scene->setFocusItem(item); + + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), true); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), true); + + scene->setFocusItem(0); + + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(focusSpy.count(), 1); + QCOMPARE(activeFocusSpy.count(), 1); + QCOMPARE(focusSpy.takeFirst().first().toBool(), false); + QCOMPARE(activeFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); +} + +void tst_qdeclarativefocusscope::notificationsInScope_data() +{ + QTest::addColumn<QString>("itemName"); + QTest::addColumn<QString>("scopeName"); + + QTest::newRow("item4") << "item4" << "scope1"; + QTest::newRow("item5") << "item5" << "scope2"; +} + +void tst_qdeclarativefocusscope::notificationsInScope() +{ + QFETCH(QString, itemName); + QFETCH(QString, scopeName); + QDeclarativeView canvas; + canvas.setSource(QUrl::fromLocalFile(SRCDIR "/data/notifications.qml")); + canvas.show(); + canvas.activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(&canvas)); + + QVERIFY(canvas.rootObject()); + + QDeclarativeItem *scope = canvas.rootObject()->findChild<QDeclarativeItem *>(scopeName); + QVERIFY(scope); + + QDeclarativeItem *item = scope->findChild<QDeclarativeItem *>(itemName); + QVERIFY(item); + + QSignalSpy itemFocusSpy(item, SIGNAL(focusChanged(bool))); + QSignalSpy itemActiveFocusSpy(item, SIGNAL(activeFocusChanged(bool))); + + QSignalSpy scopeFocusSpy(scope, SIGNAL(focusChanged(bool))); + QSignalSpy scopeActiveFocusSpy(scope, SIGNAL(activeFocusChanged(bool))); + + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scope->hasActiveFocus(), false); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), false); + + item->setFocus(true); + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scope->hasActiveFocus(), false); + QCOMPARE(itemFocusSpy.count(), 1); + QCOMPARE(itemFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(itemActiveFocusSpy.count(), 0); + QCOMPARE(scopeFocusSpy.count(), 0); + QCOMPARE(scopeActiveFocusSpy.count(), 0); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), false); + + item->setFocus(false); + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scope->hasActiveFocus(), false); + QCOMPARE(itemFocusSpy.count(), 1); + QCOMPARE(itemFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(itemActiveFocusSpy.count(), 0); + QCOMPARE(scopeFocusSpy.count(), 0); + QCOMPARE(scopeActiveFocusSpy.count(), 0); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), false); + + item->forceActiveFocus(); + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(scope->hasFocus(), true); + QCOMPARE(scope->hasActiveFocus(), true); + QCOMPARE(itemFocusSpy.count(), 1); + QCOMPARE(itemFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(itemActiveFocusSpy.count(), 1); + QCOMPARE(itemActiveFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeFocusSpy.count(), 1); + QCOMPARE(scopeFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeActiveFocusSpy.count(), 1); + QCOMPARE(scopeActiveFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), true); + QCOMPARE(scope->property("handlerFocus").value<bool>(), true); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), true); + + scope->setFocus(false); + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(scope->hasFocus(), false); + QCOMPARE(scope->hasActiveFocus(), false); + QCOMPARE(itemFocusSpy.count(), 0); + QCOMPARE(itemActiveFocusSpy.count(), 1); + QCOMPARE(itemActiveFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(scopeFocusSpy.count(), 1); + QCOMPARE(scopeFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(scopeActiveFocusSpy.count(), 1); + QCOMPARE(scopeActiveFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), false); + + scope->setFocus(true); + QCOMPARE(item->hasFocus(), true); + QCOMPARE(item->hasActiveFocus(), true); + QCOMPARE(scope->hasFocus(), true); + QCOMPARE(scope->hasActiveFocus(), true); + QCOMPARE(itemFocusSpy.count(), 0); + QCOMPARE(itemActiveFocusSpy.count(), 1); + QCOMPARE(itemActiveFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeFocusSpy.count(), 1); + QCOMPARE(scopeFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(scopeActiveFocusSpy.count(), 1); + QCOMPARE(scopeActiveFocusSpy.takeFirst().first().toBool(), true); + QCOMPARE(item->property("handlerFocus").value<bool>(), true); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), true); + QCOMPARE(scope->property("handlerFocus").value<bool>(), true); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), true); + + item->setFocus(false); + QCOMPARE(item->hasFocus(), false); + QCOMPARE(item->hasActiveFocus(), false); + QCOMPARE(scope->hasFocus(), true); + QCOMPARE(scope->hasActiveFocus(), true); + QCOMPARE(itemFocusSpy.count(), 1); + QCOMPARE(itemFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(itemActiveFocusSpy.count(), 1); + QCOMPARE(itemActiveFocusSpy.takeFirst().first().toBool(), false); + if (scopeFocusSpy.count() == 2) { + qWarning() << "ignoring spurious changed signals"; + QCOMPARE(scopeFocusSpy.takeFirst().first().toBool(), false); + QCOMPARE(scopeFocusSpy.takeFirst().first().toBool(), true); + } + QCOMPARE(scopeFocusSpy.count(), 0); + QCOMPARE(scopeActiveFocusSpy.count(), 0); + QCOMPARE(item->property("handlerFocus").value<bool>(), false); + QCOMPARE(item->property("handlerActiveFocus").value<bool>(), false); + QCOMPARE(scope->property("handlerFocus").value<bool>(), true); + QCOMPARE(scope->property("handlerActiveFocus").value<bool>(), true); +} + QTEST_MAIN(tst_qdeclarativefocusscope) #include "tst_qdeclarativefocusscope.moc" |