From 72d6768ec130cc0508bfe433711a8f374b472fe3 Mon Sep 17 00:00:00 2001 From: Axel Spoerl Date: Mon, 24 Apr 2023 11:50:54 +0200 Subject: [PATCH] Add missing nullptr check in QWidget::setFocusProxy b1802a164b8682ed9e8956a5a19a90ade65c25d0 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 --- src/widgets/kernel/qwidget.cpp | 2 +- .../widgets/kernel/qwidget/tst_qwidget.cpp | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index d5dbc3f21a..d0ad169024 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -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 diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 7ed993deac..549206875c 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -2144,6 +2144,7 @@ void tst_QWidget::tabOrderComboBox() QFETCH(const QList, 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 thirdTabOrder(secondTabOrder); + thirdTabOrder.removeIf([](int i){ return i == 0; }); + for (int &i : thirdTabOrder) + --i; + + COMPARE(thirdTabOrder); + #undef COMPARE }