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 ca15f650a1,
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>
This commit is contained in:
Volker Hilsheimer 2023-06-05 17:10:00 +02:00
parent a471324a03
commit 2a7da1b3c8
2 changed files with 39 additions and 0 deletions

View File

@ -1656,6 +1656,8 @@ void QTabBar::showEvent(QShowEvent *)
d->refresh();
if (!d->validIndex(d->currentIndex))
setCurrentIndex(0);
else
d->makeVisible(d->currentIndex);
d->updateMacBorderMetrics();
}

View File

@ -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"