1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
# Scroll momentum: a swipe still moving when the fingers lift keeps scrolling,
# in proportion to how hard it was thrown.
#
# The same shape as the dial's fling in rotate.snap, and asserted the same way,
# because the contract is the same one: momentum ramps up from zero at the
# floor (scroll_fling_floor in src/macos.zig, 8 rows/second) rather than
# switching on at it. The `gap_ms` argument is what makes the two cases
# different — it is a real sleep before the event, so libpardes measures a real
# speed off its monotonic clock rather than reading back-to-back script lines
# as an impossibly fast hand.
#
# Momentum on a real Apple trackpad comes from AppKit, not from here: its
# momentum events are ordinary pardes_scroll calls and every one of them
# cancels the coast. This is the path for the devices AppKit does not fling
# for, and it is the only one a script can reach at all, since NSEvent phases
# have no public constructor.
start 30 100
wait 8000 Newcol Joincol
wait 8000 $
stable 700 20000
# Something long enough to coast ALONG. A flick that runs out of document has
# nothing left to prove: at the top of a short scrollback the hardest possible
# throw and no throw at all leave the same screen. Brace expansion rather than
# seq, so the hermetic world needs nothing on PATH.
text printf 'LINE %s\n' {1..200}
key enter
wait 10000 LINE 200
stable 700 10000
snap home
# ---- PLACED ----
#
# Half a row every 100 ms is 5 rows/second, under the floor, so lifting the
# fingers changes nothing: the swipe itself has moved what it moved and that is
# where it stops. This is the case that has to hold — a slow deliberate scroll
# that kept sliding afterwards would be unusable.
scroll_begin
scroll -0.5 10 10 0 100
scroll -0.5 10 10 0 100
scroll -0.5 10 10 0 100
stable 700 15000
snap placed
scroll_end
stable 700 15000
# Byte-identical to `placed`, which is the whole assertion.
snap placed_released
# ---- THROWN ----
#
# The same hand moving six times as far in a twentieth of the time is hundreds
# of rows a second, so the release keeps the view travelling after the fingers
# are gone.
#
# `snap` and then `scroll_end` with NO `stable` between them, which is not
# impatience: a release is only a throw if it arrives while the hand is still
# moving, and a 700 ms wait here would be a hand that stopped — which is
# exactly what PLACED above already proves.
scroll_begin
scroll -3 10 10 0 5
scroll -3 10 10 0 5
scroll -3 10 10 0 5
snap thrown
scroll_end
stable 700 15000
# Further back through the scrollback than `thrown`, and that distance is the
# coast: nothing but the fling moved the view between these two captures.
snap coasted
# A finger back on the pad catches it. Begin re-zeros the velocity and the
# bank, so a second throw cannot inherit the first one's speed.
scroll_begin
stable 700 15000
snap caught
|