Files
ansible/roles/pi_kiosk/README.md
Martin Bauer ea00e045f9 Switch musicdolphin's screen from the IR remote's power key
pi_kiosk installs kiosk-screen on|off|toggle|status, which switches the monitor via
DPMS on the kiosk's X display (the Dell P2419H has no HDMI-CEC). Turning it back on
also turns DPMS off again, as .xinitrc does, so the screen never blanks by itself.

musicdolphin's backend config runs `kiosk-screen toggle` for the power key (the new
screen: section, MusicMouse 2d0caeb). config.yml is install-once, so the running host
is changed by hand the same way.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 16:13:29 +02:00

93 lines
4.7 KiB
Markdown

# pi_kiosk
Turns a Pi with a monitor attached into a full-screen browser display: an autologin
console user runs `startx`, whose `.xinitrc` starts Openbox and then the browser pointed
at `pi_kiosk_url`, relaunching it if it ever exits. If X itself crashes, `.bash_profile`
restarts it.
Vars:
- `pi_kiosk_user` (default `kiosk`) - the account that autologs into tty1.
- `pi_kiosk_url` (default `http://localhost:8080`) - what the browser shows.
- `pi_kiosk_browser` (default `chromium`) - `chromium` or `firefox`, see below.
- `pi_kiosk_mode` (default `kiosk`) - `kiosk` or `debug`, see below.
Meant to run alongside `pi_musicmouse` on the same host when it's serving the page
locally (the default `pi_kiosk_url`), gated in `mediapis.yml` by `mediapi_has_monitor`.
## Switching the screen off
`/usr/local/bin/kiosk-screen on|off|toggle|status` switches the monitor through DPMS:
X stops the HDMI signal and the monitor goes into standby, while the browser and
whatever is playing carry on. It is there for the MusicMouse backend, whose `screen:`
config section runs `kiosk-screen toggle` on the IR remote's power key, and works the
same as root over ssh. HDMI-CEC would switch a TV off properly, but musicdolphin's Dell
P2419H does not speak it, and every monitor understands losing its signal.
## Why Chromium
Firefox was the original choice and lost on measurement. Same page, same machine, idle:
**Firefox 24.2% of a core, Chromium 11.4%**. Two reasons, and they compound:
- Chromium here comes from `archive.raspberrypi.com` (versions carry a `+rpt` suffix)
and is patched by Raspberry Pi for this board's V3D GPU. Debian also ships a much
older `chromium`; pinning the wrong archive would quietly undo the point of choosing
it.
- The whole userland on these images is 32-bit `armhf` on a 64-bit kernel
(`dpkg --print-architecture` says `armhf`, `uname -m` says `aarch64`), and Firefox
fares worse than Chromium on that target.
The flags in `.xinitrc` are not decoration: `--use-gl=egl`,
`--enable-gpu-rasterization`, `--ignore-gpu-blocklist` and `--enable-zero-copy` are
what keep rasterization on the GPU. Chromium's blocklist does not recognise this driver,
so without `--ignore-gpu-blocklist` it quietly falls back to software.
`pi_kiosk_browser: firefox` still works and is the fallback if a Chromium update ever
regresses.
## Why there is a window manager
This role used to run no WM at all, on the theory that Firefox is the only X client and
`--kiosk` makes it full-screen by itself. It doesn't. `--kiosk` *asks* to be
full-screen, over EWMH, and with no window manager running there is nobody to answer:
Firefox falls back to its default window size in the top-left corner. On the 1920x1080
monitor on musicdolphin that came out as a 1280x972 window with black bands down the
right edge and along the bottom - looking for all the world like an overscan problem,
which it is not. Openbox answers the request and otherwise stays out of the way.
## Debug mode
`pi_kiosk_mode: debug` turns the device's own screen into something you can work on:
- Firefox runs as an ordinary window with its chrome, so the URL bar and devtools are
reachable, and it is **not** relaunched when you close it.
- The pointer is visible (no `-nocursor`, no `unclutter`).
- Openbox is the session leader. Right-click the desktop for a menu with a terminal,
both ways of opening the page again, and "End this X session", which drops back to
the autologin loop and starts a fresh one.
- `xterm`, `x11-utils`, `mesa-utils`, `xdotool` and `scrot` get installed, so
`xwininfo`, `xprop`, `glxinfo`, `glxgears`, synthetic input and screenshots are all
available over ssh.
- Chromium gets `--remote-debugging-port=9222`, bound to 127.0.0.1. `curl
localhost:9222/json` lists the tabs, and the DevTools protocol will drive and measure
the page properly - which beats firing XTEST key events at a window and hoping they
land, as they only do about half the time. (The menu's Terminal entry runs
`x-terminal-emulator`, which on the Pi OS image is `zutty`, not the xterm we
install - both work; xterm is the fallback if the alternatives link ever points
somewhere that doesn't.)
Switch a host over in `host_vars`, or for one run:
```sh
just run mediapis.yml musicdolphin -e pi_kiosk_mode=debug
just run mediapis.yml musicdolphin -e pi_kiosk_mode=kiosk
```
Either way the session restarts itself: the templates notify the getty handler, and
restarting `getty@tty1` takes X down with it because Xorg lives in that unit's cgroup.
Going back to `kiosk` does not uninstall the debug packages; they are small and inert.
niri was considered instead of Openbox, but isn't packaged for Debian Bookworm yet (no
official apt package, only third-party `.deb`s or a from-source Rust build) - revisit
once it is.