fix(docking): make workspace and lid transitions atomic
All checks were successful
Check / eval (push) Successful in 3m19s

Restore the old flake's external-only workspace handoff, protect closed-lid cable removal with a verified low-level logind inhibitor, and use monitor-added as the settled audio reprobe boundary.

Verified: V2 — nix flake check --no-build; docking-ux, option-docs, and template-sot checks; KVM tools/monitor-fallback.nix lifecycle test.

V3 pending: closed-lid BenQ round 4 in agent/HARDWARE-QUEUE.md.
This commit is contained in:
2026-07-13 13:56:54 +01:00
parent cffe432912
commit 2a34c7398b
12 changed files with 654 additions and 292 deletions

View File

@@ -11,27 +11,32 @@ the **T14s** (webcam case).
## Any machine (dev box is fine)
- [ ] **Docking correction round 3 (2026-07-13 hardware-QA follow-up)**
prior result: lid-close stayed awake, but SUPER+M rendered on the
hidden laptop workspace; the keyboard never prompted; audio stayed
on speakers; the old laptop-off action lost some applications and
abrupt undock left eDP black. After updating to the commit carrying
this entry and rebuilding Home Manager, start with the laptop open
and play audio. Close the lid and plug the monitor/keyboard: SUPER+M
must render on the external focused workspace; the new keyboard must
ask for a searchable XKB layout (or set/change it at System
Keyboard); audio must toast and move to the monitor. System Audio
Output device remains the manual fallback; the current wallpaper must
cover the external output/workspaces within ~2s. Open Display and choose
**Dock mode**: all eDP workspaces/windows move intact to the external
and focus follows; no terminal/application exits. Yank the cable: the
internal panel is already the logical fallback, lights immediately,
and the moved workspaces/windows survive. Replug then manually choose
speakers: volume/mute changes must not force the monitor again; only a
fresh replug should. If audio still misses, capture `pactl subscribe`
during plug plus `pactl --format=json list sinks` while docked. If the
menu is still misplaced, capture `hyprctl monitors -j` immediately
before SUPER+M (the `.focused` field is the discriminator).
- [ ] **Docking recovery round 4 (#100, closed-lid BenQ sequence)** after
updating to the commit carrying this entry, run `nomarchy-home` and
relogin. With the lid open, put visible windows on at least workspaces
1, 2, and 3 and start audio; plug the BenQ GW2790QT. **Pass on plug:**
wallpaper appears, audio toasts and moves to a BenQ/GPU HDMI sink, and
`journalctl --user -t nomarchy-dock-audio -n 10` shows
`trigger=monitoradded` plus `selected=…` (not only a card event). Open
System Display **Dock mode**. **Pass on dock:** every workspace and
window is on the BenQ, focus follows, eDP is disabled in `hyprctl
monitors all -j`, and `systemd-inhibit --list` shows Nomarchy holding
`handle-lid-switch` for “Safe dock/undock display transition”; there is
no dangling laptop workspace and no application exits. Close the lid;
audio/session must stay awake. While still docked, manually choose the
speakers and change volume/mute: it must stay on speakers. Unplug the
BenQ **with the lid still closed**, wait 10 seconds, then open it.
**Pass on undock:** no suspend/crash/hard reset, eDP is already active,
workspaces 1/2/3 and their windows are intact on it, and the inhibitor
disappears only after lid-open. `journalctl -b --since '-5 min'` must
contain no cable-removal `systemd-logind: Suspending...`. Finally close
the undocked lid normally: the laptop must suspend, proving policy was
restored. Wake it, replug the BenQ: that fresh plug must move audio back
to HDMI (manual speakers do not survive a physical replug). If any step
fails, capture `journalctl --user -t nomarchy-display-watch -t
nomarchy-display-transition -t nomarchy-dock-audio --since '-10 min'`,
`systemd-inhibit --list`, `hyprctl monitors all -j`, `hyprctl workspaces
-j`, and `pactl --format=json list sinks` before changing state again.
- [ ] **Parallel fingerprint-or-password on the real reader** (AMD dev
box, 2026-07-12) — with a finger enrolled and
`fingerprint.pam = true` (parallel is the default): `sudo -k true`