bench: make wl-latency compositor-independent so the instrument can leave the felis tree #263
Labels
No labels
priority/P0
priority/P1
priority/P2
release/v0.1.0
status/blocked
status/planned
type/bug
type/design
type/test-gap
type/tracker
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
natsukium/felis#263
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
wl-latencyis the Linux half of thelatencysuite and the only piece of the bench harness still tied to onecompositor. Three sites shell out to
niri msg --json:focused_window()(scripts/bench/wl-latency/src/main.rs:551) — the focused window's id and pid, behindrequire_focus(calibration,main.rs:1092,main.rs:1201) andrequire_focus_id(measurement,main.rs:839,re-checked before every keystroke at
main.rs:912).focused_output()(main.rs:770) — the focused output's logical width/height/scale, plus the refusal on atransformed output.
The harness around it is already pluggable:
scripts/bench/wm/selects aWindowPinper desktop (MacTilerPin,NiriPin,FloatingPin) andsuite_latencyasks it for nothing butfocus_for_typing(pid)→ a window id(
suites.py:791). The Python side would accept a second compositor today; the instrument is what refuses.This is the recorded revisit trigger firing (
docs/explanation/testing.md:241): "Revisit if a second Linux compositorenters the field, at which point
wl-latency's niri-only focus check … needs a second implementation".Why it matters beyond the field
Compositor-independence is also the precondition for moving the instrument out of this repo. It is already its own
crate outside the workspace with no felis dependency (
scripts/bench/devshell.nix:86), and Typometer has been deadsince 2017 and will not come to Wayland — so a published, self-calibrating Wayland latency instrument has an empty
niche to fill. While it is niri-only, publishing it invites sway/Hyprland issues that a felis-internal tool never
receives. Independence first, extraction second (its own issue, once this lands).
Two tiers, one in scope
zwp_virtual_keyboard_v1andzwlr_screencopy_manager_v1— are already there, so only the two niri IPC queries need replacing. This is the scope.scope; the suite should skip with a reason rather than pretend.
The two queries
Output geometry — take it from
wl_output/xdg_output. The tool is already a Wayland client, so logical size,scale and transform arrive over the protocol instead of over any IPC: compositor-agnostic and strictly less code.
Uncontroversial.
Focus — no core protocol lets a client ask who holds the keyboard. Three candidates:
zwlr_foreign_toplevel_manager_v1: itsstateevent carriesactivated, the wlroots family implements it (thesame family that provides screencopy), and
wayland-protocols-wlris already a dependency. The catch is identity —the suite passes a compositor window id, which means nothing here — so the handshake would have to change to
something both sides can name: a unique title the launch sets (OSC 0/2) plus
app_id, matched against the activatedhandle.
wm/:niri msg/swaymsg -t get_tree/hyprctl activewindow -j. Keeps today's handshake, but multiplies exactly what this issue exists to remove, and every newcompositor then needs a code change in the instrument.
per-keystroke re-check (
main.rs:912) is why a window that loses focus mid-leg fails the leg instead of typing twohundred characters into the desktop.
(1) is the one to try first. Whichever lands, the decision belongs in
docs/explanation/testing.mdbeside the existingrecord.
Acceptance
Command::new("niri")left inmain.rs.wl-latency --calibratestill clears its own gate on niri (p95 − p5 under 5 ms), with the numbers re-recorded:replacing the focus path changes what the instrument does between injection and detection, so the old figures do not
carry over.
niri's, that is a finding to record, not a blocker.
focus_for_typingansweringNone— alreadyFloatingPin'sbehavior (
wm/floating.py:44).Where
scripts/bench/wl-latency/src/main.rs;scripts/bench/wm/(a sway pin, if the handshake changes);scripts/bench/suites.py;docs/explanation/testing.md(the record and its Revisit if);docs/reference/testing.md:383("wl-latencydrives niri only");.agents/skills/perf-trace/references/harnesses.md.