Add missing nullptr check in QWidget::setFocusProxy

b1802a164b added handling for a parent to
become focus proxy of a child. The respective 'else if' branch didn't
check whether setFocusProxy() was called with a nullptr argument.

This patch adds the missing nullptr check.
It also adds functionality to tst_QWidget::tabOrderComboBox() to test
the removal of a focus proxy, as well as the complete removal of an
element from the focus chain.

Change-Id: I4cb865b9ac4497fc5e2595910738fb77694f5837
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Axel Spoerl 2023-04-24 11:50:54 +02:00
parent ac0953c34d
commit 72d6768ec1
2 changed files with 27 additions and 1 deletions

View File

@ -6412,7 +6412,7 @@ void QWidget::setFocusProxy(QWidget * w)
d->focus_prev = oldPrev;
oldPrev->d_func()->focus_next = this;
firstChild->d_func()->focus_prev = this;
} else if (w->isAncestorOf(this)) {
} else if (w && w->isAncestorOf(this)) {
// If the focus proxy is a parent, 'this' has to be inserted directly after its parent in the focus chain
// remove it from the chain and insert this into the focus chain after its parent

View File

@ -2144,6 +2144,7 @@ void tst_QWidget::tabOrderComboBox()
QFETCH(const QList<int>, secondTabOrder);
const int count = firstTabOrder.count();
Q_ASSERT(count == secondTabOrder.count());
Q_ASSERT(count > 1);
QWidget w;
w.setObjectName("MainWidget");
@ -2176,6 +2177,31 @@ void tst_QWidget::tabOrderComboBox()
COMPARE(secondTabOrder);
// Remove the focus proxy of the first combobox's line edit.
QComboBox *box = boxes.at(0);
QLineEdit *lineEdit = box->lineEdit();
QWidgetPrivate *lePriv = QWidgetPrivate::get(lineEdit);
const QWidget *prev = lePriv->focus_prev;
const QWidget *next = lePriv->focus_next;
const QWidget *proxy = lePriv->extra->focus_proxy;
QCOMPARE(proxy, box);
lineEdit->setFocusProxy(nullptr);
QCOMPARE(lePriv->extra->focus_proxy, nullptr);
QCOMPARE(lePriv->focus_prev, prev);
QCOMPARE(lePriv->focus_next, next);
// Remove first item and check chain consistency
boxes.removeFirst();
delete box;
// Create new list with 0 removed and other indexes updated
QList<int> thirdTabOrder(secondTabOrder);
thirdTabOrder.removeIf([](int i){ return i == 0; });
for (int &i : thirdTabOrder)
--i;
COMPARE(thirdTabOrder);
#undef COMPARE
}