Fix assert after giving focus to a disabled item.
If an item has focus stolen by another item remove activeFocus from it even if the item that gains focus doesn't gain activeFocus. Otherwise the focus tree will enter a state where an item that is not the subFocusItem of its focus scope has activeFocus which is invalid and will trigger an assert in QQuickWindowPrivate::clearFocusInScope(). Task-number: QTBUG-34779 Change-Id: I72408ec0e4fd9b05ef595147ef1ef95b6aed1c16 Reviewed-by: Alan Alpert <aalpert@blackberry.com>
This commit is contained in:
parent
9b7dabbe9a
commit
1a76a4926a
|
@ -664,14 +664,18 @@ void QQuickWindowPrivate::setFocusInScope(QQuickItem *scope, QQuickItem *item, Q
|
|||
QVarLengthArray<QQuickItem *, 20> changed;
|
||||
|
||||
// Does this change the active focus?
|
||||
if (item == contentItem || (scopePrivate->activeFocus && item->isEnabled())) {
|
||||
if (item == contentItem || scopePrivate->activeFocus) {
|
||||
QQuickItem *oldActiveFocusItem = 0;
|
||||
oldActiveFocusItem = activeFocusItem;
|
||||
newActiveFocusItem = item;
|
||||
while (newActiveFocusItem->isFocusScope()
|
||||
&& newActiveFocusItem->scopedFocusItem()
|
||||
&& newActiveFocusItem->scopedFocusItem()->isEnabled()) {
|
||||
newActiveFocusItem = newActiveFocusItem->scopedFocusItem();
|
||||
if (item->isEnabled()) {
|
||||
newActiveFocusItem = item;
|
||||
while (newActiveFocusItem->isFocusScope()
|
||||
&& newActiveFocusItem->scopedFocusItem()
|
||||
&& newActiveFocusItem->scopedFocusItem()->isEnabled()) {
|
||||
newActiveFocusItem = newActiveFocusItem->scopedFocusItem();
|
||||
}
|
||||
} else {
|
||||
newActiveFocusItem = scope;
|
||||
}
|
||||
|
||||
if (oldActiveFocusItem) {
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
#include <QtQuick/qquickitem.h>
|
||||
#include <QtQuick/qquickwindow.h>
|
||||
#include <QtQuick/qquickview.h>
|
||||
#include <QtWidgets/QGraphicsSceneMouseEvent>
|
||||
#include "private/qquickfocusscope_p.h"
|
||||
#include "private/qquickitem_p.h"
|
||||
#include <qpa/qwindowsysteminterface.h>
|
||||
|
@ -1151,6 +1150,30 @@ void tst_qquickitem::enabledFocus()
|
|||
QCOMPARE(child2.hasFocus(), false);
|
||||
QCOMPARE(child2.hasActiveFocus(), false);
|
||||
QCOMPARE(window.activeFocusItem(), static_cast<QQuickItem *>(&child1));
|
||||
|
||||
child2.setFocus(true);
|
||||
QCOMPARE(root.isEnabled(), true);
|
||||
QCOMPARE(root.hasFocus(), true);
|
||||
QCOMPARE(root.hasActiveFocus(), true);
|
||||
QCOMPARE(child1.isEnabled(), true);
|
||||
QCOMPARE(child1.hasFocus(), false);
|
||||
QCOMPARE(child1.hasActiveFocus(), false);
|
||||
QCOMPARE(child2.isEnabled(), false);
|
||||
QCOMPARE(child2.hasFocus(), true);
|
||||
QCOMPARE(child2.hasActiveFocus(), false);
|
||||
QCOMPARE(window.activeFocusItem(), static_cast<QQuickItem *>(&root));
|
||||
|
||||
root.setEnabled(false);
|
||||
QCOMPARE(root.isEnabled(), false);
|
||||
QCOMPARE(root.hasFocus(), true);
|
||||
QCOMPARE(root.hasActiveFocus(), false);
|
||||
QCOMPARE(child1.isEnabled(), false);
|
||||
QCOMPARE(child1.hasFocus(), false);
|
||||
QCOMPARE(child1.hasActiveFocus(), false);
|
||||
QCOMPARE(child2.isEnabled(), false);
|
||||
QCOMPARE(child2.hasFocus(), true);
|
||||
QCOMPARE(child2.hasActiveFocus(), false);
|
||||
QCOMPARE(window.activeFocusItem(), window.contentItem());
|
||||
}
|
||||
|
||||
static inline QByteArray msgItem(const QQuickItem *item)
|
||||
|
|
Loading…
Reference in New Issue