Commit graph

166 commits

Author SHA1 Message Date
80e4e288ad feat: keep hidden overlay-preview thumbnails live while held
Hidden tabs live in disabled scene trees, so
wlr_scene_output_send_frame_done() never reaches them and
frame-callback-throttled clients stop committing: only the shown
window's thumbnail tracked live while the rest sat at their last
frame.

Fan frame-done out to every hidden tab window once per output frame
while the overlay is held (overlay_send_hidden_frames after the scene
frame-done in both render_standalone and render_and_present). The
walk covers main plus subsurface trees for both xdg and X11 windows
via window_surface(), and skips the shown window the scene path
already handles.

Gated on --overlay-previews plus overlay_visible, so the steady state
with the menu hidden costs nothing and background clients are not
woken. The existing thumb_capture snapshot and draw-time tree
composite paths are unchanged; they simply receive the commits they
were missing.

Tests: new test_standalone_headless_overlay_previews_hidden_live uses
a hidden --pulse tab and asserts the red thumbnail count swings while
Alt is held. README overlay-previews paragraph updated from freeze to
live-while-held.

Verified: ./build.sh clean; overlay-previews suite 6 passed; full
suite 179 passed with -n4.
2026-10-02 10:24:27 +10:00
b04f6a2826 feat: add --cursor-size flag for standalone pointer size
New --cursor-size N (8..128px, both --cursor-size N and --cursor-size=N forms) sizing the standalone wlr_cursor. Precedence: CLI flag over $XCURSOR_SIZE over the 24px default. Out-of-range, missing or non-numeric values are startup errors (rc 2) naming the flag, matching the existing --start-cmd-index/--tab-groups handling. Nested mode is unaffected (the host draws the pointer there); the flag is silently ignored. Help text, README usage + cursor-shapes section, and a test_cursor_size_flag_errors regression test included. Verified: debug + release builds warning-free; cursor_size + tab-groups flag-error tests pass; --cursor-size 32 boots headless, --cursor-size 999 exits rc 2.
2026-10-01 09:41:36 +10:00
b149cf9461 test: cover locked session ignoring prefix overlay and passive keys
Adds test_standalone_headless_session_lock_no_overlay_or_disturb: while
ext-session-lock holds the session, holding the tab prefix must not
show the overlay and a passive key must leave the lock undisturbed
with the session alive. Guards the removal of the session_locked
early-return that swallowed every key (PIN typing now reaches the
locker). Verified to fail on the pre-fix compositor and pass after.
2026-09-29 23:28:08 +10:00
28d5df8d52 feat: show selected window title as header row in preview overlay
Preview menus open with a full-width header naming the active tab's current window (icon plus ellipsized title). Full width keeps menu sizing independent of the selection, so moving the highlight never resizes anything; thumbnail fill-share accounts for the header block within the existing margins. Taps on the header are swallowed.
2026-09-29 07:12:04 +10:00
d47cb4ad03 feat: size overlay preview thumbnails to the menu, capped at quarter screen height
Preview rows divide the content-sized menu (centered, 50px top/bottom margins) instead of using a fixed triple-title height, with each thumbnail capped at a quarter of the screen height. Measure, draw and hit-test share one metrics helper; snapshot size follows a cache with a legacy fallback. Adds a menu-band regression test.
2026-09-28 11:38:16 +10:00
38a17401d1 fix: composite overlay thumbnails from live textures for subsurface windows
Firefox paints into subsurfaces while its main surface stays transparent, so the single-buffer snapshot saw only black. Windows with subsurface content now composite at overlay-draw time from each live surface texture (which outlives current.buffer), while plain windows keep the legacy snapshot path. Adds wltest --subsurface repro mode and a regression test.
2026-09-27 18:22:07 +10:00
a7fe1f294d feat: make overlay previews last-appeared instead of live
Drop the ~15fps frame-done tick that woke hidden windows while
the preview overlay was held. Hidden clients now freeze on their
own (no scene frame callbacks), so their thumbnails sit at the
last-shown frame; the shown window keeps its thumbnail live
through its normal commits. Spontaneous hidden commits (a
window mapping mid-hold) still refresh via the unchanged
capture path.

Removes the preview timer, tree walk and arm/disarm logic, the
pulse smoke test that needed tick-driven hidden frames, and
rewrites the README/help wording to last-appeared semantics.
wltest --pulse stays for manual QA.
2026-09-27 08:28:46 +10:00
a9e5f3dcad feat: add --overlay-previews live window thumbnails
Adds a --overlay-previews flag that switches the hold-Alt tab
overlay from icon+title rows to icon plus a small live view of
each window (three times as tall as a title row, no captions).
Tabs with no mapped window keep their command-line text row.

Thumbnails stay live while the overlay is held: hidden windows
get no scene frame callbacks, so a ~15fps tick paces them with
frame-done (disarmed on release; the plain title list never
wakes background clients). Each commit is routed to its fresh
source -- a CPU snapshot for SHM attaches, a locked dma-buf
import for GPU clients, or the surface's own texture for
in-place SHM updates -- and hidden commits force a repaint.

Also adds a wltest --pulse MS mode (alternating color/black on
frame callbacks) as a deterministic live source, three smoke
tests (appear on open, map mid-hold, pulse flip), and README
docs.
2026-09-27 07:07:19 +10:00
78285ab581 fix: order cursor above overlay above content on the plane path
Park the hardware cursor plane while the overlay is held and paint
the themed cursor image into the plane buffer after the menu, so the
stack is cursor, overlay, content by construction on every backend:
no cursor layer exists for the menu layer to trade planes with, and
the menu buffer carries its own cursor wherever it lands.  On the
composite path re-add software cursors after the menu pass (a no-op
while a hardware cursor plane is active).

Extend the VT test with kernel-side placement (debugfs crtc-pos and
normalized-zpos must match the logged box on top) and a single-snapshot
cursor-above-menu order check.
2026-09-23 12:24:19 +10:00
9ea77fde6e fix: harden standalone overlay plane path on real DRM
Replace the per-frame overlay layer churn with one persistent layer
per output (NULL buffer parks it), so libliftoff allocations settle
instead of re-solving around a fresh layer object every frame.

Repaint the held overlay from a per-frame content hash checked in the
main-loop bodies: any drift schedules a frame, clean walks cost one
cheap string pass.  Deliberately not from the output frame handler --
scheduling there re-emits the same event via idle and wedges the loop
at 100% CPU with dead stdin (caught via gdb).  Drop all scattered
explicit overlay refresh calls; the confirm-quit modal stays on its
explicit damage path.

Cover transient plane rejects with one composite frame then retry the
plane; lock software cursors while the overlay is held on DRM so the
menu layer can never trade planes with the cursor across re-solves.
Log the plane verdict and box (WxH+X+Y) every plane frame as the
off-process handle for VT verification.

Add tests/test_vt_plane.py: foot + Alt-held probe + Alt+Shift+T
alacritty on the real DRM backend, asserting the layer stays accepted
and the menu FB sits topmost at the logged geometry (libdrm plane
reads plus debugfs crtc-pos/zpos), with cursor warps and held-key
repeats churning the allocation.
2026-09-23 10:07:00 +10:00
137e4d0568 feat: present standalone overlay on a hardware plane, repaint via per-frame hash poll
On DRM standalone outputs the Alt tab list / confirm-quit modal is
scanned out on a hardware plane via wlr_output_layer (libliftoff), so
the primary buffer stays untouched and direct scanout of the focused
client keeps running underneath. Plane capability is probed once per
output from the first overlay commit and forced via
WLR_DRM_FORCE_LIBLIFTOFF; KICK_OVERLAY_PLANE=0 keeps the composite
fallback. Unlock the plane buffer only after commit, destroy the
per-frame layer after state finish, and recompute the attach-render
lock from capability on output recreate.

Overlay freshness no longer depends on scattered explicit refresh
calls: while held, each frame decision point hashes what the overlay
would draw (rows, titles, highlight, icons) and repaints on drift.
The confirm-quit modal stays on its explicit damage path.

Adds test_alt_shift_t_refreshes_held_overlay.
2026-09-23 05:53:48 +10:00
a4bef1a0d4 revert: drop KICK_WHEEL_TICKS tick accumulation
Reverts 01fd76e. Tested against the real jittery hardware it was meant
to steady and it did not help, so out it goes rather than carrying a
knob nobody can tune into working. Overlay wheel cycling returns to
one step per discrete tick; the smooth accumulator is untouched.

This reverts both the compositor change and its test plus the
_nested_session extra_env knob, which nothing else uses.
2026-09-18 06:31:31 +10:00
01fd76e1ce feat: steady jittery wheels with KICK_WHEEL_TICKS
A bouncy old wheel emits a burst of discrete ticks per physical notch,
and each tick stepped one overlay tab, so the selection jumped around.
Discrete ticks now accumulate toward a per-step threshold with net
remainders (a +2/-1 burst leaves +1 instead of jumping), mirroring the
smooth-scroll accumulator: deliberate flicks still skip multiple tabs.

The threshold is KICK_WHEEL_TICKS, read per event like
KICK_REPEAT_DELAY_MS; unset or invalid means 1, today's
one-notch-per-step, so good hardware sees no change. It only affects
overlay cycling, never client scrolling, and the leftover fraction
resets when the overlay hides. The smooth 15px threshold is untouched.

Covered by test_overlay_wheel_ticks_env, which spawns with
KICK_WHEEL_TICKS=3 (via a new _nested_session extra_env knob) and
proves two ticks step nowhere while three step exactly once; it fails
on unpatched code.
2026-09-17 13:48:53 +10:00
3a6fdd4fd4 fix: normalize libinput wheel scale so standalone overlay cycling works
One wheel notch in standalone did nothing with the overlay up: libinput
reports discrete ticks scaled by WLR_POINTER_AXIS_DISCRETE_STEP (x120),
so a single notch ran cycle_tab 120 times -- an even number of wraps on
two tabs, netting zero visible movement while still swallowing the
event. The standalone axis handler now divides by the macro before
calling overlay_handle_axis; the client forward path stays raw since
the wlroots seat divides it back itself. Nested was never affected
(its discrete values already arrive in wire units).

Proven by test_standalone_overlay_wheel_libinput_scale, which drives
one notch through the real standalone handler via a new wltest
--virtual-axis mode and asserts exactly one step (it fails with 120
steps without the fix). wltest also grows the missing
axis_source/stop/discrete pointer handlers, without which libwayland
aborts any test client forwarded a scroll event, plus axis lines in
--pointer-out.
2026-09-17 13:33:31 +10:00
0b9012cd6f feat: cycle overlay tabs with the mouse wheel
Rolling the wheel while the overlay is up now steps through tabs
exactly like Alt+Up/Down: wheel down goes to the next tab, wheel up
to the previous one, wrapping at the ends, previewed live and
committed when Alt is released. Notched wheels step one tab per tick;
smooth touchpad-style scroll accumulates to 15px per step. Horizontal
scroll still goes to clients, and with the overlay down nothing
changes.

Swallowed vertical scroll never reaches clients (both the nested and
standalone axis paths share one overlay_handle_axis gate); wltest
grows axis_source/stop/discrete handlers so forwarded scroll no
longer aborts test clients, plus axis lines in --pointer-out.
2026-09-17 12:33:00 +10:00
a4e5633a27 feat: select overlay windows with the mouse cursor
Moving the cursor over an overlay row now previews that window, the
same as dragging a finger across it; sliding off every row keeps the
last preview. Clicks while the overlay is up do nothing and never
reach clients, and releasing Alt commits the preview.
2026-09-16 22:04:37 +10:00
d91cc8ba8d feat: drag across overlay retargets touch selection 2026-09-16 21:36:57 +10:00
0d65efdd49 feat: select overlay windows by touchscreen tap 2026-09-16 21:22:50 +10:00
57c5cb7912 docs: single-instance panels cannot nest; skip panel test when host owns bus 2026-09-15 23:20:56 +10:00
0ac7c5c3f6 fix: scrub mode vars from client environments 2026-09-14 11:42:30 +10:00
2a2aa2fbcb feat: standalone autodetect for DM Wayland sessions 2026-09-14 10:58:03 +10:00
6ec0d5f338 revert: drop per-compositor app config shadowing 2026-09-14 09:43:23 +10:00
240c1cea4f feat: per-compositor app config in kick, slim kick-pi 2026-09-14 07:30:04 +10:00
cb362b1519 feat: overlay titles via Pango+Cairo with full Unicode support 2026-09-13 11:59:07 +10:00
51faf6b7f0 test: mark intermittently-failing tests flaky 2026-09-13 09:28:27 +10:00
94884b1ef2 feat: layout and panels follow the shown entry, not the aggregate 2026-09-13 09:19:21 +10:00
e7df8d5396 feat: per-entry fullscreen, host chrome follows shown clients 2026-09-12 12:20:25 +10:00
7494fafb89 test: strip mode-forcing env from nested compositor spawns
A leaked WLR_BACKENDS (e.g. drm,libinput) or KICK_MODE in the ambient environment flips spawned nested compositors to standalone, where the DRM backend fails and every test dies at boot for reasons unrelated to what it asserts. Seen when running the suite from a shell carrying the agent session's own WLR_BACKENDS export. Strip just those two (host connection and socket dir must pass through); precedent: kick-in-kick pops and standalone env -i.
2026-09-12 08:19:55 +10:00
a2b7802ec1 fix: three startup/session crashers exposed by eager hosts and real use
tabs/mru lists init before host_init (sync configure walked garbage); EGL init keeps configured host size (swapchain desync abort); overlay sentinel bump snapshots size (shrank 1px/call to zero, then aborted). Adds motion-burst regression test.
2026-09-12 07:53:02 +10:00
f4cd5f7f92 fix: break sweep loop after tab removal; asan-gate defaults 2026-09-11 09:12:58 +10:00
16c5ed58e5 test: locked abs-pointer pin, rogue second lock surface; fix wltest abs gating 2026-09-11 08:37:27 +10:00
f58418b70d test: tier-2 harness coverage, bell, IME grab/popup, request round-trips, libdecor boot 2026-09-10 11:57:13 +10:00
3a194104a3 test: synth feed drives real host pointer/touch listeners 2026-09-10 10:58:22 +10:00
1a77721177 test: Take _ensure_build out of test_smoke.
- It didn't work with pytest xdist.
- The AI sometimes forgets to build before testing, but it is rare.
2026-09-10 08:52:47 +10:00
6b4418ae4f feat: serve xdg-decoration-v1 pinned client-side
Every tab is maximized and kick draws no frames, so new toplevels
are pinned to client-side mode (headerbars keep working) and later
server-side requests are ignored. Pinning happens at map -- set_mode
asserts on a never-committed surface, and decoration-before-commit is
the normal order (calling it in new_toplevel_decoration aborts
wlroots); late binds pin immediately when already initialized.

Adds an xdeco probe (maps one shm-backed toplevel, reports the
configured mode) with a regression test asserting mode=1, tracks it
in build.sh staleness, and covers the global in protocol_globals.
Full suite: 153 passed, 2 skipped.
2026-09-10 03:08:18 +10:00
8bdaa970cc feat: advertise alpha-modifier-v1 (passive surface alpha) 2026-09-10 02:30:55 +10:00
33526c7a4e test: unify _wait_log into Session.wait_for (phase 6)
All 16 assert _wait_log(s, rx, timeout) sites become s.wait_for(rx,
timeout); every caller only asserted truthiness, and both poll the
whole log identically, so behavior is unchanged (failures now report
the pattern plus a log tail instead of a custom one-liner). Sites on
_wait_log's 15s default keep timeout=15.0 explicitly since wait_for
defaults to 20s. The helper is deleted. Full suite: 152 passed,
2 skipped.
2026-09-10 02:10:01 +10:00
838876ff65 test: factor skip guards into _require_* helpers (phase 5)
30 host-Wayland, 6 Xwayland and 5 helper-binary skip guards become
_require_host_wayland() / _require_xwayland() / _require_file(path,
reason). Binary checks keep their own triage messages; os.access
checks and skipif/flaky markers are untouched. Full suite: 152
passed, 2 skipped.
2026-09-10 01:55:51 +10:00
f10fff910c test: factor throwaway wltest clients into _run_wl_client (phase 4)
9 uniform throwaway-client sites (late/tag, third tab, globals
prober, layer bars x2, foreign requester, takeover locker, modifiers
and popup-reposition oneshots) go from Popen + try/finally
terminate/wait to with _run_wl_client(sock, *args, **kw):. Deliberately
untouched: host-side wl-copy (host DISPLAY env), frame/menu X11 pairs
and popup a/b (shared/explicit mid-body lifecycles), the probe (custom
DISPLAY + log-file stdio), and the _oneshot_*/_poll_* helpers.
Full suite: 152 passed, 2 skipped.
2026-09-10 01:49:37 +10:00
40be266329 test: factor liveness/crash asserts into helpers (phase 3)
146 assert X.proc.poll() is None spellings (bare, log-tail tails of
varying length, custom operation messages) become _assert_alive(s,
msg): custom messages are preserved up front, the log tail is always
attached. The 4 crash-indicator loops become _assert_no_crash(log)
over the union tuple. Full suite: 152 passed, 2 skipped.
2026-09-09 23:41:00 +10:00
12b7b263bc test: realign paren continuations in with _run_* calls
Mechanical whitespace-only follow-up to phases 1-2: continuation
lines that were paren-aligned to the old s = _spawn_* heads now align
to the with _run_* heads. Verified with git diff -w (empty).
2026-09-09 23:35:30 +10:00
1d3ae67dd8 test: factor out-file polling loops into _wait_out (phase 2)
28 deadline/while/exists polling loops become one-line
assert _wait_out(path, contains, timeout) calls; the helper retries
empty/partial reads and survives exists/read races, and callers keep
their own assert messages (including the live '(missing)' payload
diagnostics). Deliberately untouched: in-loop liveness asserts
(fail-fast under load), pixel/dump/log-touch loops, line-count gates,
XWayland DISPLAY export loops, and the _oneshot_*/_poll_* helpers.
Full suite: 152 passed, 2 skipped.
2026-09-09 23:32:30 +10:00
c9a7fb813b test: factor spawn/close into _run_* context managers (phase 1)
101 single-session sites go from s = _spawn_* + try/finally
s.close() to with _run_*() as s:. Standard boot preambles fold into
wait= (any/any_frame/app0/app0_mapped). Client-cleanup tails are kept
as inner try/finally so kill order is unchanged; the dead
if poll() is None: terminate() after close() is dropped (close already
terminate+wait/kills). Fixtures, kick-in-kick outer/inner pairs and
_run_* internals are untouched. Full suite: 152 passed, 2 skipped.
2026-09-09 23:25:19 +10:00
04e056518a x11: instrument pending-associate/classify chain; mark ready_and_claim flaky
Deeper-X11 instrumentation (permanent, DEBUG): every associate event
now logs surface null/mapped/hooked state, classify logs wid/xpid/pgid
at entry, and pending-map has its own line -- closing the blind spot
between xwm pairing and tab claim.  Plus kick_monotonic_ms() timestamps
on the new lines for stall measurement (prefix-safe for all test
regexes).

Paid off immediately: two stalls autopsied to paired-but-never-mapped
wlr_surfaces (associate ran with surface mapped=0, no map for 15-30s,
classify never invoked -- proven by the absent entry line).  The stall
is therefore upstream of kick classification (X MapNotify delivery /
xwm mapping under -n15), not in it; locating it further needs live
capture during a stall, not post-hoc logs.

test_xwayland_ready_and_claim failed once the same way (paired xmessage
surface never mapped within 15s): marked flaky per the seen-it rule
(passes serially).
2026-09-09 22:31:46 +10:00
52d12bdf2e test: xwayland_alt_delete waits for the reaped launcher, not a fixed poll
The 15s os.kill poll asked for trouble (fixed window on a foreign event
loop).  Replaced with kick's own SIGCHLD reap line ([child] pid N
exited, written unbuffered per reaped child) -- the same signal, event
anchored, 30s backstop only.

Two bugs found along the way, both in the test not the product:
- claim pid != reaped pid (sh -c forks; the claim is the grandchild,
  the reap is the direct-child launcher) -- wait on [launch] app=0's pid.
- [child] uses 'pid ' (space) vs [launch]/[claim] 'pid=' -- the first
  version of this wait matched nothing for 30s, deterministically.
  (Also: earlier validation runs silently deselected this marked test;
  always pass -m flaky when validating marked tests.)

Unmarked after 12/12 at -n15 + serial green.
2026-09-09 21:59:56 +10:00
5ffc051940 test: event-driven hold-to-repeat tests (no wall-clock rate); mark xwayland_alt_delete
hold_alt_down_repeats + alt_tab_hold_repeats asserted repeat COUNTS in
fixed windows -- pure wall-clock.  Now: press -> wait [repeat] start
(new DEBUG lifecycle lines in kbd_repeat_start/cancel; stop logged only
when disarming a live timer) -> wait for ONE synthesized repeat
(count-based, unbounded time) -> release -> wait [repeat] stop ->
immediate count assert (no timer exists post-disarm, so no silence
window needed).  Generous timeouts bound hangs only; slow boxes take
longer without failing a rate.  hold_alt unmarked (6/6 at -n15).

xwayland_alt_delete_closes_x11_tab: 1 failure in 13 runs, no body --
marked flaky per the seen-it rule.

Evidence: -n15 gate clean (153 passed), serial gate clean (153).
2026-09-09 13:30:19 +10:00
e398f90b12 test: migrate host-timed tests to private kick-in-kick hosts; flock clipboard
The 7 host-timed tests failed not (only) on timeouts: autopsy showed
parallel workers stealing each other's live-host clipboard (wl-paste
returns another test's token -- no timeout survives that).

Clipboard x3: the failure is cross-talk on ONE shared host clipboard.
Serialize just those sections with an flock file across xdist workers
(the 45s polls stay as backstops for genuine host slowness -- marks
kept; focus-based backend still needs the real host).

Fullscreen x3 + cursor-shape: migrate to per-test outer-kick hosts
(same xdg/fullscreen/shape protocols, deterministic compositor instead
of GNOME).  No coverage lost (single code path; timing was the only
host variable).  cursor-shape uses deterministic warp-enter; fullscreen
uses tap/chord acks.  Added KICK_REPEAT_DELAY_MS + extra_args to
_spawn_nested_in.  Unmarked after -n15 validation.

hold_alt stays (wall-clock timer).

Evidence: -n15 gate 3x clean (152 passed), serial gate clean (152),
migrated tests 6/6 at -n15.  12 -> 7 flaky.
2026-09-09 13:03:10 +10:00
0babe8832e fix: survive Xwayland SIGKILL without aborting (detach X surface listeners)
Killing the embedded Xwayland server aborted the compositor:
surface_handle_resource_destroy assert (non-empty map listener list)
via wl_client_destroy in the main loop's flush_clients.

Mechanism: the dead server's Wayland client connection is purged before
wlroots' xwm cascade dissociates anything, so wlr_surfaces die with our
map/unmap/commit listeners still attached.

Fix: watch the Xwayland Wayland client (its destroy signal fires before
its resources are purged) and proactively detach surface listeners only
-- across claimed windows, override-redirect windows and unclaimed
pendings -- leaving xsurface-level listeners for the later tab teardown.
Idempotent; later dissociate/xsurface-destroy find clean flags.  The
restart test now also waits for the X11 window's map before killing, so
the crash path (listeners attached at death) is deterministically
exercised instead of raced.

Also re-mark output_mgmt_apply flaky (1 post-fix assertion under -n15;
budgets help but the modeset roundtrip stays load-sensitive).

Evidence: restart test 12/12 at the -n15 repro config (was ~2/9
crashing), detach handler firing on every server death, -n15 gate
clean, serial gate clean (148), flaky set green (11).
2026-09-09 12:23:56 +10:00
dcd6552533 test: fix dead_command, output_mgmt, gestures, xreqs; mark restart/leader/popup flaky
Fixed + unmarked (all green serially, holding at -n15):
- dead_command: wait for the exit line (event) before proc.wait instead
  of a fixed 10s reap timeout.
- output_mgmt_apply: phase on the existing [output] apply line so the
  commit wait covers only client reconfigure lag (30s budgets).
- gestures_roundtrip: cursor-line + [gesture] forward-line acks per
  sequence (offset), single client-file poll; no more resend-on-slow.
- x11_client_requests_driven: phased [xwayland] ready wait (own budget)
  + startup-crown settle/nav.

Hardened, marks kept (host-timed roundtrips): 3 fullscreen tests use
tap_ack/chord_ack + 30s host-configure waits.

Marked flaky (post-fix sightings under load):
- x11_menu_popup (associate never lands in X11-heavy -n15 runs),
- x11_leader (1 claim timeout post-fix),
- xwayland_server_restart_survived (real SIGSEGV in
  wl_display_flush_clients on Xwayland SIGKILL restart -- pre-existing
  race, unrelated to this work; needs a proper fix, not a test tweak).

Net flaky 14 -> 11. Evidence: -n15 gate 2x clean (148 passed),
serial gate clean, flaky set green serially.
2026-09-09 11:49:51 +10:00
f31b781d61 test: mark dead_command, x11_requests_driven, x11_leader, output_mgmt_apply flaky
All four observed failing under parallel load (X11 client startup /
claim races, dead-command explanation timeout, output-mgmt modeset
roundtrip); all pass serially. 14 flaky total.
2026-09-09 10:40:11 +10:00