The room that prompted this had a television on HDMI with working PCM
audio and nothing in the analog jack, and WirePlumber chose analog. A
teacher who corrected it by hand then had to restart the browser before
any sound came out.
The policy is a pure function so it can be tested against that room
rather than against a machine: an unavailable port is not a candidate,
an analog port merely existing is not evidence of a cable, and an
explicit AUDIO_OUTPUT overrides the lot. Twelve cases, the real room
among them.
The daemon follows PipeWire's own event stream rather than polling, and
moves streams that are already playing, which is the part that stops a
teacher having to close and reopen the browser.
Co-Authored-By: Claude Opus 5 <[email protected]>
The whole appliance UI is now configuration for a desktop Debian already
ships: a Plasma 6.3 session with a colour scheme, a look and feel package
that builds the bar, window rules, and KDE's own Kiosk restrictions.
Two things were measured rather than assumed, and both changed a decision.
Plasma restarts a crashed panel three times a minute and then gives up,
which is the failure a classroom has already had. Four lines of systemd
drop-in make it unconditional; the panel then survived eight SIGKILLs a
second apart, back each time in 2.4s.
Plasma draws a minimised task and a background task identically, so the
five states the room needs cannot all be shown. Rather than write a task
manager, the classroom removes minimise: clicking a launcher always means
show me this.
Co-Authored-By: Claude Opus 5 <[email protected]>
The development host is a VM without /dev/kvm, so a candidate desktop
cannot be given a virtual machine here. It gets a systemd container
instead, with the session nested inside a headless sway so that grim can
photograph it and sway's IPC can aim a real pointer at it.
Plasma 6.3.6 comes up in it, software-rendered, at 1920x1080.
Co-Authored-By: Claude Opus 5 <[email protected]>