Proof Portal
Omarchy
ProbeLabs65 findings · 95 requirementsA proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.
No way to opt out of lock-time display blanking in 4.0 (OMARCHY_LOCK_ONLY dropped, no shell.json equivalent)
Reported by gigq · filed Aug 19, 2026 · open at source
At a glance
- 1 · What is claimed?
- Only the report text below — no validator has restated it as checkable claims yet.
- 2 · What does it affect?
- 3 · Is it reproducible?
- No validation has been run yet.
- 4 · What remains unclear?
- Not validated yet: no claims, no reproducer.
- 5 · What happens next?
- Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. So far: in the audited area (lock) — decided by agents · verified; not a duplicate of another report — decided by agents · verified; matches no known issue — decided by agents · verified. The outcome (valid, duplicate, not a bug, …) is not decided yet. See the decision.
Original report
Summary
Omarchy 4.0 blanks the displays ~5s after every lock, and there is no way to opt out — no shell.json setting, no plugin override, and the pre-4.0 escape hatch (OMARCHY_LOCK_ONLY) is now dead code.
Pre-4.0, the shipped hypridle.conf deliberately locked without powering displays off, and said so in its own comments. That behavior is no longer reachable.
What changed
The hypridle.conf that Omarchy shipped (still on disk at ~/.config/hypr/hypridle.conf after the 4.0 upgrade, now orphaned since hypridle was removed):
general {
lock_cmd = OMARCHY_LOCK_ONLY=true omarchy-system-lock # lock without powering off the displays.
before_sleep_cmd = OMARCHY_LOCK_ONLY=true omarchy-system-lock
}
# Show the black lock screen after 30 minutes while leaving display power on.
listener {
timeout = 1800
on-timeout = pidof hyprlock || OMARCHY_LOCK_ONLY=true omarchy-system-lock
}In 4.0, OMARCHY_LOCK_ONLY is read by nothing. grep -rn OMARCHY_LOCK_ONLY /usr/share/omarchy/ returns zero hits; the only matches on my system are my own leftover config files.
Blanking moved into the shell's lock plugin and became unconditional — shell/plugins/lock/Service.qml:
:136 lockRequested = true
armBlankTimer() // unconditional, on every lock
:172 function runBlank() { // no config gate
if (!blankProcess.running) blankProcess.running = true
}
:410 Process { id: blankProcess
command: ["bash","-c","omarchy-brightness-keyboard off; omarchy-brightness-display off"] }
:415 Timer { id: idleBlankTimer; interval: 5000
onTriggered: if (root.lockRequested && !root.authenticatingPassword) root.runBlank() }Why there's no workaround
- No config knob.
runBlank()has no gate; nothing inshell.jsonreaches it. - No plugin override.
shell/services/PluginRegistry.qml:599— "Third-party plugins never shadow first-party ids" — and the check at :603 rejects the entireomarchy.*namespace. - No PATH shim.
/usr/share/omarchy/binsits ahead of both~/.local/binand~/.local/share/omarchy/binin the session PATH, so a wrapper aroundomarchy-brightness-displaynever gets resolved.
That leaves patching /usr/share/omarchy/shell/plugins/lock/Service.qml, which every omarchy package upgrade reverts.
Why it matters beyond preference
Leaving panels lit on a black lock screen is a reasonable configuration, not a quirk:
- On mini-LED / OLED panels a black lock screen already drops backlight zones to near-zero, so forced DPMS-off buys little power.
- DPMS-off drops the DP link. On monitors with slow re-sync that costs several seconds of black on every wake, and it puts the GPU through a full link re-train.
- That last part is not always benign. On this machine (dual DP monitors on a discrete RX 9070, nothing on the iGPU), waking from a long idle lock produced a hard lockup requiring a power cycle — the card dropped off the PCIe bus:
Aug 19 09:55:15 kernel/shell: idle-monitor: active <- wake
Aug 19 09:55:15 omarchy-shell: There are no outputs - creating placeholder screen
Aug 19 09:55:17 omarchy-shell: WARN: The Wayland connection experienced a fatal error: Invalid argument
Aug 19 09:55:20 kernel: amdgpu 0000:03:00.0: Fence fallback timer expired on ring sdma1
Aug 19 09:55:21 kernel: amdgpu 0000:03:00.0: device lost from bus!
Aug 19 09:55:21 kernel: amdgpu 0000:03:00.0: SMU: bus error for message: EnableSmuFeaturesLow(8) response:0xFFFFFFFF
Aug 19 09:55:23 kernel: amdgpu 0000:03:00.0: Dumping IP State
Aug 19 09:55:28 kernel: amdgpu 0000:03:00.0: MES(1) failed to respond to msg=MISC (WAIT_REG_MEM)
Aug 19 09:55:54 <last journal entry; machine wedged, hard reset required>The displays are the only thing on that GPU, so there was no console to recover from.
To be clear about what I am and am not claiming: the bus drop itself is almost certainly an amdgpu link-recovery bug, not an Omarchy bug, and I have not proven the blank is what triggered it — see the open question below. The Omarchy-side complaint is narrower and independent: there is no supported way to turn the blanking off, so a user who has a good reason to keep panels lit has nowhere to go. This is the first such lockup here in months of uptime; it happened on the first long idle after the 4.0 upgrade.
Open question / interaction with #7456
#7456 reports that the { action = "disable" } table form is a silent no-op on Hyprland 0.56's Lua dispatcher, so on some systems the blank never actually lands. If that's right, this issue is currently latent for those users — and fixing #7456 will switch forced, non-optional display-off on for everyone. That's the case for adding an opt-out alongside that fix rather than after it.
I have not run the destructive confirmation on this machine (dispatching a real DPMS-off risks reproducing the lockup above), so I can't say from here whether the blank landed on 2026-08-18 or whether the outputs went away for the reason described in #7380.
Suggested fix
Gate the blank on config, defaulting to current behavior so nothing changes for existing users:
// ~/.config/omarchy/shell.json
{ "idle": { "lock": 1800, "screensaver": 86400, "blankOnLock": false } }and in Service.qml:
function runBlank() {
if (!idleConfig.blankOnLock) return
if (!blankProcess.running) blankProcess.running = true
}Honoring OMARCHY_LOCK_ONLY again in omarchy-system-lock would also work, but a shell.json key seems more in keeping with how 4.0 does configuration.
Related
- #7456 —
omarchy-brightness-display offdispatch is a no-op on the Lua API (directly interacts with this) - #7380 — shell crashes/relaunches on every wake from idle lock (
FALLBACKmonitor removal, fatal Wayland error) — same signature seen here - #7145 — lock screen flashes blank from periodic "no outputs" Wayland glitch
- #7478 — lock screen crash-loop after locking, due to DPMS-off
System info
- Omarchy: 4.0.0-1 (upgraded from 3.x on 2026-08-18)
- Hyprland: 0.56.2-1 · quickshell-git: 0.3.0.r20.g28771c7-1
- Kernel: 7.1.8.arch1-3
- CPU: AMD Ryzen 9 9950X
- GPU: Radeon RX 9070 (Navi 48) [1002:7550] — drives both displays; iGPU Granite Ridge [1002:13c0] unused
- Monitors: DP-1 3840x2160@144 scale 1.5, DP-3 3840x2160@144 scale 1.5
- Idle config:
{"idle": {"lock": 1800, "screensaver": 86400}}
View raw text
## Summary
Omarchy 4.0 blanks the displays ~5s after every lock, and there is **no way to opt out** — no `shell.json` setting, no plugin override, and the pre-4.0 escape hatch (`OMARCHY_LOCK_ONLY`) is now dead code.
Pre-4.0, the shipped `hypridle.conf` deliberately locked *without* powering displays off, and said so in its own comments. That behavior is no longer reachable.
## What changed
The `hypridle.conf` that Omarchy shipped (still on disk at `~/.config/hypr/hypridle.conf` after the 4.0 upgrade, now orphaned since `hypridle` was removed):
```
general {
lock_cmd = OMARCHY_LOCK_ONLY=true omarchy-system-lock # lock without powering off the displays.
before_sleep_cmd = OMARCHY_LOCK_ONLY=true omarchy-system-lock
}
# Show the black lock screen after 30 minutes while leaving display power on.
listener {
timeout = 1800
on-timeout = pidof hyprlock || OMARCHY_LOCK_ONLY=true omarchy-system-lock
}
```
In 4.0, `OMARCHY_LOCK_ONLY` is read by nothing. `grep -rn OMARCHY_LOCK_ONLY /usr/share/omarchy/` returns zero hits; the only matches on my system are my own leftover config files.
Blanking moved into the shell's lock plugin and became unconditional — `shell/plugins/lock/Service.qml`:
```qml
:136 lockRequested = true
armBlankTimer() // unconditional, on every lock
:172 function runBlank() { // no config gate
if (!blankProcess.running) blankProcess.running = true
}
:410 Process { id: blankProcess
command: ["bash","-c","omarchy-brightness-keyboard off; omarchy-brightness-display off"] }
:415 Timer { id: idleBlankTimer; interval: 5000
onTriggered: if (root.lockRequested && !root.authenticatingPassword) root.runBlank() }
```
## Why there's no workaround
- **No config knob.** `runBlank()` has no gate; nothing in `shell.json` reaches it.
- **No plugin override.** `shell/services/PluginRegistry.qml:599` — *"Third-party plugins never shadow first-party ids"* — and the check at :603 rejects the entire `omarchy.*` namespace.
- **No PATH shim.** `/usr/share/omarchy/bin` sits ahead of both `~/.local/bin` and `~/.local/share/omarchy/bin` in the session PATH, so a wrapper around `omarchy-brightness-display` never gets resolved.
That leaves patching `/usr/share/omarchy/shell/plugins/lock/Service.qml`, which every `omarchy` package upgrade reverts.
## Why it matters beyond preference
Leaving panels lit on a black lock screen is a reasonable configuration, not a quirk:
- On mini-LED / OLED panels a black lock screen already drops backlight zones to near-zero, so forced DPMS-off buys little power.
- DPMS-off drops the DP link. On monitors with slow re-sync that costs several seconds of black on every wake, and it puts the GPU through a full link re-train.
- That last part is not always benign. On this machine (dual DP monitors on a discrete RX 9070, nothing on the iGPU), waking from a long idle lock produced a **hard lockup requiring a power cycle** — the card dropped off the PCIe bus:
```
Aug 19 09:55:15 kernel/shell: idle-monitor: active <- wake
Aug 19 09:55:15 omarchy-shell: There are no outputs - creating placeholder screen
Aug 19 09:55:17 omarchy-shell: WARN: The Wayland connection experienced a fatal error: Invalid argument
Aug 19 09:55:20 kernel: amdgpu 0000:03:00.0: Fence fallback timer expired on ring sdma1
Aug 19 09:55:21 kernel: amdgpu 0000:03:00.0: device lost from bus!
Aug 19 09:55:21 kernel: amdgpu 0000:03:00.0: SMU: bus error for message: EnableSmuFeaturesLow(8) response:0xFFFFFFFF
Aug 19 09:55:23 kernel: amdgpu 0000:03:00.0: Dumping IP State
Aug 19 09:55:28 kernel: amdgpu 0000:03:00.0: MES(1) failed to respond to msg=MISC (WAIT_REG_MEM)
Aug 19 09:55:54 <last journal entry; machine wedged, hard reset required>
```
The displays are the only thing on that GPU, so there was no console to recover from.
**To be clear about what I am and am not claiming:** the bus drop itself is almost certainly an `amdgpu` link-recovery bug, not an Omarchy bug, and I have not proven the blank is what triggered it — see the open question below. The Omarchy-side complaint is narrower and independent: **there is no supported way to turn the blanking off**, so a user who has a good reason to keep panels lit has nowhere to go. This is the first such lockup here in months of uptime; it happened on the first long idle after the 4.0 upgrade.
## Open question / interaction with #7456
#7456 reports that the `{ action = "disable" }` table form is a silent no-op on Hyprland 0.56's Lua dispatcher, so on some systems the blank never actually lands. If that's right, this issue is currently latent for those users — and **fixing #7456 will switch forced, non-optional display-off on for everyone**. That's the case for adding an opt-out alongside that fix rather than after it.
I have not run the destructive confirmation on this machine (dispatching a real DPMS-off risks reproducing the lockup above), so I can't say from here whether the blank landed on 2026-08-18 or whether the outputs went away for the reason described in #7380.
## Suggested fix
Gate the blank on config, defaulting to current behavior so nothing changes for existing users:
```jsonc
// ~/.config/omarchy/shell.json
{ "idle": { "lock": 1800, "screensaver": 86400, "blankOnLock": false } }
```
and in `Service.qml`:
```qml
function runBlank() {
if (!idleConfig.blankOnLock) return
if (!blankProcess.running) blankProcess.running = true
}
```
Honoring `OMARCHY_LOCK_ONLY` again in `omarchy-system-lock` would also work, but a `shell.json` key seems more in keeping with how 4.0 does configuration.
## Related
- #7456 — `omarchy-brightness-display off` dispatch is a no-op on the Lua API (directly interacts with this)
- #7380 — shell crashes/relaunches on every wake from idle lock (`FALLBACK` monitor removal, fatal Wayland error) — same signature seen here
- #7145 — lock screen flashes blank from periodic "no outputs" Wayland glitch
- #7478 — lock screen crash-loop after locking, due to DPMS-off
## System info
- Omarchy: 4.0.0-1 (upgraded from 3.x on 2026-08-18)
- Hyprland: 0.56.2-1 · quickshell-git: 0.3.0.r20.g28771c7-1
- Kernel: 7.1.8.arch1-3
- CPU: AMD Ryzen 9 9950X
- GPU: Radeon RX 9070 (Navi 48) [1002:7550] — drives both displays; iGPU Granite Ridge [1002:13c0] unused
- Monitors: DP-1 3840x2160@144 scale 1.5, DP-3 3840x2160@144 scale 1.5
- Idle config: `{"idle": {"lock": 1800, "screensaver": 86400}}`
Validation
Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.
Linked
- Related PRpr/7863· confirmed
- Fixed bypr/11072· confirmed
Decision
Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.
- Decided by agents · verified: in the audited area (lock)
- Decided by agents · verified: not a duplicate of another report
- Decided by agents · verified: matches no known issue
The outcome (valid, duplicate, not a bug, …) is not decided yet.