tst_QWidget: use focus abstraction instead of focus_next/prev

Focus abstraction in QWidgetPrivate makes direct access to
QWidget::focus_next and focus_prev an antipattern.
Remove usage.

Add object names for better diagnostics when debugging focus issues.

Task-number: QTBUG-121478
Change-Id: Iecd3bdc824bf77c519951f8f7801eb50b29a6e00
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Axel Spoerl 2024-03-22 12:10:20 +01:00
parent 839cffd521
commit c0511410e5

View File

@ -2008,8 +2008,7 @@ static QList<QWidget *> getFocusChain(QWidget *start, bool bForward)
}); });
do { do {
ret += cur; ret += cur;
auto widgetPrivate = static_cast<QWidgetPrivate *>(qt_widget_private(cur)); cur = bForward ? cur->nextInFocusChain() : cur->previousInFocusChain();
cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev;
if (!--count) if (!--count)
return ret; return ret;
} while (cur != start); } while (cur != start);
@ -2075,23 +2074,29 @@ void tst_QWidget::defaultTabOrder()
void tst_QWidget::reverseTabOrder() void tst_QWidget::reverseTabOrder()
{ {
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive)) if (QGuiApplication::platformName().startsWith(QLatin1StringView("wayland"), Qt::CaseInsensitive))
QSKIP("Wayland: This fails. Figure out why."); QSKIP("Wayland: This fails. Figure out why.");
const int compositeCount = 2; const int compositeCount = 2;
Container container; Container container;
container.setWindowTitle(QLatin1String(QTest::currentTestFunction())); container.setObjectName(QLatin1StringView("Container"));
container.setWindowTitle(QLatin1StringView(QTest::currentTestFunction()));
Composite* composite[compositeCount]; Composite* composite[compositeCount];
QLineEdit *firstEdit = new QLineEdit(); QLineEdit *firstEdit = new QLineEdit();
firstEdit->setObjectName(QLatin1StringView("FirstEdit"));
container.box->addWidget(firstEdit); container.box->addWidget(firstEdit);
static constexpr QLatin1StringView comp("Composite-%1");
for (int i = 0; i < compositeCount; i++) { for (int i = 0; i < compositeCount; i++) {
composite[i] = new Composite(); const QString name = QString(comp).arg(i);
composite[i] = new Composite(nullptr, name);
composite[i]->setObjectName(name);
container.box->addWidget(composite[i]); container.box->addWidget(composite[i]);
} }
QLineEdit *lastEdit = new QLineEdit(); QLineEdit *lastEdit = new QLineEdit();
lastEdit->setObjectName(QLatin1StringView("LastEdit"));
container.box->addWidget(lastEdit); container.box->addWidget(lastEdit);
// Reverse tab order inside each composite // Reverse tab order inside each composite
@ -2244,15 +2249,14 @@ void tst_QWidget::tabOrderComboBox()
// Remove the focus proxy of the first combobox's line edit. // Remove the focus proxy of the first combobox's line edit.
QComboBox *box = boxes.at(0); QComboBox *box = boxes.at(0);
QLineEdit *lineEdit = box->lineEdit(); QLineEdit *lineEdit = box->lineEdit();
QWidgetPrivate *lePriv = QWidgetPrivate::get(lineEdit); const QWidget *prev = lineEdit->previousInFocusChain();
const QWidget *prev = lePriv->focus_prev; const QWidget *next = lineEdit->nextInFocusChain();
const QWidget *next = lePriv->focus_next; const QWidget *proxy = lineEdit->focusProxy();
const QWidget *proxy = lePriv->extra->focus_proxy;
QCOMPARE(proxy, box); QCOMPARE(proxy, box);
lineEdit->setFocusProxy(nullptr); lineEdit->setFocusProxy(nullptr);
QCOMPARE(lePriv->extra->focus_proxy, nullptr); QCOMPARE(lineEdit->focusProxy(), nullptr);
QCOMPARE(lePriv->focus_prev, prev); QCOMPARE(lineEdit->previousInFocusChain(), prev);
QCOMPARE(lePriv->focus_next, next); QCOMPARE(lineEdit->nextInFocusChain(), next);
// Remove first item and check chain consistency // Remove first item and check chain consistency
boxes.removeFirst(); boxes.removeFirst();
@ -2491,14 +2495,15 @@ void tst_QWidget::tabOrderWithProxyOutOfOrder()
{ {
Container container; Container container;
container.setWindowTitle(QLatin1String(QTest::currentTestFunction())); container.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
container.setObjectName(QLatin1StringView("Container"));
// important to create the widgets with parent so that they are // important to create the widgets with parent so that they are
// added to the focus chain already now, and with the buttonBox // added to the focus chain already now, and with the buttonBox
// before the outsideButton. // before the outsideButton.
QWidget buttonBox(&container); QWidget buttonBox(&container);
buttonBox.setObjectName("buttonBox"); buttonBox.setObjectName(QLatin1StringView("buttonBox"));
QPushButton outsideButton(&container); QPushButton outsideButton(&container);
outsideButton.setObjectName("outsideButton"); outsideButton.setObjectName(QLatin1StringView("outsideButton"));
container.box->addWidget(&outsideButton); container.box->addWidget(&outsideButton);
container.box->addWidget(&buttonBox); container.box->addWidget(&buttonBox);
@ -13432,6 +13437,7 @@ void tst_QWidget::setParentChangesFocus()
QApplicationPrivate::setActiveWindow(secondary.get()); QApplicationPrivate::setActiveWindow(secondary.get());
QVERIFY(QTest::qWaitForWindowActive(secondary.get())); QVERIFY(QTest::qWaitForWindowActive(secondary.get()));
} }
QVERIFY(QTest::qWaitFor([]{ return QApplication::focusWidget(); }));
QCOMPARE(QApplication::focusWidget()->objectName(), focusWidget); QCOMPARE(QApplication::focusWidget()->objectName(), focusWidget);
} }