Summary
The stop and blank viewer commands do not actually pause the asset loop on a headless Wayland (cage) board. The viewer keeps rotating through the playlist for 8s+ after the command is received, instead of holding on the current frame (stop) or blanking (blank).
This is pre-existing — not introduced by the current release candidate. It was found during full-fleet QA of v2026.7.0 (f0959a4), but the loop_is_stopped pause mechanism predates that RC, so it does not gate the release; filing it as a follow-up.
Environment
- Board: headless Wayland/cage board (Pi 5 class),
QT_QPA_PLATFORM=wayland.
- Version:
v2026.7.0 (f0959a4).
Steps to reproduce
- Add ≥2 enabled, currently-active assets with short durations (e.g. a 4s image + a 4s webpage) so the loop is visibly rotating.
- Publish
reload on the anthias.viewer Redis channel, confirm the viewer log is cycling (Showing asset ... (...) every few seconds).
- Publish
stop (or blank) on anthias.viewer.
- Wait ~8s and count
Showing asset lines in the viewer log.
Expected: after stop, no new Showing asset lines (loop paused on current frame); after blank, the loop pauses and the screen paints black / DPMS-off.
Actual: the loop keeps emitting Showing asset ... (observed 2–3 switches in a 10–12s window well after the command). unblank/play also don't cleanly restore the expected state.
Scope / isolation
next, previous, asset&<id>, and reload all work — the Redis subscriber is alive and dispatching, so this is isolated to the loop_is_stopped pause path, not the command bus.
- Command handlers:
blank_display() / stop_playback() in src/anthias_viewer/__init__.py set the module-level loop_is_stopped = True (via the dispatch table around L507-518). start_loop() (same module, ~L1530) reads loop_is_stopped at the top of its while True, but keeps calling asset_loop(scheduler).
- This looks like the same cross-namespace global-visibility class of bug that the
stop_playback docstring says was already fixed for stop under python -m anthias_viewer — evidently not fully closed, or a second write path still targets the wrong namespace.
Impact
Low–medium. These are the UI's pause / screen-off controls (PR #3065). When they no-op, the screen keeps showing content instead of pausing/blanking — no data loss, no crash, core playback unaffected.
Follow-up needed
Confirm on a board with a real connected display before closing: on a headless Wayland board there is no output, so the _apply_wlr_power(False) (DPMS-off) half of blank is a no-op there and the loop-pause is the only observable effect — a physical display may behave differently. If it reproduces with a display attached, fix the loop_is_stopped write/read so the subscriber thread's update is seen by start_loop.
Found during full-fleet release QA; verified stop and blank both fail to pause while next/previous/reload succeed.
Summary
The
stopandblankviewer commands do not actually pause the asset loop on a headless Wayland (cage) board. The viewer keeps rotating through the playlist for 8s+ after the command is received, instead of holding on the current frame (stop) or blanking (blank).This is pre-existing — not introduced by the current release candidate. It was found during full-fleet QA of
v2026.7.0 (f0959a4), but theloop_is_stoppedpause mechanism predates that RC, so it does not gate the release; filing it as a follow-up.Environment
QT_QPA_PLATFORM=wayland.v2026.7.0 (f0959a4).Steps to reproduce
reloadon theanthias.viewerRedis channel, confirm the viewer log is cycling (Showing asset ... (...)every few seconds).stop(orblank) onanthias.viewer.Showing assetlines in the viewer log.Expected: after
stop, no newShowing assetlines (loop paused on current frame); afterblank, the loop pauses and the screen paints black / DPMS-off.Actual: the loop keeps emitting
Showing asset ...(observed 2–3 switches in a 10–12s window well after the command).unblank/playalso don't cleanly restore the expected state.Scope / isolation
next,previous,asset&<id>, andreloadall work — the Redis subscriber is alive and dispatching, so this is isolated to theloop_is_stoppedpause path, not the command bus.blank_display()/stop_playback()insrc/anthias_viewer/__init__.pyset the module-levelloop_is_stopped = True(via the dispatch table around L507-518).start_loop()(same module, ~L1530) readsloop_is_stoppedat the top of itswhile True, but keeps callingasset_loop(scheduler).stop_playbackdocstring says was already fixed forstopunderpython -m anthias_viewer— evidently not fully closed, or a second write path still targets the wrong namespace.Impact
Low–medium. These are the UI's pause / screen-off controls (PR #3065). When they no-op, the screen keeps showing content instead of pausing/blanking — no data loss, no crash, core playback unaffected.
Follow-up needed
Confirm on a board with a real connected display before closing: on a headless Wayland board there is no output, so the
_apply_wlr_power(False)(DPMS-off) half ofblankis a no-op there and the loop-pause is the only observable effect — a physical display may behave differently. If it reproduces with a display attached, fix theloop_is_stoppedwrite/read so the subscriber thread's update is seen bystart_loop.Found during full-fleet release QA; verified
stopandblankboth fail to pause whilenext/previous/reloadsucceed.