Don't emit doubleTapped when the buttons are different

A left-click followed by right-click was interpreted as a double-click.
This is different from what I am used to and different
from what I expect. This patch changes the behavior such that only
clicks of the same button are interpreted as double click.

Pick-to: 6.2 6.4 6.5 6.5.0
Fixes: QTBUG-111557
Change-Id: Id0d83ca66944497710d8f659ed5a6d1e4260a2d9
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Matthias Rauter 2023-02-23 12:33:27 +01:00
parent 065b146dff
commit d3c1813563
2 changed files with 70 additions and 4 deletions

View File

@ -379,12 +379,16 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QPointerEvent *event,
const qreal ts = event->timestamp() / 1000.0;
const qreal interval = ts - m_lastTapTimestamp;
const auto distanceSquared = QVector2D(point.scenePosition() - m_lastTapPos).lengthSquared();
if (interval < m_multiTapInterval && distanceSquared <
const auto singleTapReleasedButton = event->isSinglePointEvent() ? static_cast<QSinglePointEvent *>(event)->button() : Qt::NoButton;
if ((interval < m_multiTapInterval && distanceSquared <
(event->device()->type() == QInputDevice::DeviceType::Mouse ?
m_mouseMultiClickDistanceSquared : m_touchMultiTapDistanceSquared))
&& m_singleTapReleasedButton == singleTapReleasedButton) {
++m_tapCount;
else
} else {
m_singleTapReleasedButton = singleTapReleasedButton;
m_tapCount = 1;
}
qCDebug(lcTapHandler) << objectName() << "tapped" << m_tapCount << "times; interval since last:" << interval
<< "sec; distance since last:" << qSqrt(distanceSquared);
auto button = event->isSinglePointEvent() ? static_cast<QSinglePointEvent *>(event)->button() : Qt::NoButton;
@ -447,8 +451,8 @@ void QQuickTapHandler::updateTimeHeld()
\readonly
The number of taps which have occurred within the time and space
constraints to be considered a single gesture. For example, to detect
a triple-tap, you can write:
constraints to be considered a single gesture. The counter is reset to 1
if the button changed. For example, to detect a triple-tap, you can write:
\qml
Rectangle {

View File

@ -44,6 +44,8 @@ private slots:
void touchMultiTap();
void mouseMultiTap_data();
void mouseMultiTap();
void mouseMultiTapLeftRight_data();
void mouseMultiTapLeftRight();
void singleTapDoubleTap_data();
void singleTapDoubleTap();
void touchLongPress();
@ -592,6 +594,66 @@ void tst_TapHandler::mouseMultiTap()
QCOMPARE(singleTapSpy.size(), expectedSingleTapsAfterWaiting);
}
void tst_TapHandler::mouseMultiTapLeftRight_data()
{
QTest::addColumn<QQuickTapHandler::ExclusiveSignals>("exclusiveSignals");
QTest::addColumn<int>("expectedSingleTaps");
QTest::addColumn<int>("expectedDoubleTaps");
QTest::addColumn<int>("expectedTabCount2");
QTest::addColumn<int>("expectedTabCount3");
QTest::newRow("NotExclusive") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::NotExclusive)
<< 3 << 0 << 1 << 1;
QTest::newRow("SingleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::SingleTap)
<< 3 << 0 << 1 << 1;
QTest::newRow("DoubleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::DoubleTap)
<< 0 << 0 << 1 << 1;
QTest::newRow("SingleTap|DoubleTap") << QQuickTapHandler::ExclusiveSignals(QQuickTapHandler::SingleTap | QQuickTapHandler::DoubleTap)
<< 0 << 0 << 1 << 1;
}
void tst_TapHandler::mouseMultiTapLeftRight() //QTBUG-111557
{
QFETCH(QQuickTapHandler::ExclusiveSignals, exclusiveSignals);
QFETCH(int, expectedSingleTaps);
QFETCH(int, expectedDoubleTaps);
QFETCH(int, expectedTabCount2);
QFETCH(int, expectedTabCount3);
QScopedPointer<QQuickView> windowPtr;
createView(windowPtr, "buttons.qml");
QQuickView * window = windowPtr.data();
QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
QVERIFY(button);
QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>();
QVERIFY(tapHandler);
tapHandler->setExclusiveSignals(exclusiveSignals);
tapHandler->setAcceptedButtons(Qt::LeftButton | Qt::RightButton);
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
QSignalSpy singleTapSpy(tapHandler, &QQuickTapHandler::singleTapped);
QSignalSpy doubleTapSpy(tapHandler, &QQuickTapHandler::doubleTapped);
// Click once with the left button
QPoint p1 = button->mapToScene(QPointF(2, 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
// Click again with the right button -> should reset tabCount()
QTest::mousePress(window, Qt::RightButton, Qt::NoModifier, p1, 10);
QTest::mouseRelease(window, Qt::RightButton, Qt::NoModifier, p1, 10);
QCOMPARE(tapHandler->tapCount(), expectedTabCount2);
// Click again with the left button -> should reset tabCount()
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 10);
QCOMPARE(tapHandler->tapCount(), expectedTabCount3);
QCOMPARE(singleTapSpy.size(), expectedSingleTaps);
QCOMPARE(doubleTapSpy.size(), expectedDoubleTaps);
}
void tst_TapHandler::singleTapDoubleTap_data()
{
QTest::addColumn<QPointingDevice::DeviceType>("deviceType");