diff options
author | Doris Verria <doris.verria@qt.io> | 2024-05-06 19:33:27 +0200 |
---|---|---|
committer | Doris Verria <doris.verria@qt.io> | 2024-05-14 20:06:17 +0200 |
commit | 199b603633ee0827297a165cc2051a2f56b1eb8e (patch) | |
tree | ca832b03e28588d8a890ba33b5e628d76b36f15d /src/quick/items/qquickwindow.cpp | |
parent | 757bfef221654d5aeee72086393bd67b2c8554e5 (diff) |
Force active focus to target item in setFocusToTargetItem
It is not enough to call setFocus on the target item, as there
may be other focus scopes currently holding the active focus.
Call forceActiveFocus instead.
Also, if the target item is the First or Last target, we want
to explicitly set the focus to the first/last item of the window
that can receive focus. If that item is a FocusScope we need to
clear its previous subFocusItem.
Task-number: QTBUG-121789
Change-Id: I99e5da5727dfd99c76bf2fc0baf7e9b8330f7c4d
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick/items/qquickwindow.cpp')
-rw-r--r-- | src/quick/items/qquickwindow.cpp | 46 |
1 files changed, 26 insertions, 20 deletions
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 3392ab075d..9db4174af0 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -1859,31 +1859,37 @@ void QQuickWindowPrivate::clearFocusObject() void QQuickWindowPrivate::setFocusToTarget(FocusTarget target, Qt::FocusReason reason) { + if (!contentItem) + return; + QQuickItem *newFocusItem = nullptr; - if (contentItem) { - switch (target) { - case FocusTarget::First: - newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(contentItem, true); - break; - case FocusTarget::Last: - newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(contentItem, false); - break; - case FocusTarget::Next: - case FocusTarget::Prev: { - auto da = deliveryAgentPrivate(); - Q_ASSERT(da); - QQuickItem *focusItem = da->focusTargetItem() ? da->focusTargetItem() : contentItem; - bool forward = (target == FocusTarget::Next); - newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(focusItem, forward); - break; - } - default: - break; + switch (target) { + case FocusTarget::First: + case FocusTarget::Last: { + const bool forward = (target == FocusTarget::First); + newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(contentItem, forward); + if (newFocusItem) { + const auto *itemPriv = QQuickItemPrivate::get(newFocusItem); + if (itemPriv->subFocusItem && itemPriv->flags & QQuickItem::ItemIsFocusScope) + clearFocusInScope(newFocusItem, itemPriv->subFocusItem, reason); } + break; + } + case FocusTarget::Next: + case FocusTarget::Prev: { + const auto da = deliveryAgentPrivate(); + Q_ASSERT(da); + QQuickItem *focusItem = da->focusTargetItem() ? da->focusTargetItem() : contentItem; + bool forward = (target == FocusTarget::Next); + newFocusItem = QQuickItemPrivate::nextPrevItemInTabFocusChain(focusItem, forward); + break; + } + default: + break; } if (newFocusItem) - newFocusItem->setFocus(true, reason); + newFocusItem->forceActiveFocus(reason); } /*! |