From c520a69f06317fb90d37324bf284ef9614cb5dbf Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Mon, 25 Feb 2013 17:01:16 +1000 Subject: 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 Task-number: QTBUG-28288 Task-number: QTBUG-25644 Change-Id: Ib3d17c42754c15a08b34c3388f50b45cc1d2a831 Reviewed-by: Andreas Aardal Hanssen Reviewed-by: Alan Alpert --- src/declarative/graphicsitems/qdeclarativeitem.cpp | 24 +++++++++++++++++++--- src/declarative/graphicsitems/qdeclarativeitem_p.h | 23 ++++++++------------- 2 files changed, 29 insertions(+), 18 deletions(-) (limited to 'src/declarative') 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 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; @@ -311,23 +312,15 @@ public: q->geometryChanged(QRectF(this->pos.x(), this->pos.y(), mWidth, mHeight), oldGeometry); } - // 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() { -- cgit v1.2.3