From b4384dab06450ef9afe46647da48d65a0677dd00 Mon Sep 17 00:00:00 2001 From: Christian Ehrlicher Date: Mon, 6 Nov 2023 20:45:41 +0100 Subject: [PATCH] QTabWidget/Bar: ignore hidden tabs for key events Even a tab was hidden it could be accessed with the key navigation or a scroll event which lead to painting artifacts. Pick-to: 6.5 5.15 Fixes: QTBUG-101219 Task-number: QTBUG-63038 Change-Id: I58be694eef5f86cccecbe528891a39a4acdda15f Reviewed-by: Richard Moe Gustavsen (cherry picked from commit 83e92e25573f98e7530a3dfcaf02910f3932107f) Reviewed-by: Qt Cherry-pick Bot --- src/widgets/widgets/qtabbar.cpp | 2 +- src/widgets/widgets/qtabwidget.cpp | 2 +- .../widgets/widgets/qtabbar/tst_qtabbar.cpp | 20 ++++++++++++++ .../widgets/qtabwidget/tst_qtabwidget.cpp | 27 +++++++++++++++++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index c4a2f57bf5c..91be20a5dc4 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -2436,7 +2436,7 @@ void QTabBarPrivate::setCurrentNextEnabledIndex(int offset) { Q_Q(QTabBar); for (int index = currentIndex + offset; validIndex(index); index += offset) { - if (tabList.at(index)->enabled) { + if (tabList.at(index)->enabled && tabList.at(index)->visible) { q->setCurrentIndex(index); break; } diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 8db76db7c71..c524e8d4c7a 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -1139,7 +1139,7 @@ void QTabWidget::keyPressEvent(QKeyEvent *e) ) { page = 0; } - if (d->tabs->isTabEnabled(page)) { + if (d->tabs->isTabEnabled(page) && d->tabs->isTabVisible(page)) { setCurrentIndex(page); break; } diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index 00d09873b2f..7aede22441f 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -50,6 +50,7 @@ private slots: void hideTab_data(); void hideTab(); void hideAllTabs(); + void checkHiddenTab(); void setElideMode_data(); void setElideMode(); @@ -367,6 +368,25 @@ void tst_QTabBar::hideAllTabs() QVERIFY(sizeHint.width() < prevSizeHint.width()); } +void tst_QTabBar::checkHiddenTab() +{ + QTabBar tabbar; + + tabbar.addTab("foo"); + tabbar.addTab("bar"); + tabbar.addTab("baz"); + tabbar.setCurrentIndex(0); + tabbar.setTabVisible(1, false); + + QKeyEvent keyRight(QKeyEvent::KeyPress, Qt::Key_Right, Qt::NoModifier); + QVERIFY(QApplication::sendEvent(&tabbar, &keyRight)); + QCOMPARE(tabbar.currentIndex(), 2); + + QKeyEvent keyLeft(QKeyEvent::KeyPress, Qt::Key_Left, Qt::NoModifier); + QVERIFY(QApplication::sendEvent(&tabbar, &keyLeft)); + QCOMPARE(tabbar.currentIndex(), 0); +} + void tst_QTabBar::setElideMode_data() { QTest::addColumn("tabElideMode"); diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp index eb29933fd1e..036bd0d35df 100644 --- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp +++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp @@ -60,6 +60,7 @@ private slots: void tabPosition(); void tabEnabled(); void tabHidden(); + void checkHiddenTab(); void tabText(); void tabShape(); void tabTooltip(); @@ -252,6 +253,32 @@ void tst_QTabWidget::tabHidden() } } +void tst_QTabWidget::checkHiddenTab() +{ + tw->addTab(new QWidget(), "foo"); + tw->addTab(new QWidget(), "bar"); + tw->addTab(new QWidget(), "baz"); + QCOMPARE(tw->count(), 3); + tw->setCurrentIndex(0); + tw->setTabVisible(1, false); + + QKeyEvent keyTab(QKeyEvent::KeyPress, Qt::Key_Tab, Qt::ControlModifier); + QVERIFY(QApplication::sendEvent(tw, &keyTab)); + QCOMPARE(tw->currentIndex(), 2); + QVERIFY(QApplication::sendEvent(tw, &keyTab)); + QCOMPARE(tw->currentIndex(), 0); + QVERIFY(QApplication::sendEvent(tw, &keyTab)); + QCOMPARE(tw->currentIndex(), 2); + + QKeyEvent keyBacktab(QKeyEvent::KeyPress, Qt::Key_Backtab, Qt::ControlModifier); + QVERIFY(QApplication::sendEvent(tw, &keyBacktab)); + QCOMPARE(tw->currentIndex(), 0); + QVERIFY(QApplication::sendEvent(tw, &keyBacktab)); + QCOMPARE(tw->currentIndex(), 2); + QVERIFY(QApplication::sendEvent(tw, &keyBacktab)); + QCOMPARE(tw->currentIndex(), 0); +} + void tst_QTabWidget::tabText() { // Test bad arguments