Repository navigation
Conversation
[Medium impact] The PR appears safe to merge, with the previous ordering-test race fixed. SummaryAdds an off-by-default
|
chessing234
left a comment
There was a problem hiding this comment.
flock -w 10 || true keeps going when the lock is not held. blank and wake are supposed to share that lock so a slow blank cannot turn the displays off after a newer wake, and the timeout path skips it.
|
Thanks, that was a hole: the timeout path went ahead without the lock, which is the exact race the lock is there for. The lock is now taken without a timeout, so a wake always runs after the blank in flight and a blank after the wake in flight. Nothing holds it longer than its DDC writes, which the I2C layer bounds, and both processes are started asynchronously by the lock plugin, so a wait never blocks the shell. I checked this on the hardware by holding the lock from another process for three seconds: the wake waited the three seconds, then lit the monitor. Also moved the lock and the markers out of the (Prepared with Claude's help; reviewed and posted by me.) |
…k toggle Some HDMI 2.1 monitors drop hotplug when the output is turned off. Behind the lock screen that removes and re-adds the display every ~40 s, each time relighting it, and after a real standby the link needs a long FRL training to come back (40-50 s on a Dell U3224KB with amdgpu 7.2, which gives up after one attempt). Keeping the link up avoids both. With `omarchy toggle ddc-blank` on and only external monitors enabled, `omarchy-brightness-display off|on` now writes the monitor's VCP power mode (D6 = 04/01) through omarchy-brightness-display-ddc instead of dispatching DPMS. The write is unverified, since a monitor that is off no longer answers the read-back, and wakes are throttled to one a second because the lock screen requests one on every key press and pointer move. A built-in panel, a monitor that refuses the command, or a monitor that will not wake falls back to DPMS, so nothing is left lit or dark. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…inst wake `on` picked the monitors to wake from the current monitor set, so a laptop whose lid reopened between the blank and the wake found a built-in panel, sent no DDC wake, and left the external monitors dark: DPMS still read them as on. Each monitor that takes the sleep is now marked asleep under $XDG_RUNTIME_DIR/omarchy-ddc-blank/ and `on` wakes exactly those, which also makes a burst of wake requests write once per monitor without a clock-based throttle, and removes the test that depended on two runs sharing a second. The lock screen starts blank and wake without waiting for one another, so a blank slow to fail over to DPMS could turn the displays off after a newer wake had lit them. Blank and wake now share a lock; the wake waits and has the last word. The test's mock compositor remembers its DPMS state, so a wake after a DPMS blank has something to turn back on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…out a timeout The lock and the asleep markers were falling back to a shared /tmp path, where another user could plant a symlink for the truncating open. They now live in $XDG_RUNTIME_DIR only; without one the toggle is ignored and DPMS blanks as before. The lock file is opened for append, and the lock is taken without a timeout: the timeout path went ahead unserialized, which was the race the lock exists to prevent. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e lock The test slept 0.3 s and assumed the background blank had taken the lock by then; on a loaded runner the wake could finish first and the assertion fail with the lock working. The ddcutil mock now marks when its delayed write begins, and the test waits for that mark before sending the wake. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Refs #13812, #8580, #13129
Problem
Some HDMI 2.1 monitors drop hotplug-detect when the output is turned off. Behind the lock screen that becomes the loop in #13812: the kernel removes the output, the monitor re-asserts hotplug a few seconds later, Hyprland re-adds it lit, the lock plugin re-arms its blank timer, and the monitor turns off again, every ~40 s for as long as the session is locked. On a current AMD kernel the same monitors then need a long HDMI 2.1 FRL link training after a real standby, which amdgpu 7.2 abandons after one attempt, so wake takes 40–50 s of key-mashing (AMD issue 5709). The kernel-side debounce in #13129 stops the loop but makes the slow wake the normal case, and it deadlocked amdgpu once on my machine (details on that PR).
Change
The display never needs to go off for the monitor to sleep. With
omarchy toggle ddc-blankon and only external monitors enabled,omarchy-brightness-display off|onwrites the monitor's VCP power mode (D6 = 04 to sleep, 01 to wake) throughomarchy-brightness-display-ddcinstead of dispatching DPMS. The GPU keeps the link trained, so nothing disconnects, nothing reconnects, and wake is instant. The lock plugin does not change: it already blanks and wakes through that script.omarchy-brightness-display-ddc <monitor> off|onwrites D6 on the monitor's cached bus. The write is unverified (--noverify), because a monitor that is off no longer answers the read-back and a verified write reports failure for a command it applied.omarchy-brightness-display offsleeps every enabled monitor in parallel and falls back to DPMS if any of them refused, so the screen always goes dark. Each monitor that took the sleep is marked asleep under$XDG_RUNTIME_DIR/omarchy-ddc-blank/.onwakes exactly those monitors, whatever the monitor set has become since (a laptop lid reopened before the wake, say), and wakes each once however many wake requests the lock view sends (one per key press and pointer move; a single unlock produced 27omarchy-system-wakeruns in my journal). A monitor that ignores the wake gets a DPMS cycle, which is the modeset it would have had before.$XDG_RUNTIME_DIRonly; without a private runtime directory the toggle is ignored and DPMS blanks as before.displays.confsays so, has a ddc node). A laptop with its lid open keeps DPMS for everything, since the panel has no DDC and mixing the two would leave one display lit.omarchy-toggle-ddc-blankand two menu rows under Toggle, with English catalog entries. Off by default; nothing changes for anyone who does not turn it on.Testing
test/shell.d/brightness-display-test.shgains ten cases against a mock compositor that remembers its DPMS state: DPMS stays the default; the toggle writessetvcp D6 04without a DPMS dispatch; without a runtime directory the toggle is ignored; a built-in panel keeps DPMS; a monitor slept over DDC is woken over DDC even once a built-in panel is back; a burst of wakes writes once and leaves lit displays alone; a refused DDC sleep falls back to DPMS and is then woken with DPMS; an ignored DDC wake gets a DPMS cycle; a wake arriving during a slow, failing blank still ends with the display lit.i18n-test.shand./test/clipass.Disabling outputand zeroConnector … disconnectedlines in the Hyprland log, 6K@60 intact after every wake, picture back within a second of the first key press. The monitor draws 0.5 W asleep, the same as in DPMS standby.Caveats
DDC/CI has to be enabled in the monitor's OSD (it is by default on every Dell I have seen). A monitor without DDC/CI simply never takes the command and gets DPMS as before.
ddcutilis already a dependency ofomarchy-brightness-display-ddc.🤖 Generated with Claude Code