diff options
-rw-r--r-- | src/widgets/widgets/qtabbar.cpp | 16 | ||||
-rw-r--r-- | src/widgets/widgets/qtabbar_p.h | 3 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp | 45 |
3 files changed, 62 insertions, 2 deletions
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index 4b1a37d6e2..376355b0d5 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -1718,6 +1718,9 @@ bool QTabBar::event(QEvent *event) update(d->hoverRect); d->hoverIndex = -1; d->hoverRect = QRect(); +#if QT_CONFIG(wheelevent) + d->accumulatedAngleDelta = QPoint(); +#endif return true; } #if QT_CONFIG(tooltip) @@ -2421,8 +2424,17 @@ void QTabBar::wheelEvent(QWheelEvent *event) } } } else { - const int delta = wheelVertical ? event->angleDelta().y() : event->angleDelta().x(); - const int offset = delta > 0 ? -1 : 1; + d->accumulatedAngleDelta += event->angleDelta(); + const int xSteps = d->accumulatedAngleDelta.x() / QWheelEvent::DefaultDeltasPerStep; + const int ySteps = d->accumulatedAngleDelta.y() / QWheelEvent::DefaultDeltasPerStep; + int offset = 0; + if (xSteps > 0 || ySteps > 0) { + offset = -1; + d->accumulatedAngleDelta = QPoint(); + } else if (xSteps < 0 || ySteps < 0) { + offset = 1; + d->accumulatedAngleDelta = QPoint(); + } const int oldCurrentIndex = d->currentIndex; d->setCurrentNextEnabledIndex(offset); if (oldCurrentIndex != d->currentIndex) { diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index 5135839f89..5bc4c15293 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -102,6 +102,9 @@ public: QRect hoverRect; QPoint dragStartPosition; QPoint mousePosition = {-1, -1}; +#if QT_CONFIG(wheelevent) + QPoint accumulatedAngleDelta; +#endif QSize iconSize; QToolButton* rightB = nullptr; // right or bottom QToolButton* leftB = nullptr; // left or top diff --git a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp index 630b5c1167..f51f0a23d5 100644 --- a/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp +++ b/tests/auto/widgets/widgets/qtabbar/tst_qtabbar.cpp @@ -103,6 +103,8 @@ private slots: void mouseWheel(); void kineticWheel_data(); void kineticWheel(); + void highResolutionWheel_data(); + void highResolutionWheel(); void scrollButtons_data(); void scrollButtons(); @@ -1106,6 +1108,49 @@ void tst_QTabBar::kineticWheel() } } +void tst_QTabBar::highResolutionWheel_data() +{ + QTest::addColumn<int>("angleDelta"); + // Smallest angleDelta for a Logitech MX Master 3 with Linux/X11/Libinput + QTest::addRow("increment index") << -16; + QTest::addRow("decrement index") << 16; +} + +void tst_QTabBar::highResolutionWheel() +{ + TabBar tabbar; + TabBarScrollingProxyStyle proxyStyle; + tabbar.setStyle(&proxyStyle); + + tabbar.addTab("tab1"); + tabbar.addTab("tab2"); + QFETCH(int, angleDelta); + // Negative values increment, positive values decrement + int startIndex = angleDelta < 0 ? 0 : 1; + tabbar.setCurrentIndex(startIndex); + + const auto systemId = QPointingDevice::primaryPointingDevice()->systemId() + 1; + QPointingDevice hiResWheel( + "test high resolution wheel", systemId, QInputDevice::DeviceType::Mouse, + QPointingDevice::PointerType::Generic, + QInputDevice::Capability::Position | QInputDevice::Capability::Scroll, 1, 3); + + const QPoint wheelPoint = tabbar.rect().bottomRight(); + QWheelEvent event(wheelPoint, tabbar.mapToGlobal(wheelPoint), QPoint(), + QPoint(angleDelta, angleDelta), Qt::NoButton, Qt::NoModifier, + Qt::NoScrollPhase, false, Qt::MouseEventSynthesizedByApplication, + &hiResWheel); + + proxyStyle.scrolling = true; + for (int accumulated = 0; accumulated < QWheelEvent::DefaultDeltasPerStep; + accumulated += qAbs(angleDelta)) { + // verify that nothing has changed until the threshold has been reached + QVERIFY(tabbar.currentIndex() == startIndex); + QVERIFY(QApplication::sendEvent(&tabbar, &event)); + } + QVERIFY(tabbar.currentIndex() != startIndex); +} + #endif // QT_CONFIG(wheelevent) void tst_QTabBar::scrollButtons_data() |