fix(docking): make workspace and lid transitions atomic
All checks were successful
Check / eval (push) Successful in 3m19s
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:
@@ -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`
|
||||
|
||||
@@ -19,6 +19,28 @@ Template:
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-13 — #100 dock transition recovery (this commit)
|
||||
- **Task:** Fix the real T14s dangling workspace, closed-lid cable-removal
|
||||
suspend/apparent crash, and BenQ audio miss after 7ebfab4.
|
||||
- **Did:** Added one atomic dock/internal-first undock helper; the IPC watcher
|
||||
owns a verified low-level lid inhibitor through physical lid-open, with
|
||||
validated stale-process cleanup. `monitoradded` now debounces a settled
|
||||
PipeWire/WirePlumber reprobe then picks an available dock sink; generic
|
||||
audio events never override a manual choice. Named clamshell profiles share
|
||||
the safe transition. Replaced the fallback VM tool with a bounded hotplug
|
||||
workspace/output/inhibitor test and strengthened generated-artifact guards.
|
||||
- **Verified:** V2 — `nix flake check --no-build`; targeted docking-UX,
|
||||
option-docs, and template-SoT builds; and
|
||||
`nix build --impure -f tools/monitor-fallback.nix --no-link -L` all green.
|
||||
The KVM guest proved atomic workspace handoff, internal-first restoration,
|
||||
inhibitor retention with the simulated lid closed, and release on lid-open.
|
||||
The harness restores the DRM output before deleting QEMU's last synthetic
|
||||
headless output because that backend-specific zero-output state aborts
|
||||
Hyprland before a usable removal lifecycle is delivered.
|
||||
- **Pending:** V3 exact closed-lid BenQ round 4 in HARDWARE-QUEUE. No
|
||||
real-hardware or real monitor-audio claim.
|
||||
- **Next suggestion:** run V3 round 4, then take installer #91.
|
||||
|
||||
## 2026-07-13 — Live ISO hardware findings queued (#91–#99)
|
||||
- **Task:** Transcribe Bernardo's Acer Aspire M5-481T install/session notes
|
||||
and installer failure photo into the executable queue.
|
||||
|
||||
@@ -110,6 +110,15 @@ iteration would otherwise rediscover.
|
||||
check onto the whole return set or lazy attr access skips it.
|
||||
|
||||
## Design invariants
|
||||
- **Dock transitions are ordered safety operations (#100):** dock in one
|
||||
`hyprctl --batch` (external on → every internal workspace moved → focus
|
||||
external → internal off); undock enables internal *before* moving anything.
|
||||
The Hyprland watcher, not a shell-pipeline subshell, owns a low-level
|
||||
`handle-lid-switch` inhibitor until the lid is physically open; startup
|
||||
cleans a validated stale process group. HDMI availability may appear only
|
||||
as `change:sink`, so fresh `monitoradded` is the intent boundary for the
|
||||
settled PipeWire/WirePlumber reprobe + sink pick; generic audio changes must
|
||||
not override a manual in-dock speaker choice.
|
||||
- **Waybar status is never color-only** (item 28 sweep, iteration #69):
|
||||
every status module must distinguish its states by SHAPE (glyph) or
|
||||
presence (self-hide), never color alone — good/warn/bad collapse under
|
||||
|
||||
Reference in New Issue
Block a user