From f16fd9324ae5f86dfe851cad9639d2ee2e8571ed Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Tue, 22 Sep 2009 11:23:48 +0200 Subject: Fix focus scope bugs, verified against examples in kinetic-declarativeui. The C++ autotests have been updated to match the expected behavior of the examples that broke (e.g., listview.qml) in kinetic-declarativeui. Reviewed-by: Alexis --- src/gui/graphicsview/qgraphicsitem.cpp | 34 ++++++++++++-------------- src/gui/graphicsview/qgraphicsscene.cpp | 13 ++-------- tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp | 14 +++++------ 3 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0145499..3249bb1 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -982,12 +982,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = newParent; while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { - // ### We really want the parent's focus scope item to point - // to this item's focusItem... - if (q_ptr->flags() & QGraphicsItem::ItemIsFocusScope) - p->d_ptr->focusScopeItem = q_ptr; - else - p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; + p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; + // ### The below line might not make sense... + if (subFocusItem) + subFocusItem->d_ptr->clearSubFocus(); break; } p = p->d_ptr->parent; @@ -2812,15 +2810,12 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim if (scene && scene->focusItem() == f) return; - // Update the child focus chain. - setSubFocus(); - // Update focus scope item ptr. QGraphicsItem *p = parent; while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = q_ptr; - if (!q_ptr->isActive()) + if (!q_ptr->isActive() || !p->focusItem()) return; break; } @@ -2830,10 +2825,11 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim if (climb) { while (f->d_ptr->focusScopeItem && f->d_ptr->focusScopeItem->isVisible()) f = f->d_ptr->focusScopeItem; - if (f != q_ptr) - f->d_ptr->setSubFocus(); } + // Update the child focus chain. + f->d_ptr->setSubFocus(); + // Update the scene's focus item. if (scene) { QGraphicsItem *p = q_ptr->panel(); @@ -2858,13 +2854,15 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim void QGraphicsItem::clearFocus() { // Pass focus to the closest parent focus scope. - QGraphicsItem *p = d_ptr->parent; - while (p) { - if (p->flags() & ItemIsFocusScope) { - p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false); - return; + if (!d_ptr->inDestructor) { + QGraphicsItem *p = d_ptr->parent; + while (p) { + if (p->flags() & ItemIsFocusScope) { + p->d_ptr->setFocusHelper(Qt::OtherFocusReason, /* climb = */ false); + return; + } + p = p->d_ptr->parent; } - p = p->d_ptr->parent; } // Invisible items with focus must explicitly clear subfocus. diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index f6e0aaf..a267996 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -2434,17 +2434,8 @@ void QGraphicsScene::addItem(QGraphicsItem *item) // Ensure that newly added items that have subfocus set, gain // focus automatically if there isn't a focus item already. - if (!d->focusItem) { - if (item->focusItem() == item && item != d->lastFocusItem) { - QGraphicsItem *fi = item->focusItem() ? item->focusItem() : item->focusScopeItem(); - if (fi) { - QGraphicsItem *fsi; - while ((fsi = fi->focusScopeItem()) && fsi->isVisible()) - fi = fsi; - fi->setFocus(); - } - } - } + if (!d->focusItem && item != d->lastFocusItem && item->focusItem() == item) + item->focusItem()->setFocus(); d->updateInputMethodSensitivityInViews(); } diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 9b8ce1f..6f37b70 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -8299,7 +8299,7 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope2->focusScopeItem()); scope3->setParentItem(scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope2); QGraphicsRectItem *scope1 = new QGraphicsRectItem; scope1->setData(0, "scope1"); @@ -8308,9 +8308,9 @@ void tst_QGraphicsItem::focusScope() QVERIFY(!scope1->focusScopeItem()); scope2->setParentItem(scope1); - QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope3); - QCOMPARE(scope2->focusItem(), (QGraphicsItem *)scope3); - QCOMPARE(scope3->focusItem(), (QGraphicsItem *)scope3); + QCOMPARE(scope1->focusItem(), (QGraphicsItem *)scope1); + QCOMPARE(scope2->focusItem(), (QGraphicsItem *)0); + QCOMPARE(scope3->focusItem(), (QGraphicsItem *)0); QCOMPARE(scope1->focusScopeItem(), (QGraphicsItem *)scope2); QCOMPARE(scope2->focusScopeItem(), (QGraphicsItem *)scope3); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); @@ -8361,11 +8361,11 @@ void tst_QGraphicsItem::focusScope() rect5->setFocus(); rect5->setParentItem(rect4); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)rect5); - QVERIFY(rect5->hasFocus()); + QVERIFY(!rect5->hasFocus()); rect4->setParentItem(0); QCOMPARE(scope3->focusScopeItem(), (QGraphicsItem *)0); - QVERIFY(!scope3->hasFocus()); + QVERIFY(scope3->hasFocus()); QGraphicsRectItem *rectA = new QGraphicsRectItem; QGraphicsRectItem *scopeA = new QGraphicsRectItem(rectA); @@ -8376,7 +8376,7 @@ void tst_QGraphicsItem::focusScope() scopeB->setFocus(); scene.addItem(rectA); - QVERIFY(rect5->hasFocus()); + QVERIFY(!rect5->hasFocus()); QVERIFY(!scopeB->hasFocus()); scopeA->setFocus(); -- cgit v0.12