test(docking): prove the keyboard-restore path; the reload clobber is real
All checks were successful
Check / eval (push) Successful in 3m10s
All checks were successful
Check / eval (push) Successful in 3m10s
The last unproven half of bec826b, and it needed a keyboard that stays behind
when the dock leaves. The dev box's by-tech hangs off the BenQ's own hub, so
it always walked away with the cable — a Logitech K400 with its receiver in
the laptop is the real case, and Bernardo happened to plug one in.
Both halves measured on hardware (dev box, 2026-07-14):
- PRIMARY: across a real unplug + the fixed transition, the K400 kept its
remembered `us`. Panel back, layout intact.
- CONTROL: a bare `hyprctl reload` with no restore took the same board from
`us` to the session's `gb`.
The control matters more than the pass. That reload clobbers runtime
`device[<name>]:kb_layout` was an inference from the mechanism when
restore_keyboards was written — reasonable, but unmeasured, and this session
has already shown what unmeasured reasoning about this watcher is worth.
It holds: without that call the undock's escalation would have silently
broken the layout of every keyboard that outlives the cable, trading a black
panel for a keyboard that types the wrong characters at the password prompt.
Verified V2 again after the comment/doc edits: nix flake check --no-build,
checks.docking-ux, shellcheck clean.
Round 8 now asks only for what is still open: relogin (the watcher calls the
transition by baked store path, so exec-once means it runs the old build
until then) and repetition — 5+ unplugs, one with the lid shut.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -49,19 +49,21 @@ the **T14s** (webcam case).
|
||||
The transition now escalates to `reload` when the keyword proves inert,
|
||||
re-asserts the rule, and restores per-device keyboard layouts (a reload
|
||||
drops runtime `device[…]:kb_layout` keywords).
|
||||
**Already proven on hardware:** one real unplug, invoking the fixed
|
||||
`nomarchy-display-transition undock eDP-1` directly with the watcher
|
||||
paused — panel on and workspaces 1–3 home in 1.8s, journal
|
||||
`keyword=inert escalate=reload` → `enable=via-reload` → `result=ok`.
|
||||
**Already proven on hardware** (2026-07-14, two real unplugs invoking
|
||||
the fixed `nomarchy-display-transition undock eDP-1` directly with the
|
||||
watcher paused): panel on and workspaces 1–3 home in 1.8s, journal
|
||||
`keyword=inert escalate=reload` → `enable=via-reload` → `result=ok`; and
|
||||
the keyboard-restore path with a Logitech K400 whose receiver is in the
|
||||
laptop — it kept its remembered `us` across the undock, while a control
|
||||
`hyprctl reload` with no restore dropped it to the session's `gb`
|
||||
(so `restore_keyboards` is load-bearing, not insurance).
|
||||
**What is NOT proven, and is this round:** the *watcher-driven* path
|
||||
(the running watcher calls the transition by baked store path, so it
|
||||
only picks the fix up at relogin — the round-5 trap), and repetition.
|
||||
**Re-check:** relogin (mandatory — see below), dock, then unplug the
|
||||
cable **at least five times**, plus once with the lid shut and once
|
||||
while an external keyboard is plugged into the *laptop* (not the dock's
|
||||
hub) — that last one is the only check on the keyboard-restore path.
|
||||
**Pass:** the panel comes back every time with workspaces intact, the
|
||||
external keyboard keeps its remembered layout, and `journalctl --user
|
||||
cable **at least five times**, plus once with the lid shut.
|
||||
**Pass:** the panel comes back every time with workspaces intact, and
|
||||
`journalctl --user
|
||||
-t nomarchy-display-transition -t nomarchy-display-watch --since
|
||||
'-10 min'` shows `result=ok` for each undock with **no**
|
||||
`result=enable-failed`. `keyword=inert escalate=reload` on every undock
|
||||
|
||||
@@ -41,16 +41,19 @@ Template:
|
||||
around it will keep confirming whatever story you bring. The probe cost 10
|
||||
minutes and killed two rounds of theory.
|
||||
- **Verified:** V3 (partial) — the fixed `nomarchy-display-transition undock
|
||||
eDP-1` driven through a real unplug on the dev box: panel on, workspaces
|
||||
eDP-1` driven through two real unplugs on the dev box: panel on, workspaces
|
||||
1–3 home, 1.8s, `keyword=inert escalate=reload` → `enable=via-reload` →
|
||||
`result=ok`. Plus V2: `nix flake check --no-build` all pass;
|
||||
`checks.docking-ux` + `checks.dock-audio` pass; shellcheck clean on
|
||||
`result=ok`. Keyboard-restore proven too, on a K400 whose receiver is in the
|
||||
laptop (so it survives the cable): kept its remembered `us`, while a control
|
||||
bare `hyprctl reload` dropped it to the session `gb` — the clobber was an
|
||||
inference until measured, and it makes `restore_keyboards` load-bearing.
|
||||
Plus V2: `nix flake check --no-build` all pass; `checks.docking-ux` +
|
||||
`checks.dock-audio` + `monitor-fallback.nix` pass; shellcheck clean on
|
||||
display-transition (profile-watch's lone SC2125 is pre-existing).
|
||||
- **Pending:** HARDWARE-QUEUE round 8 — the *watcher-driven* path needs a
|
||||
relogin (exec-once, baked store path) and repetition; the keyboard-restore
|
||||
path is entirely untested (dev box's keyboard hangs off the dock hub, so it
|
||||
leaves with the cable). New BACKLOG #114 (PROPOSED): tuigreet ignores
|
||||
per-device layouts.
|
||||
relogin (exec-once, baked store path) and repetition (5+ unplugs, one with
|
||||
the lid shut). New BACKLOG #114 (PROPOSED): tuigreet ignores per-device
|
||||
layouts.
|
||||
- **Next suggestion:** #114, or the dock direction's unverified panel-off
|
||||
(it disables the panel trusting hyprctl's exit code — same class, latent).
|
||||
|
||||
|
||||
@@ -170,10 +170,13 @@ let
|
||||
}
|
||||
# `hyprctl reload` re-reads the config, and every runtime keyword dies
|
||||
# with it — including the `device[<name>]:kb_layout` the keyboard watcher
|
||||
# applies to an external board. The remembered choices live in the
|
||||
# in-flake state, so `restore` is authoritative and cheap; without this a
|
||||
# reload would silently drop an external keyboard back to the session
|
||||
# layout mid-undock.
|
||||
# applies to an external board. Measured on hardware 2026-07-14: a bare
|
||||
# reload took a keyboard remembered as `us` straight back to the session's
|
||||
# `gb`, so without this the undock's escalation would silently break the
|
||||
# layout of any keyboard that stays behind when the dock leaves (a
|
||||
# wireless receiver in the laptop; only boards on the dock's own hub are
|
||||
# unaffected, and only because they leave with it). The remembered
|
||||
# choices live in the in-flake state, so `restore` is authoritative.
|
||||
restore_keyboards() {
|
||||
hyprctl devices -j 2>/dev/null | jq -r '.keyboards[].name' 2>/dev/null \
|
||||
| while IFS= read -r kb; do
|
||||
|
||||
Reference in New Issue
Block a user