diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-10-28 10:25:31 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-10-28 10:37:17 (GMT) |
commit | cc34b794439b59e3e226e2a8dc896fec5e27689d (patch) | |
tree | 8e23260564836f2913581eba7865bdfc0c072500 /src | |
parent | 44f8fac4e2fc4a4258b921ac595c2826ca96e99c (diff) | |
download | Qt-cc34b794439b59e3e226e2a8dc896fec5e27689d.zip Qt-cc34b794439b59e3e226e2a8dc896fec5e27689d.tar.gz Qt-cc34b794439b59e3e226e2a8dc896fec5e27689d.tar.bz2 |
Fix initial focus bug in ItemIsFocusScope.
The task provides an example that doesn't gain input focus when started.
The fix contains two parts: one is to allow items with focus scope
ancestors to become focus items even if the scope is inactive. The other
is to fix up the focusItem pointers on reparent. Before, the focus
scopes' focusItem pointers always pointed to itself, or the next scope.
Now these items are treated no differently than other items in that
respect.
The change has a performance impact when reparenting a large subtree
that has a sub focus item onto another item (one more dig).
Task-number: QT-2331
Reviewed-by: Alexis Menard
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 0107fba..ef43d5c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1039,13 +1039,31 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Update focus scope item ptr in new scope. - if (newParent) { + QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; + if (newFocusScopeItem && newParent) { + if (subFocusItem) { + // Find the subFocusItem's topmost focus scope. + QGraphicsItem *ancestorScope = 0; + QGraphicsItem *p = subFocusItem->d_ptr->parent; + while (p) { + if (p->flags() & QGraphicsItem::ItemIsFocusScope) + ancestorScope = p; + if (p->isPanel()) + break; + p = p->parentItem(); + } + if (ancestorScope) + newFocusScopeItem = ancestorScope; + } + QGraphicsItem *p = newParent; while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { - p->d_ptr->focusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; - // ### The below line might not make sense... - if (subFocusItem) + p->d_ptr->focusScopeItem = newFocusScopeItem; + // Ensure the new item is no longer the subFocusItem. The + // only way to set focus on a child of a focus scope is + // by setting focus on the scope itself. + if (subFocusItem && !p->focusItem()) subFocusItem->d_ptr->clearSubFocus(); break; } @@ -2983,8 +3001,11 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim while (p) { if (p->flags() & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = q_ptr; - if (!q_ptr->isActive() || !p->focusItem()) + if (!p->focusItem()) { + // If you call setFocus on a child of a focus scope that + // doesn't currently have a focus item, then stop. return; + } break; } p = p->d_ptr->parent; @@ -10751,8 +10772,12 @@ QDebug operator<<(QDebug debug, QGraphicsItem *item) return debug; } - debug << "QGraphicsItem(this =" << ((void*)item) - << ", parent =" << ((void*)item->parentItem()) + if (QGraphicsObject *o = item->toGraphicsObject()) + debug << o->metaObject()->className(); + else + debug << "QGraphicsItem"; + debug << "(this =" << (void*)item + << ", parent =" << (void*)item->parentItem() << ", pos =" << item->pos() << ", z =" << item->zValue() << ", flags = " << item->flags() << ")"; |