Make sure the focus is passed on correctly when back-tabbing

When the tested widget has a focus proxy, then we should check if the
current focus widget is not the same as that focus proxy before setting
it to be the widget that gets focus. This ensures that when back-tabbing
from a widget like QDoubleSpinBox that it will not get stuck inside that
widget and will back-tab to the next correct one.

Fixes: QTBUG-81097
Change-Id: I3f689c7715da7f3ce8c3d2f616041528f5778a2f
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
bb10
Andy Shaw 2020-01-06 10:26:49 +01:00
parent 236a47ff7a
commit bb42b7d8b2
2 changed files with 30 additions and 1 deletions

View File

@ -2139,7 +2139,8 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
&& !(!next && focusProxy && test->isAncestorOf(focusProxy))
&& test->isVisibleTo(toplevel) && test->isEnabled()
&& !(w->windowType() == Qt::SubWindow && !w->isAncestorOf(test))
&& (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))) {
&& (toplevel->windowType() != Qt::SubWindow || toplevel->isAncestorOf(test))
&& f != focusProxy) {
w = test;
if (seenWindow)
focusWidgetAfterWindow = true;

View File

@ -72,6 +72,7 @@
#include <QtWidgets/QGraphicsProxyWidget>
#include <QtGui/qwindow.h>
#include <qtimer.h>
#include <QtWidgets/QDoubleSpinBox>
#if defined(Q_OS_OSX)
#include "tst_qwidget_mac_helpers.h" // Abstract the ObjC stuff out so not everyone must run an ObjC++ compile.
@ -187,6 +188,7 @@ private slots:
void tabOrderNoChange2();
void appFocusWidgetWithFocusProxyLater();
void appFocusWidgetWhenLosingFocusProxy();
void explicitTabOrderWithComplexWidget();
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void activation();
#endif
@ -2086,6 +2088,32 @@ void tst_QWidget::appFocusWidgetWhenLosingFocusProxy()
QCOMPARE(QApplication::focusWidget(), lineEdit);
}
void tst_QWidget::explicitTabOrderWithComplexWidget()
{
// Check that handling tab/backtab with a widget comprimised of other widgets
// handles tabbing correctly
Container window;
auto lineEditOne = new QLineEdit;
window.box->addWidget(lineEditOne);
auto lineEditTwo = new QLineEdit;
window.box->addWidget(lineEditTwo);
QWidget::setTabOrder(lineEditOne, lineEditTwo);
lineEditOne->setFocus();
window.show();
QApplication::setActiveWindow(&window);
QVERIFY(QTest::qWaitForWindowActive(&window));
QTRY_COMPARE(QApplication::focusWidget(), lineEditOne);
window.tab();
QTRY_COMPARE(QApplication::focusWidget(), lineEditTwo);
window.tab();
QTRY_COMPARE(QApplication::focusWidget(), lineEditOne);
window.backTab();
QTRY_COMPARE(QApplication::focusWidget(), lineEditTwo);
window.backTab();
QTRY_COMPARE(QApplication::focusWidget(), lineEditOne);
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT)
void tst_QWidget::activation()
{