aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquickitem.cpp
diff options
context:
space:
mode:
authorShawn Rutledge <shawn.rutledge@qt.io>2021-04-16 14:16:37 +0200
committerShawn Rutledge <shawn.rutledge@qt.io>2021-06-10 12:32:38 +0000
commit6c56f0eef6a6c54e437d6472eeda25ef4e7b9862 (patch)
treea1a63e1755644d9a439e86c35517f3d39b658753 /src/quick/items/qquickitem.cpp
parent21c4c5f4eb9590a7435e8cab98ae9236b7a9e8d8 (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 CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/quick/items/qquickitem.cpp')
-rw-r--r--src/quick/items/qquickitem.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 0f03e776c9..f17b4110f9 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -4790,14 +4790,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);
}
/*!