diff options
author | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-04-16 14:16:37 +0200 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@qt.io> | 2021-04-16 23:21:01 +0200 |
commit | 52c6fd1437df56cc167d208bafb85c1096bfc1cb (patch) | |
tree | 5d54469c9f14cc42e339ff2f51afa3cbd5410fbc /src/quick | |
parent | 3ba6fe4b620f8147d3152e8ae33c3a0e6a360332 (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: Shawn Rutledge <shawn.rutledge@qt.io>
Diffstat (limited to 'src/quick')
-rw-r--r-- | src/quick/items/qquickitem.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index 83964c4a3a..d1638670dc 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -4795,14 +4795,24 @@ 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 && d->window) + QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this, Qt::OtherFocusReason); } /*! |