fix(docking): make clamshell hotplug safe and discoverable
All checks were successful
Check / eval (push) Successful in 3m32s

Real dock QA exposed pointer-bound menus, an absent default rescue watcher, the unsafe zero-output panel-off path, missing keyboard/audio hotplug coverage, and unpainted new outputs.

Route Rofi to the focused output; replace panel disable with safe workspace migration; always run and reconnect the display watcher and repaint hotplugged outputs; expose a default per-device keyboard picker; handle audio card availability transitions.

Verified: V1 — nix flake check --no-build; checks.docking-ux real Home Manager artifact build; option-docs/template-sot; Nix parse, py_compile, and git diff --check. V2 unavailable: no readable KVM. V3 pending in agent/HARDWARE-QUEUE.md.
This commit is contained in:
2026-07-13 11:53:01 +01:00
parent 16846786e2
commit 7ebfab4bd4
15 changed files with 357 additions and 171 deletions

View File

@@ -416,14 +416,9 @@ Design/decision records and a running log of shipped work (items marked
`useDefaultOutputDevice` defaults true and verified live — with a
stream playing, EE's output links moved to a fake dock-named null sink
and back on unload. Unplug = WirePlumber priority fallback to built-in.
Docked menu rows shipped alongside: Display gains "Laptop screen off ·
everything → <ext>" (live-only `keyword monitor <eDP>,disable` — a
persisted disable could black-screen an undocked boot), "Screen on ·
<name>", "Move workspace · → next monitor"
(`movecurrentworkspacetomonitor +1`), "Swap workspaces"
(`swapactiveworkspaces`, exactly-2 gate); Audio gains a self-gated
"Send output → <dock sink>" quick row (the watcher's manual override).
Real-dock V3 for both in HARDWARE-QUEUE.
Docked menu rows shipped alongside (the original panel-disable action is
superseded by the hardware-QA correction below); Audio has a self-gated
"Send output → <dock sink>" quick row plus the full output picker.
✓ **Undock blackout rescue (2026-07-12):** Bernardo asked whether the
panel comes back if you undock while "Laptop screen off" — VM answer
(tools/monitor-fallback.nix, full softGL desktop): **no**, Hyprland
@@ -439,10 +434,28 @@ Design/decision records and a running log of shipped work (items marked
survives 5/5, so it's the state, not headless removal; monitor-
disconnect crashes are a known upstream class). Posture: rescue ships
as defense-in-depth (recovers every surviving case; worst case on real
DRM is session-to-greeter on the re-lit panel, not a black brick);
V3 decides if the menu row needs a mirror-based rework. Also fixed in
the rescue: `grep -c .` exits 1 at count 0 — an `||`-guard on that
DRM is session-to-greeter on the re-lit panel, not a black brick).
Also fixed in the rescue: `grep -c .` exits 1 at count 0 — an `||`-guard on that
pipeline silently disabled the rescue exactly when it mattered.
✓ **Docking hardware-QA correction (2026-07-13):** real clamshell QA
confirmed every warned residual: Rofi's default `monitor=-5` followed
the mouse pointer onto the hidden laptop workspace; the profile watcher
(and blackout rescue) was not launched with default
`displayProfiles = {}`; disabling eDP then unplugging failed to restore
it, with application loss consistent with the known zero-output crash;
audio did not arrive as a new sink; and the keyboard picker was disabled
by an empty optional-candidate list. Correction: Rofi targets the focused
output (`monitor=-1`); interactive **Dock mode** explicitly moves eDP
workspaces/focus to the external but keeps eDP logically active as the
unplug fallback; the reconnecting display watcher runs unconditionally
and watches through the racy removal snapshot; keyboard hotplug runs by
default, searches the pinned XKB catalog without D-Bus, persists
per-device, and has a manual System Keyboard path; dock audio handles new sinks and
card/profile/port-availability changes while ignoring volume/default
changes so manual picks stick; and monitor-added re-applies the current
awww wallpaper after the output settles (new outputs do not inherit the
existing image). `checks.docking-ux` guards the generated default-session
artifacts; the corrected real sequence remains V3.
✓ **Parallel fingerprint-or-password (2026-07-12, Bernardo promoted
from PROPOSED):** `nomarchy.hardware.fingerprint.parallel` (default
**true** — the better UX is what opting into fingerprint PAM gets you;