diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-04-16 14:16:37 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-04-19 09:43:16 +0000 |
commit | ab253c6bc7905c1d734e58d4d673ca45c5384967 (patch) | |
tree | 96d0fba4dae369203b74fa26d5ce59f8a5cea735 /src | |
parent | c2d0b2973037c7656d7b69d28fcc3be0005e3935 (diff) |
QQuickItem::forceActiveFocus(): actually force active focus
It was trying to get by with setFocus() but that doesn't always work,
in cases when the item's d->focus flag is true (leftover state) but
it doesn't actually have focus anymore after a reparenting scenario.
Item.focus represents the intention to be focused when possible, and
does not necessarily change due to environmental circumstances, such as
having its parent reparented. QQuickItem::setFocus(true) returns early
if the new requested focus state is the same as the stored d->focus;
so it was not enough for foceActiveFocus() to call only setFocus().
In the bug, TextInput and Loader both get stuck in the state
d->focus == true, so forceActiveFocus() did not do anything before.
Fixes: QTBUG-89736
Change-Id: Ib7f4caccf81b60a02e2655332b64efba4d1fd7cf
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
(cherry picked from commit a8be17a1472c6f504c0c40f68fdc13df035ac4b4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 82f4fac2bf..464076cbf8 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4798,14 +4798,26 @@ void QQuickItem::forceActiveFocus() void QQuickItem::forceActiveFocus(Qt::FocusReason reason) { + Q_D(QQuickItem); setFocus(true, reason); QQuickItem *parent = parentItem(); + QQuickItem *scope = nullptr; while (parent) { if (parent->flags() & QQuickItem::ItemIsFocusScope) { parent->setFocus(true, reason); + if (!scope) + scope = parent; } parent = parent->parentItem(); } + // In certain reparenting scenarios, d->focus might be true and the scope + // might also have focus, so that setFocus() returns early without actually + // acquiring active focus, because it thinks it already has it. In that + // case, try to set the DeliveryAgent's active focus. (QTBUG-89736). + if (scope && !d->activeFocus) { + if (auto da = d->deliveryAgentPrivate()) + da->setFocusInScope(scope, this, Qt::OtherFocusReason); + } } /*! |