0.4.0: pointer injection (POST /pointer) — needed to verify a mouse floor headlessly issue #1
closed: completed andymccall opened this · 0 comments
andymccall
Raising this as a consumer: rstar-api is about to add a pointer floor to
RWM (its WIMP toolkit), and 0.3.0 has no way to drive a mouse.
0.2 added POST /key, which is what makes keyboard-driven behaviour testable
without a human. A pointer needs the same treatment, for the same reason:
without it, the only headless options are to poke the drivers state through POST /mem` — which tests the toolkit while skipping the floor, the exact
layer most likely to be wrong — or to verify by hand, which does not survive
contact with CI.
What the consumer needs
POST /pointer?x=<n>&y=<n>[&buttons=<mask>] absolute position
POST /pointer?dx=<n>&dy=<n>[&buttons=<mask>] relative motion
GET /pointer read back current state
Absolute matters more than relative, for tests
Real mice report relative motion, and some platform drivers (the X16
KERNAL mouse) maintain an absolute position from it. But a test wants to say
"put the cursor on that button and click", not "move right by 37 and hope".
Relative-only injection would force every test to model the platform`s
acceleration and clamping in order to predict where the cursor ended up —
which is precisely the platform-specific behaviour the test is trying to stay
out of.
So: absolute is the primary form, relative offered where the backend can
express it honestly. If a backend can only do one, absolute is the one worth
having.
Inject at the device, not the driver
The value of this endpoint is that it exercises the platforms own mouse path — KERNAL/VERA on the X16, whatever the Neo firmware exposes. An implementation that writes the *drivers* result state would look identical from the test`s
side while testing nothing. Where a backend cannot reach the device layer,
that is worth stating in the per-platform appendix rather than papering over.
Determinism
Same contract as /key: an injection must land at a frame boundary, so that
pause -> pointer(x, y) -> step(1) -> screenshot
is reproducible run to run. Frame-exact pointer input is what would let a UI
be screenshot-diffed under a cursor — the same trick that makes the RGM
screenshot suite exact rather than tolerant.
Button semantics
A bitmask (bit 0 primary, bit 1 secondary) rather than separate down/up calls
reads better for a UI test, which usually wants "move here with the button
already held" for a drag. Worth allowing buttons to be omitted so a pure move
does not have to restate them.
GET /pointer
Cheap, and it makes a whole class of assertion possible: did the floor
actually consume what was injected? Without a read-back, a failing test can
only say "the wrong thing was drawn", not "the input never arrived".
Why now
rstar-api RGM is done on Neo6502 and X16, verified by frame-exact screenshot
assertions on both. The pointer floor is next, and it is the first thing in
that stack that cannot be verified with what 0.3.0 offers.
Happy to be a test consumer of a draft — a Neo6502 implementation alone would
unblock us, since that is the reference platform for this work.
Imported from GitHub #1, opened by andymccall on 2026-07-22, closed 2026-07-22.
Raising this as a consumer:
rstar-apiis about to add a pointer floor to RWM (its WIMP toolkit), and 0.3.0 has no way to drive a mouse.0.2 added
POST /key, which is what makes keyboard-driven behaviour testable without a human. A pointer needs the same treatment, for the same reason: without it, the only headless options are to poke the drivers state throughPOST /mem` — which tests the toolkit while skipping the floor, the exact layer most likely to be wrong — or to verify by hand, which does not survive contact with CI.What the consumer needs
Absolute matters more than relative, for tests
Real mice report relative motion, and some platform drivers (the X16 KERNAL mouse) maintain an absolute position from it. But a test wants to say "put the cursor on that button and click", not "move right by 37 and hope". Relative-only injection would force every test to model the platform`s acceleration and clamping in order to predict where the cursor ended up — which is precisely the platform-specific behaviour the test is trying to stay out of.
So: absolute is the primary form, relative offered where the backend can express it honestly. If a backend can only do one, absolute is the one worth having.
Inject at the device, not the driver
The value of this endpoint is that it exercises the platform
s own mouse path — KERNAL/VERA on the X16, whatever the Neo firmware exposes. An implementation that writes the *drivers* result state would look identical from the test`s side while testing nothing. Where a backend cannot reach the device layer, that is worth stating in the per-platform appendix rather than papering over.Determinism
Same contract as
/key: an injection must land at a frame boundary, so thatis reproducible run to run. Frame-exact pointer input is what would let a UI be screenshot-diffed under a cursor — the same trick that makes the RGM screenshot suite exact rather than tolerant.
Button semantics
A bitmask (bit 0 primary, bit 1 secondary) rather than separate down/up calls reads better for a UI test, which usually wants "move here with the button already held" for a drag. Worth allowing buttons to be omitted so a pure move does not have to restate them.
GET /pointerCheap, and it makes a whole class of assertion possible: did the floor actually consume what was injected? Without a read-back, a failing test can only say "the wrong thing was drawn", not "the input never arrived".
Why now
rstar-apiRGM is done on Neo6502 and X16, verified by frame-exact screenshot assertions on both. The pointer floor is next, and it is the first thing in that stack that cannot be verified with what 0.3.0 offers.Happy to be a test consumer of a draft — a Neo6502 implementation alone would unblock us, since that is the reference platform for this work.
Imported from GitHub #1, opened by andymccall on 2026-07-22, closed 2026-07-22.