Files
sloposk/tests/tst_pointertracker.cpp
T
ericek111andClaude Opus 5.5 2b5edeb365 Gestures: flick, long-press alternates, trackpad, layer slide, rollover
- PointerTracker: per-finger gesture state machine (pure, unit-tested)
- AlternatesPicker + AlternatesPopup.qml: long-press choices, finger selects
- Space long-press trackpad moves the cursor with arrow keysyms
- Slide from .?123 onto a symbol types it and switches back
- New finger commits pending taps (iOS rollover)
- Flick animation: secondary symbol slides down as the finger moves
- Transparent popup margin with an input region that passes clicks through
- tst_keyboardsurface: end-to-end gesture tests on the real QML

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 14:55:49 +02:00

124 lines
2.9 KiB
C++

#include "input/PointerTracker.h"
#include <QTest>
using namespace Qt::StringLiterals;
using Gesture = PointerTracker::Gesture;
namespace {
KeyDef letter(const QString &flick = {}, const QStringList &alternates = {})
{
KeyDef k;
k.label = u"e"_s;
k.flick = flick;
k.alternates = alternates;
return k;
}
KeyDef ofType(KeyType type)
{
KeyDef k;
k.type = type;
return k;
}
PointerTracker::Config config()
{
PointerTracker::Config c;
c.slop = 10;
c.flickDistance = 30;
c.trackpadStep = 10;
c.trackpadRowStep = 40;
return c;
}
} // namespace
class TestPointerTracker : public QObject
{
Q_OBJECT
private Q_SLOTS:
void smallMovementStaysTap()
{
PointerTracker t(letter(u"3"_s), {0, 0}, config());
t.moveTo({5, 8});
QCOMPARE(t.gesture(), Gesture::Tap);
}
void downwardMovementFlicks()
{
PointerTracker t(letter(u"3"_s), {0, 0}, config());
t.moveTo({2, 15});
QCOMPARE(t.gesture(), Gesture::Flick);
QCOMPARE(t.flickProgress(), 0.5);
QVERIFY(!t.flickCommitted());
t.moveTo({2, 45});
QVERIFY(t.flickCommitted());
}
void flickBackUpUncommits()
{
PointerTracker t(letter(u"3"_s), {0, 0}, config());
t.moveTo({0, 40});
t.moveTo({0, 5});
QCOMPARE(t.gesture(), Gesture::Flick);
QVERIFY(!t.flickCommitted());
}
void sidewaysMovementDoesNotFlick()
{
PointerTracker t(letter(u"3"_s), {0, 0}, config());
t.moveTo({30, 15});
QCOMPARE(t.gesture(), Gesture::Tap);
}
void keysWithoutFlickNeverFlick()
{
PointerTracker t(letter(), {0, 0}, config());
t.moveTo({0, 40});
QCOMPARE(t.gesture(), Gesture::Tap);
}
void holdingStillOpensAlternates()
{
PointerTracker t(letter({}, {u"é"_s}), {0, 0}, config());
QVERIFY(t.wantsLongPress());
QVERIFY(t.longPressElapsed());
QCOMPARE(t.gesture(), Gesture::LongPress);
}
void movingCancelsLongPress()
{
PointerTracker t(letter({}, {u"é"_s}), {0, 0}, config());
t.moveTo({20, 0});
QVERIFY(!t.longPressElapsed());
QCOMPARE(t.gesture(), Gesture::Tap);
}
void spaceLongPressBecomesTrackpad()
{
PointerTracker t(ofType(KeyType::Space), {100, 0}, config());
QVERIFY(t.longPressElapsed());
QCOMPARE(t.gesture(), Gesture::Trackpad);
t.moveTo({125, 0});
QCOMPARE(t.takeTrackpadSteps(), QPoint(2, 0));
t.moveTo({131, 0});
QCOMPARE(t.takeTrackpadSteps(), QPoint(1, 0));
t.moveTo({95, -45});
QCOMPARE(t.takeTrackpadSteps(), QPoint(-3, -1));
}
void layerKeySlides()
{
PointerTracker t(ofType(KeyType::LayerSwitch), {0, 0}, config());
t.moveTo({40, -30});
QCOMPARE(t.gesture(), Gesture::Slide);
}
};
QTEST_GUILESS_MAIN(TestPointerTracker)
#include "tst_pointertracker.moc"