diff options
author | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-08-16 20:28:31 +0200 |
---|---|---|
committer | Volker Hilsheimer <volker.hilsheimer@qt.io> | 2023-08-16 22:36:35 +0200 |
commit | 3965d52ad5a6376d593026a87831026a8a5f3469 (patch) | |
tree | 912d9d3fbd9d3c68ee8344b5a0ce5514691f241f | |
parent | 6e9f989eb61dd39562c47707cbd70d7f514b6e54 (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.cpp | 5 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 30 |
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" |