summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-06-05 17:10:00 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-06-06 21:49:02 +0200
commit2a7da1b3c8c4096d7c2b09f3fcc58e9cf47867cd (patch)
treec6e080e257dc0f2504d103c91cd89ad0cc22a514
parenta471324a03a0b83e657325ee22f032b273e84102 (diff)
QTabBar: recalculate scroll offset when showing
If an application sets the current index and resizes the tab widget before showing it, then the scroll offset might be calculated based on an old size. Since after ca15f650a1a914bb9a41131109c46c4e52c5ebb1, resizing explicitly avoids scrolling, this could result in tabs ending up scrolled outside of the tab bar when showing the tab widget. Fix that by explicitly making the current tab visible in the tab bar's showEvent handler, which recalculates the scroll offset based on the actual size. This is only reproducible with a tab widget, which lays out the tab bar for each change and resets the tab bar's layoutDirty flag. Add a test case there. Pick-to: 6.5 6.6 Fixes: QTBUG-114204 Change-Id: I1e9506b9dde1dd892291d108dd2c7b675ef99509 Reviewed-by: Axel Spoerl <axel.spoerl@qt.io> Reviewed-by: Jonas Kvinge <jonas@jkvinge.net>
-rw-r--r--src/widgets/widgets/qtabbar.cpp2
-rw-r--r--tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp37
2 files changed, 39 insertions, 0 deletions
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 75cb6dd4ea..ea408ec7f6 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1656,6 +1656,8 @@ void QTabBar::showEvent(QShowEvent *)
d->refresh();
if (!d->validIndex(d->currentIndex))
setCurrentIndex(0);
+ else
+ d->makeVisible(d->currentIndex);
d->updateMacBorderMetrics();
}
diff --git a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
index 00cb26c2d3..eb29933fd1 100644
--- a/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
+++ b/tests/auto/widgets/widgets/qtabwidget/tst_qtabwidget.cpp
@@ -79,6 +79,9 @@ private slots:
void moveCurrentTab();
void autoHide();
+ void setCurrentBeforeShow_data();
+ void setCurrentBeforeShow();
+
private:
int addPage();
void removePage(int index);
@@ -750,5 +753,39 @@ void tst_QTabWidget::autoHide()
QVERIFY(heightForWidth1 > tabWidget.heightForWidth(20));
}
+void tst_QTabWidget::setCurrentBeforeShow_data()
+{
+ QTest::addColumn<QTabWidget::TabPosition>("tabPosition");
+ QTest::newRow("West") << QTabWidget::West;
+ QTest::newRow("North") << QTabWidget::North;
+ QTest::newRow("East") << QTabWidget::East;
+ QTest::newRow("South") << QTabWidget::South;
+}
+
+void tst_QTabWidget::setCurrentBeforeShow()
+{
+ QFETCH(QTabWidget::TabPosition, tabPosition);
+
+ QTabWidget tabWidget;
+ tabWidget.setTabPosition(tabPosition);
+
+ QPixmap pm(50, 50);
+ pm.fill(Qt::red);
+ const QIcon icon(pm);
+ for (int i = 0; i < 4; ++i)
+ tabWidget.addTab(new QWidget, icon, QString("Tab %1").arg(i));
+
+ // the tab widget has space for the entire tab bar
+ tabWidget.resize(tabWidget.tabBar()->sizeHint() + QSize(50, 50));
+ tabWidget.setCurrentIndex(2);
+ tabWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabWidget));
+
+ QCOMPARE_GE(tabWidget.tabBar()->tabRect(0).x(), 0);
+ QCOMPARE_GE(tabWidget.tabBar()->tabRect(0).y(), 0);
+
+ QTest::qWait(2000);
+}
+
QTEST_MAIN(tst_QTabWidget)
#include "tst_qtabwidget.moc"