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 <frederik.gladhorn@qt.io>
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
Christian Ehrlicher 2018-08-24 22:56:45 +02:00
parent 9a3bdbf40a
commit 81e298a51d
2 changed files with 32 additions and 1 deletions

View File

@ -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

View File

@ -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<QWidget*> getFocusChain(QWidget *start, bool bForward)
{
QVector<QWidget*> ret;
QWidget *cur = start;
do {
ret += cur;
auto widgetPrivate = static_cast<QWidgetPrivate *>(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()
{