From 81e298a51d08c510457b4a26b37c0d4aac5eba65 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Fri, 24 Aug 2018 22:56:45 +0200 Subject: QWidget: fix setTabOrder for compound widgets When adjusting the tab order for compound widgets, it can happen that the order is already correct. The check for this case forgot one case which lead to a garbled focus chain. Task-number: QTBUG-68393 Task-number: QTBUG-69619 Task-number: QTBUG-10907 Change-Id: Ic3242746bdcf3a4db6ea8daa1498381500ca116d Reviewed-by: Frederik Gladhorn Reviewed-by: Richard Moe Gustavsen --- src/widgets/kernel/qwidget.cpp | 4 +++- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 29 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 23d8d32b0d..4adccceebb 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -6963,8 +6963,10 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) determineLastFocusChild(second, lastFocusChildOfSecond); // If the tab order is already correct, exit early - if (lastFocusChildOfFirst->d_func()->focus_next == second) + if (lastFocusChildOfFirst == second || + lastFocusChildOfFirst->d_func()->focus_next == second) { return; + } // Note that we need to handle two different sections in the tab chain; The section // that 'first' belongs to (firstSection), where we are about to insert 'second', and diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index ae50b32164..360e6986f6 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -188,6 +188,7 @@ private slots: void reverseTabOrder(); void tabOrderWithProxy(); void tabOrderWithCompoundWidgets(); + void tabOrderNoChange(); #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void activation(); #endif @@ -1930,6 +1931,34 @@ void tst_QWidget::tabOrderWithCompoundWidgets() QVERIFY(lastEdit->hasFocus()); } +static QVector getFocusChain(QWidget *start, bool bForward) +{ + QVector ret; + QWidget *cur = start; + do { + ret += cur; + auto widgetPrivate = static_cast(qt_widget_private(cur)); + cur = bForward ? widgetPrivate->focus_next : widgetPrivate->focus_prev; + } while (cur != start); + return ret; +} + +void tst_QWidget::tabOrderNoChange() +{ + QWidget w; + auto *verticalLayout = new QVBoxLayout(&w); + auto *tabWidget = new QTabWidget(&w); + auto *tv = new QTreeView(tabWidget); + tabWidget->addTab(tv, QStringLiteral("Tab 1")); + verticalLayout->addWidget(tabWidget); + + const auto focusChainForward = getFocusChain(&w, true); + const auto focusChainBackward = getFocusChain(&w, false); + QWidget::setTabOrder(tabWidget, tv); + QCOMPARE(focusChainForward, getFocusChain(&w, true)); + QCOMPARE(focusChainBackward, getFocusChain(&w, false)); +} + #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) void tst_QWidget::activation() { -- cgit v1.2.3