summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp24
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem_p.h23
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/data/notifications.qml81
-rw-r--r--tests/auto/declarative/qdeclarativefocusscope/tst_qdeclarativefocusscope.cpp293
-rw-r--r--tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp179
5 files changed, 569 insertions, 31 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 99b3857d..c3bb5d9f 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -2744,9 +2744,27 @@ QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const
void QDeclarativeItemPrivate::focusChanged(bool flag)
{
Q_Q(QDeclarativeItem);
- if (!(flags & QGraphicsItem::ItemIsFocusScope) && parent)
- emit q->activeFocusChanged(flag); //see also QDeclarativeItemPrivate::subFocusItemChange()
- emit q->focusChanged(flag);
+
+ if (hadActiveFocus != flag) {
+ hadActiveFocus = flag;
+ emit q->activeFocusChanged(flag);
+ }
+
+ QDeclarativeItem *focusItem = q;
+ for (QDeclarativeItem *p = q->parentItem(); p; p = p->parentItem()) {
+ if (p->flags() & QGraphicsItem::ItemIsFocusScope) {
+ if (!flag && QGraphicsItemPrivate::get(p)->focusScopeItem != focusItem)
+ break;
+ if (p->d_func()->hadActiveFocus != flag) {
+ p->d_func()->hadActiveFocus = flag;
+ emit p->activeFocusChanged(flag);
+ }
+ focusItem = p;
+ }
+ }
+
+ // For all but the top most focus scope/item this will be called for us by QGraphicsItem.
+ focusItem->d_func()->focusScopeItemChange(flag);
}
QDeclarativeListProperty<QObject> QDeclarativeItemPrivate::resources()
diff --git a/src/declarative/graphicsitems/qdeclarativeitem_p.h b/src/declarative/graphicsitems/qdeclarativeitem_p.h
index 8ef91887..20262307 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeitem_p.h
@@ -128,8 +128,8 @@ public:
componentComplete(true), keepMouse(false),
smooth(false), transformOriginDirty(true), doneEventPreHandler(false),
inheritedLayoutMirror(false), effectiveLayoutMirror(false), isMirrorImplicit(true),
- inheritMirrorFromParent(false), inheritMirrorFromItem(false), keyHandler(0),
- mWidth(0), mHeight(0), mImplicitWidth(0), mImplicitHeight(0), attachedLayoutDirection(0), hadSubFocusItem(false)
+ inheritMirrorFromParent(false), inheritMirrorFromItem(false), hadFocus(false), hadActiveFocus(false), keyHandler(0),
+ mWidth(0), mHeight(0), mImplicitWidth(0), mImplicitHeight(0), attachedLayoutDirection(0)
{
QGraphicsItemPrivate::acceptedMouseButtons = 0;
isDeclarativeItem = 1;
@@ -289,6 +289,8 @@ public:
bool isMirrorImplicit:1;
bool inheritMirrorFromParent:1;
bool inheritMirrorFromItem:1;
+ bool hadFocus:1;
+ bool hadActiveFocus:1;
QDeclarativeItemKeyFilter *keyHandler;
@@ -299,7 +301,6 @@ public:
QDeclarativeLayoutMirroringAttached* attachedLayoutDirection;
- bool hadSubFocusItem;
QPointF computeTransformOrigin() const;
@@ -312,22 +313,14 @@ public:
}
// Reimplemented from QGraphicsItemPrivate
- virtual void subFocusItemChange()
- {
- bool hasSubFocusItem = subFocusItem != 0;
- if (((flags & QGraphicsItem::ItemIsFocusScope) || !parent) && hasSubFocusItem != hadSubFocusItem)
- emit q_func()->activeFocusChanged(hasSubFocusItem);
- //see also QDeclarativeItemPrivate::focusChanged
- hadSubFocusItem = hasSubFocusItem;
- }
-
- // Reimplemented from QGraphicsItemPrivate
virtual void focusScopeItemChange(bool isSubFocusItem)
{
- emit q_func()->focusChanged(isSubFocusItem);
+ if (hadFocus != isSubFocusItem) {
+ hadFocus = isSubFocusItem;
+ emit q_func()->focusChanged(isSubFocusItem);
+ }
}
-
// Reimplemented from QGraphicsItemPrivate
virtual void siblingOrderChange()
{
diff --git a/tests/auto/declarative/qdeclarativefocusscope/data/notifications.qml b/tests/auto/declarative/qdeclarativefocusscope/data/notifications.qml
new file mode 100644
index 00000000..8345972a
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativefocusscope/data/notifications.qml
@@ -0,0 +1,81 @@
+import QtQuick 1.1
+
+Item {
+ objectName: "rootItem"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+
+ Item {
+ objectName: "item1"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+ }
+
+ Item {
+ objectName: "item2"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+
+ Item {
+ objectName: "item3"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+ }
+ }
+
+ FocusScope {
+ objectName: "scope1"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+
+ Item {
+ objectName: "item4"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+ }
+
+ FocusScope {
+ objectName: "scope2"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+
+ Item {
+ objectName: "item5"
+
+ property bool handlerFocus
+ property bool handlerActiveFocus
+
+ onFocusChanged: handlerFocus = focus
+ onActiveFocusChanged: handlerActiveFocus = activeFocus
+ }
+ }
+ }
+}
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"
diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
index 0f61bb7e..0251d74d 100644
--- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
+++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
@@ -86,6 +86,11 @@ private slots:
void qtbug_16871();
void qtbug_21045();
void hasActiveFocusAfterClear();
+ void setAndClearFocusOfItem();
+ void setAndClearFocusScopeFocus();
+ void setFocusThenSetFocusItem0();
+ void setFocusFocusItem0ThenHasActiveFocus();
+
private:
QDeclarativeEngine engine;
};
@@ -1043,6 +1048,7 @@ void tst_QDeclarativeItem::propertyChanges()
QCOMPARE(parentItem->childrenRect(), childrenRectArguments.at(0).toRectF());
QCOMPARE(item->hasActiveFocus(), true);
+ QCOMPARE(item->hasFocus(), true);
QCOMPARE(focusSpy.count(),1);
QList<QVariant> focusArguments = focusSpy.first();
QVERIFY(focusArguments.count() == 1);
@@ -1249,8 +1255,9 @@ void tst_QDeclarativeItem::qtbug_21045()
void tst_QDeclarativeItem::hasActiveFocusAfterClear()
{
QGraphicsScene scene;
- QGraphicsView view(&scene);
- view.show();
+ scene.setFocus();
+ QEvent event(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &event);
QDeclarativeEngine engine;
QDeclarativeComponent qmlComponent(&engine);
@@ -1273,6 +1280,174 @@ void tst_QDeclarativeItem::hasActiveFocusAfterClear()
QVERIFY(!createdItem->hasActiveFocus());
}
+void tst_QDeclarativeItem::setAndClearFocusOfItem()
+{
+ QGraphicsScene scene;
+ scene.setFocus();
+ QEvent event(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &event);
+
+ QDeclarativeEngine engine(&scene);
+ QDeclarativeComponent qmlComponent(&engine);
+ qmlComponent.setData(
+ "import QtQuick 1.1;"
+ "Item { id: root; "
+ "signal focusChangedTo(bool value);"
+ "signal activeFocusChangedTo(bool value);"
+ "onFocusChanged: root.focusChangedTo(focus);"
+ "onActiveFocusChanged: root.activeFocusChangedTo(activeFocus);"
+ "}", QUrl("test"));
+
+ QGraphicsItem *createdItem = qobject_cast<QGraphicsItem*>(qmlComponent.create(engine.rootContext()));
+ QVERIFY(createdItem);
+ scene.addItem(createdItem);
+
+ QSignalSpy focusChangedSpy(createdItem->toGraphicsObject(), SIGNAL(focusChangedTo(bool)));
+ QSignalSpy activeFocusChangedSpy(createdItem->toGraphicsObject(), SIGNAL(activeFocusChangedTo(bool)));
+
+ QVERIFY(!createdItem->hasFocus());
+ createdItem->toGraphicsObject()->setFocus();
+ QCOMPARE(focusChangedSpy.count(), 1);
+ QCOMPARE(activeFocusChangedSpy.count(), 1);
+ QCOMPARE(focusChangedSpy.takeFirst().first().toBool(), true);
+ QCOMPARE(activeFocusChangedSpy.takeFirst().first().toBool(), true);
+
+ createdItem->toGraphicsObject()->clearFocus();
+ QCOMPARE(focusChangedSpy.count(), 1);
+ QCOMPARE(activeFocusChangedSpy.count(), 1);
+ QCOMPARE(focusChangedSpy.takeFirst().first().toBool(), false);
+ QCOMPARE(activeFocusChangedSpy.takeFirst().first().toBool(), false);
+}
+
+void tst_QDeclarativeItem::setAndClearFocusScopeFocus()
+{
+ //graphicsview init
+ QGraphicsScene scene;
+ scene.setFocus();
+ QEvent event(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &event);
+
+ //declarative init
+ QDeclarativeEngine engine(&scene);
+ QDeclarativeComponent qmlComponent(&engine);
+
+ qmlComponent.setData(
+ "\nimport QtQuick 1.1"
+ "\nFocusScope {"
+ "\n id: root"
+ "\n signal listActiveFocusChangedTo(bool value)"
+ "\n signal topRectActiveFocusChangedTo(bool value)"
+ "\n Rectangle {"
+ "\n id: topRect"
+ "\n focus: true"
+ "\n onActiveFocusChanged: root.topRectActiveFocusChangedTo(topRect.activeFocus)"
+ "\n }"
+ "\n FocusScope {"
+ "\n objectName: \"focusScope\""
+ "\n onActiveFocusChanged: root.listActiveFocusChangedTo(activeFocus)"
+ "\n }"
+ "\n Rectangle { objectName: \"bottom\" }"
+ "}", QUrl(""));
+
+ QGraphicsItem *createdItem = qobject_cast<QGraphicsItem*>(qmlComponent.create(engine.rootContext()));
+ QVERIFY(createdItem);
+ scene.addItem(createdItem);
+
+ QDeclarativeItem *focusScope = createdItem->toGraphicsObject()->findChild<QDeclarativeItem*>("focusScope");
+ QDeclarativeItem *bottomRect = createdItem->toGraphicsObject()->findChild<QDeclarativeItem*>("bottom");
+
+ QSignalSpy focusScopeSpy(createdItem->toGraphicsObject(), SIGNAL(listActiveFocusChangedTo(bool)));
+ QSignalSpy topRectFocusSpy(createdItem->toGraphicsObject(), SIGNAL(topRectActiveFocusChangedTo(bool)));
+
+ //#1: root gets activefocus, and in turn the top rectangle
+ createdItem->setFocus();
+
+ //#2
+ focusScope->setFocus(true);
+
+ //#3
+ bottomRect->setFocus(true);
+
+ QCOMPARE(topRectFocusSpy.count(), 2);
+ QCOMPARE(focusScopeSpy.count(), 2);
+
+ QCOMPARE(topRectFocusSpy.takeFirst().first().toBool(), true); //from #1
+ QCOMPARE(topRectFocusSpy.takeFirst().first().toBool(), false); //from #2
+
+ QCOMPARE(focusScopeSpy.takeFirst().first().toBool(), true); //from #2
+ QCOMPARE(focusScopeSpy.takeFirst().first().toBool(), false); //from #3
+}
+
+void tst_QDeclarativeItem::setFocusThenSetFocusItem0()
+{
+ //graphicsview init
+ QGraphicsScene scene;
+ scene.setFocus();
+ QEvent event(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &event);
+
+ //declarative init
+ QDeclarativeEngine engine(&scene);
+ QDeclarativeComponent qmlComponent(&engine);
+ qmlComponent.setData(
+ "import QtQuick 1.1;"
+ "Item {"
+ "signal focusChangedTo(bool value);"
+ "signal activeFocusChangedTo(bool value);"
+ "onFocusChanged: focusChangedTo(focus);"
+ "onActiveFocusChanged: activeFocusChangedTo(activeFocus);"
+ "}", QUrl(""));
+
+ QGraphicsItem *createdItem = qobject_cast<QGraphicsItem*>(qmlComponent.create(engine.rootContext()));
+ QVERIFY(createdItem);
+
+ scene.addItem(createdItem);
+
+ QSignalSpy focusChangedSpy(createdItem->toGraphicsObject(), SIGNAL(focusChangedTo(bool)));
+ QSignalSpy activeFocusChangedSpy(createdItem->toGraphicsObject(), SIGNAL(activeFocusChangedTo(bool)));
+
+ createdItem->toGraphicsObject()->setFocus();
+ QVERIFY(!focusChangedSpy.isEmpty());
+ QVERIFY(!activeFocusChangedSpy.isEmpty());
+ QCOMPARE(focusChangedSpy.takeFirst().first().toBool(), true);
+ QCOMPARE(activeFocusChangedSpy.takeFirst().first().toBool(), true);
+
+ scene.setFocusItem(0);
+ QVERIFY(!focusChangedSpy.isEmpty());
+ QVERIFY(!activeFocusChangedSpy.isEmpty());
+ QCOMPARE(focusChangedSpy.takeFirst().first().toBool(), false);
+ QCOMPARE(activeFocusChangedSpy.takeFirst().first().toBool(), false);
+ QVERIFY(activeFocusChangedSpy.isEmpty());
+}
+
+void tst_QDeclarativeItem::setFocusFocusItem0ThenHasActiveFocus()
+{
+ QGraphicsScene scene;
+ scene.setFocus();
+ QEvent event(QEvent::WindowActivate);
+ qApp->sendEvent(&scene, &event);
+
+ QDeclarativeEngine engine(&scene);
+ QDeclarativeComponent qmlComponent(&engine);
+ qmlComponent.setData(
+ "import QtQuick 1.1;"
+ "TextInput {"
+ "width: 100; height: 100;"
+ "Rectangle { anchors.fill: parent; color: \"yellow\"; z: parent.z - 1 }"
+ "}", QUrl(""));
+ QDeclarativeItem *createdItem = qobject_cast<QDeclarativeItem*>(qmlComponent.create(engine.rootContext()));
+ QVERIFY(createdItem != 0);
+
+ scene.addItem(createdItem);
+
+ createdItem->QGraphicsItem::setFocus();
+ QCoreApplication::processEvents();
+ scene.setFocusItem(0);
+ QCoreApplication::processEvents();
+
+ QVERIFY(!createdItem->hasActiveFocus());
+}
+
QTEST_MAIN(tst_QDeclarativeItem)
#include "tst_qdeclarativeitem.moc"