summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVolker Hilsheimer <volker.hilsheimer@qt.io>2023-08-16 20:28:31 +0200
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-08-16 22:36:35 +0200
commit3965d52ad5a6376d593026a87831026a8a5f3469 (patch)
tree912d9d3fbd9d3c68ee8344b5a0ce5514691f241f
parent6e9f989eb61dd39562c47707cbd70d7f514b6e54 (diff)
QTabBar: don't make current tab visible while tab bar is invisible
When changing the current index while the tab bar is not visible, calculating the necessary scroll offset might result in wrong results if the tab bar still has an old size. When the tab bar then gets shown and resized, the scroll wouldn't be corrected, potentially leaving tabs unnecessarily scrolled out. We don't need to make the current index visible if the tab bar itself is not visible, it's enough to flag the layout as dirty so that the next show event (which either way makes the then current index visible) triggers a laying out of the tab bar tabs. Amends e851d4c06154bf02b23030ff1f7024a8b9edf874. Fixes: QTBUG-115109 Task-number: QTBUG-113140 Pick-to: 6.6 6.5 Change-Id: I3d8633f9f8b907a36190123839a6104a17bfe138 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: David Faure <david.faure@kdab.com> Reviewed-by: Santhosh Kumar <santhosh.kumar.selvaraj@qt.io> Reviewed-by: Axel Spoerl <axel.spoerl@qt.io>
-rw-r--r--src/widgets/widgets/qtabbar.cpp5
-rw-r--r--tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp30
2 files changed, 34 insertions, 1 deletions
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index f6015f09d8..c4a2f57bf5 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -1413,7 +1413,10 @@ void QTabBar::setCurrentIndex(int index)
if (tabRect(index).size() != tabSizeHint(index))
d->layoutTabs();
update();
- d->makeVisible(index);
+ if (!isVisible())
+ d->layoutDirty = true;
+ else
+ d->makeVisible(index);
if (d->validIndex(oldIndex)) {
tab->lastTab = oldIndex;
d->layoutTab(oldIndex);
diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
index 6d5be7d558..00d09873b2 100644
--- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
+++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp
@@ -99,6 +99,7 @@ private slots:
void resizeKeepsScroll_data();
void resizeKeepsScroll();
void changeTabTextKeepsScroll();
+ void settingCurrentTabBeforeShowDoesntScroll();
private:
void checkPositions(const TabBar &tabbar, const QList<int> &positions);
@@ -1452,5 +1453,34 @@ void tst_QTabBar::changeTabTextKeepsScroll()
QCOMPARE(getScrollOffset(), scrollOffset);
}
+void tst_QTabBar::settingCurrentTabBeforeShowDoesntScroll()
+{
+ QTabBar tabBar;
+ TabBarScrollingProxyStyle proxyStyle;
+ tabBar.setStyle(&proxyStyle);
+
+ for (int i = 0; i < 6; ++i)
+ tabBar.addTab(u"Tab Number %1"_s.arg(i));
+
+ const auto getScrollOffset = [&]() -> int {
+ return static_cast<QTabBarPrivate *>(QObjectPrivate::get(&tabBar))->scrollOffset;
+ };
+
+ tabBar.setCurrentIndex(5);
+
+ // changing the current index while the tab bar isn't visible shouldn't scroll yet
+ QCOMPARE(getScrollOffset(), 0);
+
+ // now show the tab bar with a size that's too small to fit the current index
+ const QSize fullSize = tabBar.sizeHint();
+ tabBar.resize(fullSize.width() / 2, fullSize.height());
+
+ tabBar.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&tabBar));
+
+ // this should scroll
+ QCOMPARE_GT(getScrollOffset(), 0);
+}
+
QTEST_MAIN(tst_QTabBar)
#include "tst_qtabbar.moc"