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-4795GitHub issuePublicReceived

Editing idle.screensaver/idle.lock in shell.json silently disables idle detection until the shell is restarted

Reported by kurtome · filed Aug 31, 2026Closed upstream on 2026-09-21 by bjarneo via an automated message, as a duplicate of #8038 (R-1509). GitHub close reason: completed.

Received and recorded verbatim. Nothing has been checked yet.

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?
Not yet mapped to any requirement or component.
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. No decision has been recorded yet.

Original report

Editing idle.screensaver/idle.lock in shell.json silently disables idle detection until the shell is restartedrevision 1 · captured 2026-10-04 12:03 UTC via poll

What happened

~/.config/omarchy/shell.json hot-reloads on save, and omarchy-shell idle status immediately reports the new idle.screensaver / idle.lock values. But idle detection stops working entirely — no screensaver, no lock, no display blanking — until omarchy restart shell.

It fails silently. The status output looks correct, so there is no indication anything is wrong. My machine sat unlocked for ~21 hours before I noticed, with a matching 21-hour gap in the omarchy idle journal lines (the last entry was idle-monitor: active, and no further transition ever came).

Expected

Either the new timeouts take effect on save, or the shell makes it clear they have not been applied.

Root cause

shell/plugins/services/idle/Service.qml:

IdleMonitor {
  id: idleMonitor
  enabled: root.idleEnabled
  timeout: root.firstIdleTimeoutSeconds
  respectInhibitors: true
  onIsIdleChanged: root.handleIdleChanged()
}

Quickshell's IdleMonitor does not re-arm its ext-idle-notification when timeout changes at runtime. Because firstIdleTimeoutSeconds is Math.min(screensaverTimeoutSeconds, lockTimeoutSeconds), any edit to those two values in shell.json mutates timeout on a live monitor, and the monitor then goes permanently silent.

Reproduction

Standalone, no Omarchy involved — quickshell -n -p . on this file:

import QtQuick
import Quickshell
import Quickshell.Wayland

ShellRoot {
  id: root
  property int t: 3600
  IdleMonitor {
    enabled: true
    timeout: root.t
    respectInhibitors: true
    onIsIdleChanged: console.log("isIdle=" + isIdle + " timeout=" + timeout)
  }
  Timer {
    interval: 5000; running: true; repeat: false
    onTriggered: root.t = 8      // change timeout on a live monitor
  }
}

Leave the machine untouched. The monitor never reports idle. A control IdleMonitor constructed with timeout: 8 reports idle after 8s as expected.

Validated workaround / suggested fix

Pulsing enabled off and back on re-arms the notification — but only if the pulse spans an event-loop turn. Qt.callLater is not enough (I tested it; still never fires). A short Timer works:

Timer { id: rearm; interval: 150; repeat: false; onTriggered: root.en = true }

onFirstIdleTimeoutSecondsChanged: { root.en = false; rearm.restart() }

With that in place the same probe logs isIdle=true timeout=8 on schedule.

This may warrant an upstream Quickshell fix as well, but the pulse is a small, self-contained change on the Omarchy side.

Impact

Editing shell.json is the documented way to change lock timing, and doing it silently disables auto-lock until the shell happens to be restarted. That seems worth treating as security-relevant rather than cosmetic.

System

  • Omarchy 4.0.0-1
  • Hyprland 0.56.2-1
  • quickshell-git 0.3.0.r20.g28771c7-1
  • AMD Ryzen AI MAX+ 395 w/ Radeon 8060S (Strix Halo)
View raw text
## What happened

`~/.config/omarchy/shell.json` hot-reloads on save, and `omarchy-shell idle status` immediately reports the new `idle.screensaver` / `idle.lock` values. But idle detection stops working **entirely** — no screensaver, no lock, no display blanking — until `omarchy restart shell`.

It fails silently. The status output looks correct, so there is no indication anything is wrong. My machine sat unlocked for ~21 hours before I noticed, with a matching 21-hour gap in the `omarchy idle` journal lines (the last entry was `idle-monitor: active`, and no further transition ever came).

## Expected

Either the new timeouts take effect on save, or the shell makes it clear they have not been applied.

## Root cause

`shell/plugins/services/idle/Service.qml`:

```qml
IdleMonitor {
  id: idleMonitor
  enabled: root.idleEnabled
  timeout: root.firstIdleTimeoutSeconds
  respectInhibitors: true
  onIsIdleChanged: root.handleIdleChanged()
}
```

Quickshell's `IdleMonitor` does not re-arm its `ext-idle-notification` when `timeout` changes at runtime. Because `firstIdleTimeoutSeconds` is `Math.min(screensaverTimeoutSeconds, lockTimeoutSeconds)`, **any** edit to those two values in `shell.json` mutates `timeout` on a live monitor, and the monitor then goes permanently silent.

## Reproduction

Standalone, no Omarchy involved — `quickshell -n -p .` on this file:

```qml
import QtQuick
import Quickshell
import Quickshell.Wayland

ShellRoot {
  id: root
  property int t: 3600
  IdleMonitor {
    enabled: true
    timeout: root.t
    respectInhibitors: true
    onIsIdleChanged: console.log("isIdle=" + isIdle + " timeout=" + timeout)
  }
  Timer {
    interval: 5000; running: true; repeat: false
    onTriggered: root.t = 8      // change timeout on a live monitor
  }
}
```

Leave the machine untouched. The monitor never reports idle. A control `IdleMonitor` *constructed* with `timeout: 8` reports idle after 8s as expected.

## Validated workaround / suggested fix

Pulsing `enabled` off and back on re-arms the notification — but only if the pulse spans an event-loop turn. `Qt.callLater` is **not** enough (I tested it; still never fires). A short `Timer` works:

```qml
Timer { id: rearm; interval: 150; repeat: false; onTriggered: root.en = true }

onFirstIdleTimeoutSecondsChanged: { root.en = false; rearm.restart() }
```

With that in place the same probe logs `isIdle=true timeout=8` on schedule.

This may warrant an upstream Quickshell fix as well, but the pulse is a small, self-contained change on the Omarchy side.

## Impact

Editing `shell.json` is the documented way to change lock timing, and doing it silently disables auto-lock until the shell happens to be restarted. That seems worth treating as security-relevant rather than cosmetic.

## System

- Omarchy `4.0.0-1`
- Hyprland `0.56.2-1`
- `quickshell-git 0.3.0.r20.g28771c7-1`
- AMD Ryzen AI MAX+ 395 w/ Radeon 8060S (Strix Halo)

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

Not linked to any known issue, other report or change yet.

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.

No decision has been recorded yet.