Commit Graph
6 Commits
Author SHA1 Message Date
ekklesiaandClaude Opus 5 2ff9d47be9 feat: decide the classroom's audio output from what is plugged in
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]>
2026-09-10 08:47:28 -05:00
ekklesiaandClaude Opus 5 87b55761c6 feat: give the classroom a desktop instead of a shell
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]>
2026-09-10 08:35:12 -05:00
ekklesiaandClaude Opus 5 255072ac94 feat: settle Chrome's window, crash bubble and password prompts
Three things a volunteer should never have to see.

Sway was drawing its own title bar above Chrome's tab strip, which
already carries the window controls. Verified on a real session: Chrome
is an xdg_shell client with app_id "google-chrome" and sway was giving
it border "normal". A scoped rule removes the compositor decoration
only — Chrome keeps its tabs and address bar, stays a normal window, and
still maximises and minimises. A class rule covers an XWayland fallback.
Nothing else changes: the only other window in this classroom is VLC,
which is already borderless, so no broader rule is warranted.

"Restore pages? Chrome didn't shut down correctly" is suppressed with
--hide-crash-restore-bubble. Note the name. The switch this was going to
use, --disable-session-crashed-bubble, is not present in Chrome 152 at
all — checked against the strings of the installed binary — so it would
have silently done nothing.

That hides the prompt; the profile was still being marked as crashed,
which is the untidy half. Chrome's browser process shuts down cleanly on
SIGTERM, so a shutdown unit now gives it one and waits up to eight
seconds before the session is torn out from under it. Best effort by
construction: a shutdown that will not finish is far worse than a crash
flag.

Password prompts go off with the PasswordManagerEnabled policy, on the
path the classroom already manages. Existing profile and session data
are untouched, and website logins are unaffected: Wonder Ink and YouTube
stay signed in.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-05 00:21:02 -05:00
ekklesiaandClaude Opus 5 af79aba21b feat: minimize and restore windows the way a desktop does
The scratchpad technically minimized Chrome, but sway hands scratchpad
windows back floating, so restoring gave a draggable window instead of
the maximized one the user put away. Park windows on a hidden workspace
as ordinary tiled containers instead, and move them back to the visible
workspace on restore.

classroom-window carries the whole state machine, so the dock buttons
and Super+M share one implementation:

  not running  -> launch
  unfocused    -> focus
  focused      -> minimize
  minimized    -> restore, tiled and maximized

Fullscreen is dropped on the way out, since a container parked while
still fullscreen keeps drawing over everything else. floating disable on
the way back also rescues windows left floating by the old scratchpad
path.

Super+Shift+M restores the newest minimized window, so nothing can get
stranded on the hidden workspace.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-04 17:06:43 -05:00
ekklesia d05f5bf909 feat: reserve classroom shell and restore dock interaction 2026-09-02 20:26:12 -05:00
ekklesia b1ff7a31ce feat: establish classroom 0.1.0 baseline 2026-08-31 18:12:06 -05:00