Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A 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.

Inbox
ReportR-677GitHub issuePublicFixed

Lock screen blank loops indefinitely on displays that drop HDMI HPD in power save

Reported by blueedgesolutions-tom · filed Sep 11, 2026 · open at source

Decided: Duplicate — decided by agents · verified 3 days ago.

This defect is tracked under R-2112. This report describes the same defect, so it is folded under it in the inbox.

Earliest report of this defect: R-677 (filed Sep 11, 2026).

Decided by agents · verified· Oct 9, 2026

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?
AreaIn the audited arealock· Decided by agents · verified
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?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

Lock screen blank loops indefinitely on displays that drop HDMI HPD in power saverevision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

On a display that deasserts HDMI hotplug-detect when it enters power save, the
lock screen's blank step puts the session into an infinite blank/wake loop. The
monitor cycles on and off roughly every 6 seconds for as long as the session
stays locked, with a full workspace migration on every cycle. GPU fans spool up
and stay up.

Measured on one overnight lock: 4,190 cycles, and a 51 MB Hyprland log.

System details

Omarchy4.0.0.r2014.gf99d33a-1
Hyprland0.56.2
aquamarine0.14.0-2
quickshell0.3.1-1
Kernel7.2.2-arch1-1
Mesa26.2.2
CPUAMD Ryzen 7 5700
GPUAMD Radeon RX 7600 (Navi 33), amdgpu
DisplayMSI MP341CQ, [email protected], HDMI

Expected

Locking the session blanks the display, and it stays blank until there is user
input.

Actual

The display blanks, wakes ~1 second later, blanks again 5 seconds after that,
and repeats indefinitely.

Steps to reproduce

  1. Use a display that drops HDMI HPD when it enters power save (MSI MP341CQ

here; this is common monitor firmware behaviour, not specific to this model).
2. Lock the session, via idle timeout or omarchy system lock.
3. Leave it locked and watch ~/.local/state/.../hyprland.log, or just listen
to the fans.

Root cause

omarchy.lock arms a 5-second timer on lock and then blanks the display:

  • shell/plugins/lock/Service.qml:415 — idleBlankTimer, interval: 5000
  • shell/plugins/lock/Service.qml:410 — blankProcess runs

omarchy-brightness-keyboard off; omarchy-brightness-display off
- bin/omarchy-brightness-display:62 — off issues
hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })'

DPMS-off stops the TMDS clock. The monitor enters power save and deasserts HPD.
From there:

  1. Kernel reports the connector disconnected.
  2. aquamarine tears the output down —

drm: HDMI-A-2 is not connected, clearing stale crtc 376.
3. Hyprland creates a headless FALLBACK monitor and migrates every workspace
and window onto it, at 1920x1080.
4. The link re-asserts, the connector reconnects, and the output is recreated —
with DPMS back on, because the DPMS state lived on the output object that
was just destroyed.
5. Windows migrate back to 3440x1440, idleBlankTimer re-arms, and 5 seconds
later we are back at step 1.

The loop is self-sustaining because nothing re-asserts the blank state onto the
recreated output, and nothing records that the session is still locked and was
deliberately blanked.

Evidence

From a single session's logs, all four counts agreeing:

SignalCount
drm: Connector HDMI-A-2 disconnected4,190
drm: Connector HDMI-A-2 connected4,191
quickshell.hyprland.ipc: Got removal for monitor "FALLBACK"4,190
ERR drm: Cannot commit when a page-flip is awaiting8,382

The page-flip errors are the compositor colliding with its own in-flight flips
while churning through modesets.

Quickshell cannot build a lock surface during the gap:

DEBUG: Not creating lock surface for screen QScreen(...) as it is not backed by a valid wayland output.
INFO qt.qpa.wayland: There are no outputs - creating placeholder screen
WARN: Layershell screen does not correspond to a real screen. Letting the compositor pick.

That is worth a look on its own: for part of each cycle the session is locked
with no lock surface.

The flapping windows line up exactly with the lock windows, which is what rules
out a flaky cable:

FlappingLock state
overnight → 07:05unlocked at 07:05
07:50 → 07:59locked 07:50:18, unlocked 07:59:20
08:36 → 09:34locked 08:35:55, unlocked 09:34:22

Workaround

Force the connector to always report connected, so the output is never
destroyed and the DPMS-off state survives:

# /etc/limine-entry-tool.d/hdmi-force-connected.conf
KERNEL_CMDLINE[default]+=" video=HDMI-A-2:e"

Applied here but not yet verified across a reboot at time of filing; I will
update this issue once it has been through a full locked overnight. Even if it
works, it is a per-machine, per-connector kernel change, and it costs the
ability to detect a genuine unplug.

Suggested fixes

Omarchy side. Treat "blanked while locked" as session state rather than
output state. On monitoradded while lockRequested is true, re-assert the
blank instead of letting the fresh output come up lit. That alone would not stop
the physical HPD flap, but it would stop Omarchy driving it, which is what makes
it infinite.

A cheaper mitigation regardless of the above: back off idleBlankTimer if a
blank has already been attempted several times during one lock, rather than
re-arming at a fixed 5 seconds forever.

Hyprland side. DPMS state is lost when a connector is re-added, which looks
like the underlying defect. Happy to file that separately upstream if you'd
rather it live there — I have the full logs.

Attachments

Raw log excerpts, permanent: https://gist.github.com/blueedgesolutions-tom/944e1adbd2fd7332edd88eaba1a69115

  • 01-hyprland-one-cycle.log — one complete disconnect/reconnect cycle from

the aquamarine log, from the udev hotplug through CRTC teardown, the
1920x1080 FALLBACK buffer allocation, and the modeset back to 3440x1440.
- 02-quickshell-lock-start.log — the shell's own timeline for the start of
one lock: secure=true at 08:35:55.6, first There are no outputs at
08:36:07.
- 03-flap-histogram-per-minute.txt — cycles per minute across the whole
boot, so the lock-window correlation can be checked directly.

Note on captures

No screen recording attached: the misbehaviour only occurs while the session is
locked, and the session lock blocks screen capture. The log counts above are the
substitute.

View raw text
## Summary

On a display that deasserts HDMI hotplug-detect when it enters power save, the
lock screen's blank step puts the session into an infinite blank/wake loop. The
monitor cycles on and off roughly every 6 seconds for as long as the session
stays locked, with a full workspace migration on every cycle. GPU fans spool up
and stay up.

Measured on one overnight lock: **4,190 cycles**, and a 51 MB Hyprland log.

## System details

| | |
|---|---|
| Omarchy | 4.0.0.r2014.gf99d33a-1 |
| Hyprland | 0.56.2 |
| aquamarine | 0.14.0-2 |
| quickshell | 0.3.1-1 |
| Kernel | 7.2.2-arch1-1 |
| Mesa | 26.2.2 |
| CPU | AMD Ryzen 7 5700 |
| GPU | AMD Radeon RX 7600 (Navi 33), amdgpu |
| Display | MSI MP341CQ, [email protected], HDMI |

## Expected

Locking the session blanks the display, and it stays blank until there is user
input.

## Actual

The display blanks, wakes ~1 second later, blanks again 5 seconds after that,
and repeats indefinitely.

## Steps to reproduce

1. Use a display that drops HDMI HPD when it enters power save (MSI MP341CQ
   here; this is common monitor firmware behaviour, not specific to this model).
2. Lock the session, via idle timeout or `omarchy system lock`.
3. Leave it locked and watch `~/.local/state/.../hyprland.log`, or just listen
   to the fans.

## Root cause

`omarchy.lock` arms a 5-second timer on lock and then blanks the display:

- `shell/plugins/lock/Service.qml:415` — `idleBlankTimer`, `interval: 5000`
- `shell/plugins/lock/Service.qml:410` — `blankProcess` runs
  `omarchy-brightness-keyboard off; omarchy-brightness-display off`
- `bin/omarchy-brightness-display:62` — `off` issues
  `hyprctl dispatch 'hl.dsp.dpms({ action = "disable" })'`

DPMS-off stops the TMDS clock. The monitor enters power save and deasserts HPD.
From there:

1. Kernel reports the connector disconnected.
2. aquamarine tears the output down —
   `drm: HDMI-A-2 is not connected, clearing stale crtc 376`.
3. Hyprland creates a headless `FALLBACK` monitor and migrates every workspace
   and window onto it, at 1920x1080.
4. The link re-asserts, the connector reconnects, and the output is recreated —
   **with DPMS back on**, because the DPMS state lived on the output object that
   was just destroyed.
5. Windows migrate back to 3440x1440, `idleBlankTimer` re-arms, and 5 seconds
   later we are back at step 1.

The loop is self-sustaining because nothing re-asserts the blank state onto the
recreated output, and nothing records that the session is still locked and was
deliberately blanked.

## Evidence

From a single session's logs, all four counts agreeing:

| Signal | Count |
|---|---|
| `drm: Connector HDMI-A-2 disconnected` | 4,190 |
| `drm: Connector HDMI-A-2 connected` | 4,191 |
| `quickshell.hyprland.ipc: Got removal for monitor "FALLBACK"` | 4,190 |
| `ERR drm: Cannot commit when a page-flip is awaiting` | 8,382 |

The page-flip errors are the compositor colliding with its own in-flight flips
while churning through modesets.

Quickshell cannot build a lock surface during the gap:

```
DEBUG: Not creating lock surface for screen QScreen(...) as it is not backed by a valid wayland output.
INFO qt.qpa.wayland: There are no outputs - creating placeholder screen
WARN: Layershell screen does not correspond to a real screen. Letting the compositor pick.
```

That is worth a look on its own: for part of each cycle the session is locked
with no lock surface.

The flapping windows line up exactly with the lock windows, which is what rules
out a flaky cable:

| Flapping | Lock state |
|---|---|
| overnight → 07:05 | unlocked at 07:05 |
| 07:50 → 07:59 | locked 07:50:18, unlocked 07:59:20 |
| 08:36 → 09:34 | locked 08:35:55, unlocked 09:34:22 |

## Workaround

Force the connector to always report connected, so the output is never
destroyed and the DPMS-off state survives:

```
# /etc/limine-entry-tool.d/hdmi-force-connected.conf
KERNEL_CMDLINE[default]+=" video=HDMI-A-2:e"
```

Applied here but not yet verified across a reboot at time of filing; I will
update this issue once it has been through a full locked overnight. Even if it
works, it is a per-machine, per-connector kernel change, and it costs the
ability to detect a genuine unplug.

## Suggested fixes

**Omarchy side.** Treat "blanked while locked" as session state rather than
output state. On `monitoradded` while `lockRequested` is true, re-assert the
blank instead of letting the fresh output come up lit. That alone would not stop
the physical HPD flap, but it would stop Omarchy driving it, which is what makes
it infinite.

A cheaper mitigation regardless of the above: back off `idleBlankTimer` if a
blank has already been attempted several times during one lock, rather than
re-arming at a fixed 5 seconds forever.

**Hyprland side.** DPMS state is lost when a connector is re-added, which looks
like the underlying defect. Happy to file that separately upstream if you'd
rather it live there — I have the full logs.

## Attachments

Raw log excerpts, permanent: https://gist.github.com/blueedgesolutions-tom/944e1adbd2fd7332edd88eaba1a69115

- `01-hyprland-one-cycle.log` — one complete disconnect/reconnect cycle from
  the aquamarine log, from the udev hotplug through CRTC teardown, the
  1920x1080 FALLBACK buffer allocation, and the modeset back to 3440x1440.
- `02-quickshell-lock-start.log` — the shell's own timeline for the start of
  one lock: `secure=true` at 08:35:55.6, first `There are no outputs` at
  08:36:07.
- `03-flap-histogram-per-minute.txt` — cycles per minute across the whole
  boot, so the lock-window correlation can be checked directly.

## Note on captures

No screen recording attached: the misbehaviour only occurs while the session is
locked, and the session lock blocks screen capture. The log counts above are the
substitute.

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

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.

  • DuplicateR-2112Decided by agents · verified · 2026-10-09 03:21 UTC