Skip proxy widgets that can't take focus when (back)tabbing
Fixes regression introduced in b4981f9d4ca914c6ecaa49bfdd69e51806a3671a, due to which it was possible to back-tab into a widget even though it or its focusProxy had a NoFocus policy. As a drive-by, split the complicated if-statement up a bit for improved readability. Change-Id: Ib0ac2604076e812e340b11534c23ae8ae958d082 Fixes: QTBUG-76924 Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io> (cherry picked from commit 0dbd2dd86389c0705dbe9f518aed12f609ed09a1) Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
parent
9115c84103
commit
d6bda220f7
@ -2165,10 +2165,12 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
|
|||||||
// \a next). This is to ensure that we can tab in and out of compound widgets
|
// \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.
|
// without getting stuck in a tab-loop between parent and child.
|
||||||
QWidget *focusProxy = test->d_func()->deepestFocusProxy();
|
QWidget *focusProxy = test->d_func()->deepestFocusProxy();
|
||||||
|
const bool canTakeFocus = ((focusProxy ? focusProxy->focusPolicy() : test->focusPolicy())
|
||||||
if ((test->focusPolicy() & focus_flag) == focus_flag
|
& focus_flag) == focus_flag;
|
||||||
&& !(next && focusProxy && focusProxy->isAncestorOf(test))
|
const bool composites = focusProxy ? (next ? focusProxy->isAncestorOf(test)
|
||||||
&& !(!next && focusProxy && test->isAncestorOf(focusProxy))
|
: test->isAncestorOf(focusProxy))
|
||||||
|
: false;
|
||||||
|
if (canTakeFocus && !composites
|
||||||
&& test->isVisibleTo(toplevel) && test->isEnabled()
|
&& test->isVisibleTo(toplevel) && test->isEnabled()
|
||||||
&& !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
|
&& !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
|
||||||
&& (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
|
&& (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
|
||||||
|
@ -67,6 +67,7 @@
|
|||||||
#include <qproxystyle.h>
|
#include <qproxystyle.h>
|
||||||
#include <QtWidgets/QGraphicsView>
|
#include <QtWidgets/QGraphicsView>
|
||||||
#include <QtWidgets/QGraphicsProxyWidget>
|
#include <QtWidgets/QGraphicsProxyWidget>
|
||||||
|
#include <QtWidgets/QSpinBox>
|
||||||
#include <QtGui/qwindow.h>
|
#include <QtGui/qwindow.h>
|
||||||
#include <qtimer.h>
|
#include <qtimer.h>
|
||||||
|
|
||||||
@ -180,6 +181,7 @@ private slots:
|
|||||||
void reverseTabOrder();
|
void reverseTabOrder();
|
||||||
void tabOrderWithProxy();
|
void tabOrderWithProxy();
|
||||||
void tabOrderWithCompoundWidgets();
|
void tabOrderWithCompoundWidgets();
|
||||||
|
void tabOrderWithCompoundWidgetsNoFocusPolicy();
|
||||||
void tabOrderNoChange();
|
void tabOrderNoChange();
|
||||||
void tabOrderNoChange2();
|
void tabOrderNoChange2();
|
||||||
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
|
||||||
@ -1964,6 +1966,51 @@ static void dumpFocusChain(QWidget *start, bool bForward, const char *desc = nul
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QWidget::tabOrderWithCompoundWidgetsNoFocusPolicy()
|
||||||
|
{
|
||||||
|
Container container;
|
||||||
|
container.setWindowTitle(QLatin1String(QTest::currentTestFunction()));
|
||||||
|
QSpinBox spinbox1;
|
||||||
|
spinbox1.setObjectName("spinbox1");
|
||||||
|
QSpinBox spinbox2;
|
||||||
|
spinbox2.setObjectName("spinbox2");
|
||||||
|
QSpinBox spinbox3;
|
||||||
|
spinbox3.setObjectName("spinbox3");
|
||||||
|
|
||||||
|
spinbox1.setFocusPolicy(Qt::StrongFocus);
|
||||||
|
spinbox2.setFocusPolicy(Qt::NoFocus);
|
||||||
|
spinbox3.setFocusPolicy(Qt::StrongFocus);
|
||||||
|
container.box->addWidget(&spinbox1);
|
||||||
|
container.box->addWidget(&spinbox2);
|
||||||
|
container.box->addWidget(&spinbox3);
|
||||||
|
|
||||||
|
container.show();
|
||||||
|
container.activateWindow();
|
||||||
|
|
||||||
|
QApplication::setActiveWindow(&container);
|
||||||
|
if (!QTest::qWaitForWindowActive(&container))
|
||||||
|
QSKIP("Window failed to activate, skipping test");
|
||||||
|
|
||||||
|
QVERIFY2(spinbox1.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
container.tab();
|
||||||
|
QVERIFY2(!spinbox2.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
QVERIFY2(spinbox3.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
container.tab();
|
||||||
|
QVERIFY2(spinbox1.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
container.backTab();
|
||||||
|
QVERIFY2(spinbox3.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
container.backTab();
|
||||||
|
QVERIFY2(!spinbox2.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
QVERIFY2(spinbox1.hasFocus(),
|
||||||
|
qPrintable(QApplication::focusWidget()->objectName()));
|
||||||
|
}
|
||||||
|
|
||||||
void tst_QWidget::tabOrderNoChange()
|
void tst_QWidget::tabOrderNoChange()
|
||||||
{
|
{
|
||||||
QWidget w;
|
QWidget w;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user