Disable TapHandler.longPressed signal if longPressThreshold == 0
There needs to be a way to disable the long-press feature, because it's exclusive: if we emit longPressed(), we do not emit tapped(). But we should also be able to accommodate slow users who pause for too long unintentionally, or while simply observing the behavior. Also clarify that resetting longPressThreshold reverts to the default. Add more exhaustive test coverage, verify that longPressed and tapped are mutually exclusive, and verify the effects of violating the gesturePolicy. Change longPressThreshold on LauncherList's back button so that it always triggers, regardless whether the user pauses on it for a while. [ChangeLog][QtQuick][Event Handlers] TapHandler.longPressThreshold can now be set to 0 to disable its press-and-hold feature, and can be reset to undefined to restore the platform default. Fixes: QTBUG-119132 Task-number: QTBUG-105810 Pick-to: 6.5 6.6 Change-Id: Id5fd7e51c70fdb0cb6c4beb5615717a222aec871 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@qt.io>
This commit is contained in:
parent
1b166c87d0
commit
8f6809681e
|
@ -182,6 +182,7 @@ Rectangle {
|
|||
id: tapHandler
|
||||
enabled: root.activePageCount > 0
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
longPressThreshold: 0
|
||||
onTapped: {
|
||||
pageContainer.children[pageContainer.children.length - 1].exit()
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ int QQuickTapHandler::m_touchMultiTapDistanceSquared(-1);
|
|||
|
||||
QQuickTapHandler::QQuickTapHandler(QQuickItem *parent)
|
||||
: QQuickSinglePointHandler(parent)
|
||||
, m_longPressThreshold(QGuiApplication::styleHints()->mousePressAndHoldInterval())
|
||||
{
|
||||
if (m_mouseMultiClickDistanceSquared < 0) {
|
||||
m_multiTapInterval = qApp->styleHints()->mouseDoubleClickInterval();
|
||||
|
@ -148,18 +149,27 @@ void QQuickTapHandler::handleEventPoint(QPointerEvent *event, QEventPoint &point
|
|||
\qmlproperty real QtQuick::TapHandler::longPressThreshold
|
||||
|
||||
The time in seconds that an \l eventPoint must be pressed in order to
|
||||
trigger a long press gesture and emit the \l longPressed() signal.
|
||||
If the point is released before this time limit, a tap can be detected
|
||||
if the \l gesturePolicy constraint is satisfied. The default value is
|
||||
QStyleHints::mousePressAndHoldInterval() converted to seconds.
|
||||
trigger a long press gesture and emit the \l longPressed() signal, if the
|
||||
value is greater than \c 0. If the point is released before this time
|
||||
limit, a tap can be detected if the \l gesturePolicy constraint is
|
||||
satisfied. If \c longPressThreshold is \c 0, the timer is disabled and the
|
||||
signal will not be emitted. If \c longPressThreshold is set to \c undefined,
|
||||
the default value is used instead, and can be read back from this property.
|
||||
|
||||
The default value is QStyleHints::mousePressAndHoldInterval() converted to
|
||||
seconds.
|
||||
*/
|
||||
qreal QQuickTapHandler::longPressThreshold() const
|
||||
{
|
||||
return longPressThresholdMilliseconds() / 1000.0;
|
||||
return m_longPressThreshold / qreal(1000);
|
||||
}
|
||||
|
||||
void QQuickTapHandler::setLongPressThreshold(qreal longPressThreshold)
|
||||
{
|
||||
if (longPressThreshold < 0) {
|
||||
resetLongPressThreshold();
|
||||
return;
|
||||
}
|
||||
int ms = qRound(longPressThreshold * 1000);
|
||||
if (m_longPressThreshold == ms)
|
||||
return;
|
||||
|
@ -168,9 +178,14 @@ void QQuickTapHandler::setLongPressThreshold(qreal longPressThreshold)
|
|||
emit longPressThresholdChanged();
|
||||
}
|
||||
|
||||
int QQuickTapHandler::longPressThresholdMilliseconds() const
|
||||
void QQuickTapHandler::resetLongPressThreshold()
|
||||
{
|
||||
return (m_longPressThreshold < 0 ? QGuiApplication::styleHints()->mousePressAndHoldInterval() : m_longPressThreshold);
|
||||
int ms = QGuiApplication::styleHints()->mousePressAndHoldInterval();
|
||||
if (m_longPressThreshold == ms)
|
||||
return;
|
||||
|
||||
m_longPressThreshold = ms;
|
||||
emit longPressThresholdChanged();
|
||||
}
|
||||
|
||||
void QQuickTapHandler::timerEvent(QTimerEvent *event)
|
||||
|
@ -353,7 +368,8 @@ void QQuickTapHandler::setPressed(bool press, bool cancel, QPointerEvent *event,
|
|||
connectPreRenderSignal(press);
|
||||
updateTimeHeld();
|
||||
if (press) {
|
||||
m_longPressTimer.start(longPressThresholdMilliseconds(), this);
|
||||
if (m_longPressThreshold > 0)
|
||||
m_longPressTimer.start(m_longPressThreshold, this);
|
||||
m_holdTimer.start();
|
||||
} else {
|
||||
m_longPressTimer.stop();
|
||||
|
|
|
@ -30,7 +30,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTapHandler : public QQuickSinglePointHandler
|
|||
Q_PROPERTY(bool pressed READ isPressed NOTIFY pressedChanged FINAL)
|
||||
Q_PROPERTY(int tapCount READ tapCount NOTIFY tapCountChanged FINAL)
|
||||
Q_PROPERTY(qreal timeHeld READ timeHeld NOTIFY timeHeldChanged FINAL)
|
||||
Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged FINAL)
|
||||
Q_PROPERTY(qreal longPressThreshold READ longPressThreshold WRITE setLongPressThreshold NOTIFY longPressThresholdChanged RESET resetLongPressThreshold FINAL)
|
||||
Q_PROPERTY(GesturePolicy gesturePolicy READ gesturePolicy WRITE setGesturePolicy NOTIFY gesturePolicyChanged FINAL)
|
||||
Q_PROPERTY(QQuickTapHandler::ExclusiveSignals exclusiveSignals READ exclusiveSignals WRITE setExclusiveSignals NOTIFY exclusiveSignalsChanged REVISION(6, 5) FINAL)
|
||||
|
||||
|
@ -63,6 +63,7 @@ public:
|
|||
|
||||
qreal longPressThreshold() const;
|
||||
void setLongPressThreshold(qreal longPressThreshold);
|
||||
void resetLongPressThreshold();
|
||||
|
||||
GesturePolicy gesturePolicy() const { return m_gesturePolicy; }
|
||||
void setGesturePolicy(GesturePolicy gesturePolicy);
|
||||
|
@ -92,7 +93,6 @@ protected:
|
|||
|
||||
private:
|
||||
void setPressed(bool press, bool cancel, QPointerEvent *event, QEventPoint &point);
|
||||
int longPressThresholdMilliseconds() const;
|
||||
void connectPreRenderSignal(bool conn = true);
|
||||
void updateTimeHeld();
|
||||
|
||||
|
|
|
@ -10,13 +10,20 @@ Rectangle {
|
|||
property alias pressed: tap.pressed
|
||||
property bool checked: false
|
||||
property alias gesturePolicy: tap.gesturePolicy
|
||||
property alias longPressThreshold: tap.longPressThreshold
|
||||
property point tappedPosition: Qt.point(0, 0)
|
||||
property real timeHeldWhenTapped: 0
|
||||
property real timeHeldWhenLongPressed: 0
|
||||
signal tapped
|
||||
signal canceled
|
||||
|
||||
width: label.implicitWidth * 1.5; height: label.implicitHeight * 2.0
|
||||
border.color: "#9f9d9a"; border.width: 1; radius: height / 4; antialiasing: true
|
||||
|
||||
function assignUndefinedLongPressThreshold() {
|
||||
tap.longPressThreshold = undefined
|
||||
}
|
||||
|
||||
gradient: Gradient {
|
||||
GradientStop { position: 0.0; color: tap.pressed ? "#b8b5b2" : "#efebe7" }
|
||||
GradientStop { position: 1.0; color: "#b8b5b2" }
|
||||
|
@ -25,14 +32,17 @@ Rectangle {
|
|||
TapHandler {
|
||||
id: tap
|
||||
objectName: label.text
|
||||
longPressThreshold: 100 // CI can be insanely slow, so don't demand a timely release to generate onTapped
|
||||
onSingleTapped: console.log("Single tap")
|
||||
onDoubleTapped: console.log("Double tap")
|
||||
onTapped: {
|
||||
console.log("Tapped")
|
||||
onTapped: (eventPoint, button) => {
|
||||
console.log("Tapped", button, eventPoint)
|
||||
tapFlash.start()
|
||||
root.tappedPosition = point.scenePosition
|
||||
root.tapped()
|
||||
root.timeHeldWhenTapped = tap.timeHeld // eventPoint.timeHeld is already 0
|
||||
}
|
||||
onLongPressed: {
|
||||
root.timeHeldWhenLongPressed = tap.timeHeld
|
||||
}
|
||||
onCanceled: root.canceled()
|
||||
}
|
||||
|
|
|
@ -9,19 +9,25 @@ Item {
|
|||
Button {
|
||||
objectName: "DragThreshold"
|
||||
label: "DragThreshold"
|
||||
x: 10; y: 10; width: parent.width - 20; height: 40
|
||||
x: 10; y: 10; width: 300; height: 40
|
||||
gesturePolicy: TapHandler.DragThreshold
|
||||
}
|
||||
Button {
|
||||
objectName: "WithinBounds"
|
||||
label: "WithinBounds"
|
||||
x: 10; y: 60; width: parent.width - 20; height: 40
|
||||
x: 10; y: 60; width: 300; height: 40
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
}
|
||||
Button {
|
||||
objectName: "ReleaseWithinBounds"
|
||||
label: "ReleaseWithinBounds"
|
||||
x: 10; y: 110; width: parent.width - 20; height: 40
|
||||
x: 10; y: 110; width: 300; height: 40
|
||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||
}
|
||||
Button {
|
||||
objectName: "DragWithinBounds"
|
||||
label: "DragWithinBounds"
|
||||
x: 10; y: 160; width: 300; height: 40
|
||||
gesturePolicy: TapHandler.DragWithinBounds
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ private slots:
|
|||
void mouseMultiTapLeftRight();
|
||||
void singleTapDoubleTap_data();
|
||||
void singleTapDoubleTap();
|
||||
void touchLongPress();
|
||||
void mouseLongPress();
|
||||
void longPress_data();
|
||||
void longPress();
|
||||
void buttonsMultiTouch();
|
||||
void componentUserBehavioralOverride();
|
||||
void rightLongPressIgnoreWheel();
|
||||
|
@ -778,76 +778,192 @@ void tst_TapHandler::singleTapDoubleTap()
|
|||
QCOMPARE(singleTapSpy.size(), expectedEndingSingleTapCount);
|
||||
}
|
||||
|
||||
void tst_TapHandler::touchLongPress()
|
||||
void tst_TapHandler::longPress_data()
|
||||
{
|
||||
QScopedPointer<QQuickView> windowPtr;
|
||||
createView(windowPtr, "buttons.qml");
|
||||
QQuickView * window = windowPtr.data();
|
||||
QTest::addColumn<const QPointingDevice *>("device");
|
||||
QTest::addColumn<QString>("buttonName");
|
||||
QTest::addColumn<qreal>("longPressThreshold");
|
||||
QTest::addColumn<QPoint>("releaseOffset");
|
||||
QTest::addColumn<bool>("expectLongPress");
|
||||
QTest::addColumn<bool>("expectTapped");
|
||||
|
||||
QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
|
||||
QVERIFY(button);
|
||||
QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
|
||||
QVERIFY(tapHandler);
|
||||
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
|
||||
QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
|
||||
QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
|
||||
QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
|
||||
const QPointingDevice *constTouchDevice = touchDevice;
|
||||
|
||||
// Reduce the threshold so that we can get a long press quickly
|
||||
tapHandler->setLongPressThreshold(0.5);
|
||||
QCOMPARE(longPressThresholdChangedSpy.size(), 1);
|
||||
// Reduce the threshold so that we can get a long press quickly (faster in CI)
|
||||
const qreal longPressThreshold = 0.3;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: DragThreshold")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragThreshold"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: DragThreshold")
|
||||
<< constTouchDevice << "DragThreshold" << longPressThreshold
|
||||
<< QPoint(0, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: DragThreshold, drag")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragThreshold"
|
||||
<< longPressThreshold << QPoint(50, 0) << false << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: DragThreshold, drag")
|
||||
<< constTouchDevice << "DragThreshold"
|
||||
<< longPressThreshold << QPoint(50, 0) << false << false;
|
||||
|
||||
// Press and hold
|
||||
QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
|
||||
QTest::touchEvent(window, touchDevice).press(1, p1, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
QTRY_VERIFY(button->property("pressed").toBool());
|
||||
QTRY_COMPARE(longPressedSpy.size(), 1);
|
||||
timeHeldSpy.wait(); // the longer we hold it, the more this will occur
|
||||
qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.size() << "times";
|
||||
QVERIFY(timeHeldSpy.size() > 0);
|
||||
QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
|
||||
QTest::newRow("mouse, lpt longPressThreshold: WithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: WithinBounds")
|
||||
<< constTouchDevice << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: WithinBounds, drag")
|
||||
<< QPointingDevice::primaryPointingDevice() << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: WithinBounds, drag")
|
||||
<< constTouchDevice << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: WithinBounds, drag out")
|
||||
<< QPointingDevice::primaryPointingDevice() << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: WithinBounds, drag out")
|
||||
<< constTouchDevice << "WithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
|
||||
// Release and verify that tapped was not emitted
|
||||
QTest::touchEvent(window, touchDevice).release(1, p1, window);
|
||||
QQuickTouchUtils::flush(window);
|
||||
QTRY_VERIFY(!button->property("pressed").toBool());
|
||||
QCOMPARE(tappedSpy.size(), 0);
|
||||
QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds")
|
||||
<< constTouchDevice << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds, drag")
|
||||
<< QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds, drag")
|
||||
<< constTouchDevice << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: ReleaseWithinBounds, drag out")
|
||||
<< QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: ReleaseWithinBounds, drag out")
|
||||
<< constTouchDevice << "ReleaseWithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
|
||||
QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds")
|
||||
<< constTouchDevice << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds, drag")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds, drag")
|
||||
<< constTouchDevice << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(50, 0) << true << false;
|
||||
QTest::newRow("mouse, lpt longPressThreshold: DragWithinBounds, drag out")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
QTest::newRow("touch, lpt longPressThreshold: DragWithinBounds, drag out")
|
||||
<< constTouchDevice << "DragWithinBounds"
|
||||
<< longPressThreshold << QPoint(155, 0) << false << false;
|
||||
|
||||
// Zero or negative threshold means long press is disabled
|
||||
QTest::newRow("mouse, lpt 0: DragThreshold")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragThreshold"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
QTest::newRow("mouse, lpt -1: DragThreshold")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragThreshold"
|
||||
<< qreal(-1) << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt 0: DragThreshold")
|
||||
<< constTouchDevice << "DragThreshold"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
|
||||
QTest::newRow("mouse, lpt 0: WithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "WithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
QTest::newRow("mouse, lpt -1: WithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "WithinBounds"
|
||||
<< qreal(-1) << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt 0: WithinBounds")
|
||||
<< constTouchDevice << "WithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
|
||||
QTest::newRow("mouse, lpt 0: ReleaseWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
QTest::newRow("mouse, lpt -1: ReleaseWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "ReleaseWithinBounds"
|
||||
<< qreal(-1) << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt 0: ReleaseWithinBounds")
|
||||
<< constTouchDevice << "ReleaseWithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
|
||||
QTest::newRow("mouse, lpt 0: DragWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
QTest::newRow("mouse, lpt -1: DragWithinBounds")
|
||||
<< QPointingDevice::primaryPointingDevice() << "DragWithinBounds"
|
||||
<< qreal(-1) << QPoint(0, 0) << true << false;
|
||||
QTest::newRow("touch, lpt 0: DragWithinBounds")
|
||||
<< constTouchDevice << "DragWithinBounds"
|
||||
<< qreal(0) << QPoint(0, 0) << false << true;
|
||||
}
|
||||
|
||||
void tst_TapHandler::mouseLongPress()
|
||||
void tst_TapHandler::longPress()
|
||||
{
|
||||
QScopedPointer<QQuickView> windowPtr;
|
||||
createView(windowPtr, "buttons.qml");
|
||||
QQuickView * window = windowPtr.data();
|
||||
QFETCH(const QPointingDevice *, device);
|
||||
QFETCH(QString, buttonName);
|
||||
QFETCH(qreal, longPressThreshold);
|
||||
QFETCH(QPoint, releaseOffset);
|
||||
QFETCH(bool, expectLongPress);
|
||||
QFETCH(bool, expectTapped);
|
||||
|
||||
QQuickItem *button = window->rootObject()->findChild<QQuickItem*>("DragThreshold");
|
||||
QQuickView window;
|
||||
QVERIFY(QQuickTest::showView(window, testFileUrl("buttons.qml")));
|
||||
|
||||
QQuickItem *button = window.rootObject()->findChild<QQuickItem*>(buttonName);
|
||||
QVERIFY(button);
|
||||
QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>("DragThreshold");
|
||||
QQuickTapHandler *tapHandler = button->findChild<QQuickTapHandler*>(buttonName);
|
||||
QVERIFY(tapHandler);
|
||||
QSignalSpy tappedSpy(button, SIGNAL(tapped()));
|
||||
QSignalSpy longPressThresholdChangedSpy(tapHandler, SIGNAL(longPressThresholdChanged()));
|
||||
QSignalSpy timeHeldSpy(tapHandler, SIGNAL(timeHeldChanged()));
|
||||
QSignalSpy longPressedSpy(tapHandler, SIGNAL(longPressed()));
|
||||
|
||||
// Reduce the threshold so that we can get a long press quickly
|
||||
tapHandler->setLongPressThreshold(0.5);
|
||||
QCOMPARE(longPressThresholdChangedSpy.size(), 1);
|
||||
const qreal defaultThreshold = tapHandler->longPressThreshold();
|
||||
qsizetype changedCount = 0;
|
||||
QCOMPARE_GT(defaultThreshold, 0);
|
||||
tapHandler->setLongPressThreshold(longPressThreshold);
|
||||
if (longPressThreshold > 0)
|
||||
QCOMPARE(longPressThresholdChangedSpy.size(), ++changedCount);
|
||||
QVERIFY(QMetaObject::invokeMethod(button, "assignUndefinedLongPressThreshold"));
|
||||
if (longPressThreshold > 0)
|
||||
QCOMPARE(longPressThresholdChangedSpy.size(), ++changedCount);
|
||||
QCOMPARE(tapHandler->longPressThreshold(), defaultThreshold);
|
||||
tapHandler->setLongPressThreshold(longPressThreshold);
|
||||
|
||||
// Press and hold
|
||||
QPoint p1 = button->mapToScene(button->clipRect().center()).toPoint();
|
||||
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
|
||||
QQuickTest::pointerPress(device, &window, 1, p1);
|
||||
QTRY_VERIFY(button->property("pressed").toBool());
|
||||
QTRY_COMPARE(longPressedSpy.size(), 1);
|
||||
QTRY_COMPARE(longPressedSpy.size(), expectLongPress ? 1 : 0);
|
||||
timeHeldSpy.wait(); // the longer we hold it, the more this will occur
|
||||
qDebug() << "held" << tapHandler->timeHeld() << "secs; timeHeld updated" << timeHeldSpy.size() << "times";
|
||||
QVERIFY(timeHeldSpy.size() > 0);
|
||||
QVERIFY(tapHandler->timeHeld() > 0.4); // Should be > 0.5 but slow CI and timer granularity can interfere
|
||||
QCOMPARE_GT(timeHeldSpy.size(), 0);
|
||||
if (expectLongPress) {
|
||||
// Should be > longPressThreshold but slow CI and timer granularity can interfere
|
||||
QCOMPARE_GT(tapHandler->timeHeld(), longPressThreshold - 0.1);
|
||||
} else {
|
||||
// Should be quite small, but event delivery is not instantaneous
|
||||
QCOMPARE_LT(tapHandler->timeHeld(), 0.3);
|
||||
}
|
||||
|
||||
// Release and verify that tapped was not emitted
|
||||
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1, 500);
|
||||
// If we have an offset, we need a move between press and release for realistic simulation
|
||||
if (!releaseOffset.isNull())
|
||||
QQuickTest::pointerMove(device, &window, 1, p1 + releaseOffset);
|
||||
|
||||
// Release (optionally at an offset) and check whether tapped was emitted
|
||||
QQuickTest::pointerRelease(device, &window, 1, p1 + releaseOffset);
|
||||
QTRY_VERIFY(!button->property("pressed").toBool());
|
||||
QCOMPARE(tappedSpy.size(), 0);
|
||||
if (expectLongPress)
|
||||
QCOMPARE_GT(button->property("timeHeldWhenLongPressed").toReal(), longPressThreshold - 0.1);
|
||||
QCOMPARE(tapHandler->timeHeld(), -1);
|
||||
QCOMPARE(tappedSpy.size(), expectTapped ? 1 : 0);
|
||||
QCOMPARE(longPressedSpy.size(), expectLongPress ? 1 : 0);
|
||||
}
|
||||
|
||||
void tst_TapHandler::buttonsMultiTouch()
|
||||
|
|
Loading…
Reference in New Issue