diff options
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 15 | ||||
-rw-r--r-- | tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 32 |
2 files changed, 46 insertions, 1 deletions
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index c9bd706a0c..c2df098125 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6775,8 +6775,21 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) lastFocusChild = target; QWidget *focusProxy = target->d_func()->deepestFocusProxy(); - if (!focusProxy || !target->isAncestorOf(focusProxy)) + if (!focusProxy || !target->isAncestorOf(focusProxy)) { + // QTBUG-81097: Another case is possible here. We can have a child + // widget, that sets its focusProxy() to the parent (target). + // An example of such widget is a QLineEdit, nested into + // a QAbstractSpinBox. In this case such widget should be considered + // the last focus child. + for (auto *object : target->children()) { + QWidget *w = qobject_cast<QWidget*>(object); + if (w && w->focusProxy() == target) { + lastFocusChild = w; + break; + } + } return; + } lastFocusChild = focusProxy; diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index ebdb3b83c4..191ae2c5e1 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -194,6 +194,7 @@ private slots: void appFocusWidgetWithFocusProxyLater(); void appFocusWidgetWhenLosingFocusProxy(); void explicitTabOrderWithComplexWidget(); + void explicitTabOrderWithSpinBox_QTBUG81097(); #if defined(Q_OS_WIN) void activation(); #endif @@ -2331,6 +2332,37 @@ void tst_QWidget::explicitTabOrderWithComplexWidget() QTRY_COMPARE(QApplication::focusWidget(), lineEditOne); } +void tst_QWidget::explicitTabOrderWithSpinBox_QTBUG81097() +{ + // Check the special case of QAbstractSpinBox-like widgets, that have a + // child widget with a focusPolicy() set to its parent. + Container window; + auto spinBoxOne = new QDoubleSpinBox; + auto spinBoxTwo = new QDoubleSpinBox; + auto lineEdit = new QLineEdit; + window.box->addWidget(spinBoxOne); + window.box->addWidget(spinBoxTwo); + window.box->addWidget(lineEdit); + QWidget::setTabOrder(spinBoxOne, spinBoxTwo); + QWidget::setTabOrder(spinBoxTwo, lineEdit); + spinBoxOne->setFocus(); + window.show(); + QApplication::setActiveWindow(&window); + QVERIFY(QTest::qWaitForWindowActive(&window)); + QTRY_COMPARE(QApplication::focusWidget(), spinBoxOne); + + window.tab(); + QTRY_COMPARE(QApplication::focusWidget(), spinBoxTwo); + window.tab(); + QTRY_COMPARE(QApplication::focusWidget(), lineEdit); + window.backTab(); + QTRY_COMPARE(QApplication::focusWidget(), spinBoxTwo); + window.backTab(); + QTRY_COMPARE(QApplication::focusWidget(), spinBoxOne); + window.backTab(); + QTRY_COMPARE(QApplication::focusWidget(), lineEdit); +} + #if defined(Q_OS_WIN) void tst_QWidget::activation() { |