fix(idle): #127 — input wakes the screen compositor-side; revert the clamshell skip
All checks were successful
Check / eval (push) Successful in 3m33s
All checks were successful
Check / eval (push) Successful in 3m33s
The idle brick was never DPMS. Hyprland ships misc:key_press_enables_dpms
and misc:mouse_move_enables_dpms OFF, so hypridle's on-resume was the ONLY
caller of `dpms on` in the session — an idle daemon with the display held
hostage behind it. hypridle then deadlocks on an unfixed upstream bug
(hyprwm/hypridle#171, "Disconnected from pollfd id 1", open since 2025-09,
absent from 0.1.7 and main) and hangs WITHOUT exiting, so Restart=always
never fires and systemd still reports it active (running). Blank + deadlock
= a black seat no keypress can escape. That was the brick: two mundane bugs,
not one exotic DRM state. 19 disconnects in 11 days on the dev box, incl.
the incident day; the compositor is healthy through all of them.
Both options on, so the wake lives in the compositor where no daemon can
lose it — a dead hypridle now costs auto-lock, not the machine. The #127
clamshell DPMS-off skip (060bf52) is therefore reverted: idle blanks again
in every dock/lid state, and the 27" panels stop being held lit all night
under a static lock screen. #135 (an option to opt back in) is retired
unbuilt — there is nothing left to opt into.
TEST B's first run was invalid and nearly bought the wrong answer: it ran
`hyprctl dispatch dpms off` by hand, which no wake path watches, so "input
did not wake it" was guaranteed on any hardware. The undocked control
returning the SAME result — where the theory demanded a difference — is what
exposed it. Driven through hypridle instead, input wakes it in all three
configurations, including clamshell-docked on the sole live output.
Filed from the diagnosis: #146 (hypridle dies silently, systemd calls it
healthy — the surviving bug) and #147 (a re-login leaves session units dead;
graphical-session.target never re-enters, which is why Waybar already runs
from exec-once).
V3 on the incident hardware (AMD dev box, clamshell): hypridle deliberately
stopped, `dpms off` -> keypress woke it in 6s; the identical test before the
options stayed black the full 45s. V1: nix flake check, checks.option-docs,
checks.clamshell-logind, checks.docking-ux, checks.display-profiles; read the
emitted hyprland.conf/hypridle.conf rather than the source.
V3 pending: the fix is proven via runtime `hyprctl keyword`, not yet from our
own Nix — HARDWARE-QUEUE re-checks it after nomarchy-home + relogin.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -622,6 +622,10 @@ Design/decision records and a running log of shipped work (items marked
|
||||
that could not run — two mundane bugs, not one exotic DRM state. The shipped
|
||||
DPMS mitigation may therefore be treating the wrong cause; #127's TEST B is
|
||||
what decides, and it is far safer now that an undock works again.
|
||||
**It did decide, the same day: the hunch was right on both counts** — the
|
||||
mitigation *was* treating the wrong cause and is now reverted, and the brick
|
||||
*was* two mundane bugs (an ordinary blank + a wake path that had died). See
|
||||
"#127 solved" below.
|
||||
- ✓ **The #107 compat shim is pinned (#133, 2026-07-16):** `mkFlake` prefers
|
||||
`state.json` and still accepts the legacy `theme-state.json`, because a
|
||||
machine only migrates on its next menu write — but nothing evaluated a
|
||||
@@ -723,19 +727,44 @@ Design/decision records and a running log of shipped work (items marked
|
||||
`nomarchy-suspend` (hypridle + Power menu). LUKS: unlock session before
|
||||
encrypted hibernate phase so resume is LUKS-only (not hyprlock twice).
|
||||
Menu row self-gates on CanHibernate. V3: HARDWARE-QUEUE bag-carry test.
|
||||
- **Clamshell idle DPMS (#127 mitigation):** after an idle brick (alive
|
||||
machine, black external, undock no eDP, no usable Ctrl+Alt+F3), hypridle
|
||||
**skips DPMS-off** when any laptop internal is present but not enabled.
|
||||
Lock at 5 min unchanged; undocked still blanks at 10 min.
|
||||
**Say clamshell, not "docked" (#136, settled 2026-07-16):** the gate is
|
||||
"an internal exists and is switched off" — the lid shut — and Bernardo
|
||||
confirms the incident was exactly that, laptop closed. Docked with the lid
|
||||
**open** has every output enabled, falls straight through, and still blanks;
|
||||
whether *that* can brick is untested and not claimed either way. The earlier
|
||||
wording ("skip when docked") promised twice the coverage the code has, which
|
||||
is how a recurrence gets misread as a regression.
|
||||
Intentional DPMS-when-clamshell is LATER (BACKLOG) once wake is proven.
|
||||
Tooling kept: `nomarchy-display-wake` / `nomarchy-display-dump`.
|
||||
- ✓ **#127 solved — the idle brick was never DPMS (2026-07-16, AMD dev box):**
|
||||
the clamshell DPMS-off skip (060bf52, and its #136 wording fix) is
|
||||
**reverted**; idle blanks again in every dock/lid state. Hyprland ships
|
||||
`misc:key_press_enables_dpms` and `misc:mouse_move_enables_dpms` **off**, and
|
||||
nothing else in the session calls `dpms on` — so hypridle's `on-resume` was
|
||||
the *only* thing that could un-blank a screen: an idle daemon with the
|
||||
display held hostage behind it. hypridle then deadlocks on an unfixed
|
||||
upstream bug (hyprwm/hypridle#171, "Disconnected from pollfd id 1", open
|
||||
since 2025-09, absent from 0.1.7 *and* main) and hangs **without exiting**,
|
||||
so `Restart=always` never fires and systemd still reports it
|
||||
`active (running)`. Blank + deadlock = a black seat no keypress can escape.
|
||||
That is the brick: two mundane bugs, not one exotic DRM state — the same
|
||||
shape as the #100 latch above.
|
||||
**Evidence, on the incident hardware.** With hypridle driving the blank,
|
||||
input woke it in all three configurations — including clamshell-docked on the
|
||||
sole live output (`nomarchy-display-wake done enabled=1 first=DP-2`), which
|
||||
is the incident's exact geometry. So blanking-while-clamshell is innocent and
|
||||
the gate guarded nothing. Then the decisive run: same box, still clamshell,
|
||||
hypridle **deliberately stopped** (i.e. the brick condition manufactured on
|
||||
purpose), `dpms off` → a keypress woke it in **6 s** with the two options on.
|
||||
The identical test before them stayed black the full 45 s.
|
||||
**Why the first TEST B said the opposite, and the lesson.** It ran `hyprctl
|
||||
dispatch dpms off` **by hand**, which no wake path watches, so "input did not
|
||||
wake it" was guaranteed on any hardware, in any dock state. The tell was the
|
||||
undocked control returning the *same* result where the theory demanded a
|
||||
different one. A test must put the mechanism under test inside the circuit —
|
||||
this one measured a wake path that was never armed, and nearly bought a
|
||||
permanent behaviour cost with the answer.
|
||||
**Why the fix is structural.** The wake now lives in the compositor, where no
|
||||
daemon can lose it; a dead hypridle costs auto-lock, not the machine. #135
|
||||
(an option to opt back into DPMS-when-clamshell) is therefore **retired
|
||||
unbuilt** — there is nothing left to opt into, and the 27" panels stop being
|
||||
held lit all night under a static lock screen.
|
||||
**Still open:** hypridle's silent death is its own bug (~2×/week on this box;
|
||||
no auto-lock is a security cost even when the screen is recoverable), and the
|
||||
incident's dead Ctrl+Alt+F3 remains unexplained — a known co-symptom upstream
|
||||
(hyprwm/hypridle#145) but not accounted for here. Tooling kept:
|
||||
`nomarchy-display-wake` / `nomarchy-display-dump`.
|
||||
- ✓ **Generation prune (#128):** weekly `nomarchy-gen-prune` (system + HM):
|
||||
delete only gens older than **14 days** that are also beyond the **3 most
|
||||
recent past** gens (current always kept). Stock `nix.gc` no longer uses
|
||||
|
||||
Reference in New Issue
Block a user