Skip disabled proxy widgets when (back)tabbing

Fixes: QTBUG-98137
Pick-to: 6.2 5.15
Change-Id: If52053dce361b130ef7dcfaf747710d8ceb9bbcd
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
bb10
Alexander Volkov 2021-11-09 18:02:49 +03:00
parent 610123b1c8
commit 185c8d5adf
2 changed files with 56 additions and 1 deletions

View File

@ -1955,7 +1955,10 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
// \a next). This is to ensure that we can tab in and out of compound widgets
// without getting stuck in a tab-loop between parent and child.
QWidget *focusProxy = test->d_func()->deepestFocusProxy();
const bool canTakeFocus = ((focusProxy ? focusProxy->focusPolicy() : test->focusPolicy())
auto effectiveFocusPolicy = [](QWidget *widget) {
return widget->isEnabled() ? widget->focusPolicy() : Qt::NoFocus;
};
const bool canTakeFocus = (effectiveFocusPolicy(focusProxy ? focusProxy : test)
& focus_flag) == focus_flag;
const bool composites = focusProxy ? (next ? focusProxy->isAncestorOf(test)
: test->isAncestorOf(focusProxy))

View File

@ -189,6 +189,7 @@ private slots:
void defaultTabOrder();
void reverseTabOrder();
void tabOrderWithProxy();
void tabOrderWithProxyDisabled();
void tabOrderWithCompoundWidgets();
void tabOrderWithCompoundWidgetsNoFocusPolicy();
void tabOrderNoChange();
@ -2109,6 +2110,57 @@ void tst_QWidget::tabOrderWithProxy()
QVERIFY(firstEdit->hasFocus());
}
void tst_QWidget::tabOrderWithProxyDisabled()
{
Container container;
container.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
QLineEdit lineEdit1;
lineEdit1.setObjectName("lineEdit1");
QWidget containingWidget;
containingWidget.setFocusPolicy(Qt::StrongFocus);
auto *containingLayout = new QVBoxLayout;
QLineEdit lineEdit2;
lineEdit2.setObjectName("lineEdit2");
QLineEdit lineEdit3;
lineEdit3.setObjectName("lineEdit3");
containingLayout->addWidget(&lineEdit2);
containingLayout->addWidget(&lineEdit3);
containingWidget.setLayout(containingLayout);
containingWidget.setFocusProxy(&lineEdit2);
lineEdit2.setEnabled(false);
container.box->addWidget(&lineEdit1);
container.box->addWidget(&containingWidget);
container.show();
container.activateWindow();
QApplication::setActiveWindow(&container);
if (!QTest::qWaitForWindowActive(&container))
QSKIP("Window failed to activate, skipping test");
QVERIFY2(lineEdit1.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
container.tab();
QVERIFY2(!lineEdit2.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
QVERIFY2(lineEdit3.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
container.tab();
QVERIFY2(lineEdit1.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
container.backTab();
QVERIFY2(lineEdit3.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
container.backTab();
QVERIFY2(!lineEdit2.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
QVERIFY2(lineEdit1.hasFocus(),
qPrintable(QApplication::focusWidget()->objectName()));
}
void tst_QWidget::tabOrderWithCompoundWidgets()
{
if (QGuiApplication::platformName().startsWith(QLatin1String("wayland"), Qt::CaseInsensitive))