diff options
| author | Gabriel Schneider <[email protected]> | 2026-08-26 01:42:15 -0300 |
|---|---|---|
| committer | Gabriel Schneider <[email protected]> | 2026-08-26 01:42:16 -0300 |
| commit | 2d3148247e6555b7b33bd532ae538d7a4358e160 (patch) | |
| tree | 0b9d40d116de8e70a979f92d718b01d4b7e9dfb9 /build.zig | |
| parent | 4ab24352873ed7bf8db93ef6bfec36a34b0357e8 (diff) | |
| download | pardes-2d3148247e6555b7b33bd532ae538d7a4358e160.tar.gz pardes-2d3148247e6555b7b33bd532ae538d7a4358e160.zip | |
Hold a lone ESC: every escape sequence on this wire was being shredded
The mouse did not work. Chasing that found something much larger: NO escape sequence
worked on this transport, and had not since the port began.
`vaxis.Parser` resolves a buffer containing nothing but 0x1b as the Escape KEY. That is
deliberate and correct for a terminal, where the kernel hands over a whole escape sequence
in a single read, so a solitary ESC really does mean somebody pressed Escape. A 115200
serial line hands over ONE BYTE AT A TIME - 87 us apart, an eternity to a loop running at
360 MHz - so the first byte of every sequence arrived alone and was resolved as Escape,
and the remaining bytes arrived as ordinary keys.
A mouse click therefore came through as TEN key presses: Escape, `[`, `<`, `0`, `;`, `1`,
`8`, `;`, `3`, `M`. The `0` among them is "go to column zero" in normal mode, which is
exactly where the cursor kept landing, and why the first attempt at this looked like a
coordinate bug. Arrow keys, function keys, and the host bridge's in-band resize reports
were all being taken apart the same way.
Longer partial sequences were never affected: the CSI scanner returns `n == 0` for "no
final byte yet" and the shell already keeps those bytes. Only the one-byte case needed an
answer, because it is the only one the parser answers WRONGLY instead of declining. So the
shell holds a buffer that is exactly one ESC and lets `pardes_p4_tick` release it after
10 ms - two orders of magnitude longer than the 87 us until the next byte of a real
sequence, and imperceptible to a person pressing Escape. The same trade every terminal
editor makes, for the same reason.
Finding it took instrumenting the ABI: printing `@tagName` of every event the shell
applied. Ten `key_press` where one `mouse` belonged is not a thing any amount of reading
the coordinate arithmetic would have shown, and I had already read it twice.
## Mouse reporting, and the 1003 that is not requested
With the sequences intact, `apply` already handled `.mouse` - it mirrors the tty shell - so
enabling reporting was the only missing piece. Spelled out here rather than taken from
`vx.setMouseMode`, which asks for `1002;1003;1004;1006`: 1003 is ANY-MOTION tracking, a
report per cell the pointer crosses with no button held. On a 115200 line that is dozens of
15-byte reports for one sweep, arriving as input the editor must parse while it paints, and
arriving whether or not anyone wants it - moving the mouse over the window would starve
typing. 1002 reports presses, releases and motion while a button is held, which is exactly
what a click and a drag-select need.
Verified on the die: a click at column 12 puts the cursor at column 12 and one at column 22
puts it at column 22, a drag paints a selection, and the wheel scrolls. A press alone paints
the new position and then reverts - the caret does not move until the gesture ends - so the
release is what commits it, which cost an hour of believing a working click was broken.
Screen byte-identical to the vaxis reference, round trip median 3682 us against 3682, snap
95/95, hxdiff 481/0, hxparity 561/0, unit-test, tty/p4/gui all build.
Diffstat (limited to 'build.zig')
0 files changed, 0 insertions, 0 deletions
