tools: preview the plymouth splash unprivileged; #137 attempt 1 reverted
All checks were successful
Check / eval (push) Successful in 3m49s
All checks were successful
Check / eval (push) Successful in 3m49s
Answering "how do I give you root": you don't. tools/plymouth-preview.sh renders the splash — LUKS dialog included — into X11 windows in ~10s with no reboot, no root and no DRM: - unshare -rm = user + mount namespace; every mount dies with it. - /run/plymouth is BOTH the socket dir and the compiled-in plugin path (`strings plymouthd` → /run/plymouth/plugins/), so we bind a writable dir over it AND recreate its symlinks — miss those and plymouth can't find x11.so, silently skips X11 and reaches for a tty. - never pass --tty (main.c:2133 takes the X11 path only while default_tty is unset); /dev/dri is masked so a preview physically cannot mode-set a real output — which matters on a docked session (#127). - PLY_CREATE_FAKE_MULTI_HEAD_SETUP fakes 800x600 + 640x480 heads. - debug wants plymouth.debug=stream: — `file:` buffers and yields nothing. What it proved immediately: with a STABLE two-head canvas the current theme centres correctly on both heads. So the geometry is fine and #137 really is the timing bug (positions frozen at parse time vs a canvas that resizes when a head arrives) — recorded in the item. And it caught my own fix: hoisting positions into layout() rendered the background on both heads and nothing else — no logo, no bar — with NO parse error logged. Reverted rather than shipped, because that script draws the passphrase box on an encrypted machine. #137 carries the failure, the prime suspect (plymouth script scope: assignment lands in `local` unless the name already exists) and the fast edit/render loop for the next attempt. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -214,20 +214,48 @@ the existing `refresh_callback` (already running at 50 fps) whenever
|
||||
included), entry, lock, any live bullets, progress box/bar. Keep it a
|
||||
canvas-change check, not an every-frame recompute.
|
||||
|
||||
**Testing — the rig exists, and it needs root.** nixpkgs' plymouth ships
|
||||
`x11.so`, and plymouth has a built-in fake dual-head mode:
|
||||
`PLY_CREATE_FAKE_MULTI_HEAD_SETUP=1` (`renderers/x11/plugin.c:294`) creates
|
||||
800×600 + 640×480 heads, so the splash can be rendered in a window with no
|
||||
DRM and no reboot. Caveat: that fake path builds both heads up front, so it
|
||||
proves *rendering and centring*, not the canvas-change bug itself — for that,
|
||||
plug/unplug while the splash is up, or compare a boot with and without the
|
||||
external. `plymouthd` wants root and its theme comes from
|
||||
`/etc/plymouth/plymouthd.conf`, so this needs a sudo session.
|
||||
**The rig works, needs no root, and is in `scratchpad/ply-rig.sh`** (recipe
|
||||
below — rebuild it, it is ~20 lines). Rendered on the dev box 2026-07-16:
|
||||
|
||||
**Do not ship this blind:** the same script draws the **LUKS passphrase box**,
|
||||
this machine is encrypted, and a script that fails to parse leaves a prompt you
|
||||
cannot see. Pass = with the rig, a two-head render centred on both; then a real
|
||||
docked boot + shutdown, undocked unchanged.
|
||||
- `unshare -rm` gives a user + mount namespace: root *in there* only, every
|
||||
mount invisible to the real system and gone when it exits.
|
||||
- `/run/plymouth` is BOTH the daemon's socket dir **and** its compiled-in
|
||||
plugin/theme path (`strings plymouthd` → `/run/plymouth/plugins/`). Bind a
|
||||
writable dir over it **and recreate its three symlinks** (`plugins`,
|
||||
`themes`, `plymouthd.defaults` → `/etc/plymouth/…`) or plymouth cannot find
|
||||
`x11.so`, silently skips X11 and reaches for a tty.
|
||||
- **Do not pass `--tty`**: `main.c:2133` only takes the X11 path while
|
||||
`default_tty` is unset. Bind an empty dir over `/dev/dri` too — with X11
|
||||
first in the renderer order (`ply-renderer.c:283`) DRM is never used, and the
|
||||
mask makes that a guarantee rather than a hope.
|
||||
- `PLY_CREATE_FAKE_MULTI_HEAD_SETUP=1` → 800×600 + 640×480 windows.
|
||||
`plymouth show-splash`, then `plymouth ask-for-password` renders the LUKS
|
||||
dialog. Debug: `--kernel-command-line="plymouth.debug=stream:/path splash"`
|
||||
(**`stream:`**, not `file:` — `file:` buffers and you get nothing).
|
||||
- Fast loop: copy the theme into the rig's `themes/` and sed its `.plymouth`
|
||||
`ScriptFile=`/`ImageDir=` to the copy — then editing the script is a 10s
|
||||
render instead of a 3min `nixos-rebuild`.
|
||||
|
||||
**What the rig already proved (2026-07-16):** with a *stable* two-head canvas
|
||||
the **current** theme centres correctly on both heads — logo and progress bar
|
||||
each in their own head's middle. So the geometry is not the bug, which is the
|
||||
evidence for the timing diagnosis above. The fake path builds both heads up
|
||||
front, so it cannot reproduce a canvas *change*: for that, plug/unplug while
|
||||
the splash is up, or compare a boot with and without the external.
|
||||
|
||||
**Attempt 1 failed, and the rig caught it — that is the point.** Hoisting the
|
||||
positions into a `layout()` called from `refresh_callback` rendered the
|
||||
background on both heads and **nothing else**: no logo, no progress bar. The
|
||||
script plugin logs `starting boot animation` and **no parse error**, so it
|
||||
fails *silently* — reverted rather than shipped (that script draws the LUKS box
|
||||
on an encrypted machine). Next session: bisect with the fast loop. Prime
|
||||
suspect is scope — plymouth script assigns into `local` unless the name already
|
||||
exists, so a `logo.image = …` inside a function may not be the `logo` the rest
|
||||
of the script sees, even though the same pattern works in `update_progress_bar`.
|
||||
Test that hypothesis *first*, in isolation, before rewriting anything.
|
||||
|
||||
Pass = with the rig, a two-head render centred on both **plus the password
|
||||
dialog visible**; then a real docked boot + shutdown, undocked unchanged.
|
||||
|
||||
### 143. Rofi keeps the selected *row number* when the search changes, so the highlight lands on an unrelated entry
|
||||
|
||||
|
||||
Reference in New Issue
Block a user