Files
enricobuehler 62728317cf The couch gets the other half of the round trip: host power on every client
design/host-actions.md P2. The host has offered sleep/restart/shutdown since
the previous commit; this is where a person can reach them. Every client's host
menu grows the rows right where Wake host appears when the machine is asleep —
finish on the TV, sleep the host from the same menu that woke it.

One shared core: pf_client_core::host_actions holds the discovery read, the
id-only invoke, and a process-wide TTL cache the console, the GTK page and the
Windows tile all read, so three shells cannot end up disagreeing about what a
host offers. Every shell warms it on a refresh tick it already had.

Discovery is PRE-fetched, never fetched when a menu opens: the console screen
holds a cloned row, and rows that appear under a cursor already moving are a
hazard when two of them shut a machine down. For the same reason the console's
armed state became WHICH row is armed rather than a bare flag — a flag let an
arming press on Forget fire Shut down host. Restart and shut down confirm;
sleep is reversible from the same menu, so it goes on one press. An action the
host says it cannot run right now stays listed, disabled, and says why.

Surfaces: console-UI rows + ConsoleCmd::HostAction with session and Android
dispatch; GTK card menu (plus a card-level Toast) with an AlertDialog confirm;
Windows tile menu, its label built and matched through one function so a menu
whose rows outlived their handlers cannot run a different verb; Android touch
home and Skia console; Apple host card and gamepad options. Unknown ids render
from the host's own title on all of them — a later host action needs no client
release to appear.

Typed close: the Swift hostPower case and the Kotlin host-power token. Without
them, sleeping your own host from the couch reads as a crash on those two
clients.
2026-08-28 23:26:26 +02:00
..