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-937GitHub issuePublicDecided· Out of scope

ScreenRecording bar indicator stuck 'active' after boot despite no gpu-screen-recorder process running

Reported by AmanKRoy · filed Sep 5, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

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?
AreaOutside the audited area· 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

ScreenRecording bar indicator stuck 'active' after boot despite no gpu-screen-recorder process runningrevision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

The ScreenRecording bar indicator (shell/plugins/bar/indicators/ScreenRecording.qml) shows the "Stop recording" (active) state immediately after every shell/session restart or reboot, even though no gpu-screen-recorder process is actually running. This has persisted across multiple real reboots, not just shell restarts, so it isn't a leftover in-memory flag — the false-positive is regenerated fresh every boot.

Environment

  • Omarchy 4.0.2-1 (Arch Linux, Hyprland)
  • Dual-monitor setup (two bar instances, so two ScreenRecording indicator instances load concurrently at startup)

Evidence

  1. No real process ever exists. Direct /proc scan for any process whose exe symlink resolves to gpu-screen-recorder, run repeatedly across restarts and reboots, finds nothing. pgrep -af "^gpu-screen-recorder" (unanchored, no --quiet) also finds nothing at any point I checked, including a 5-second 100ms-interval poll spanning a full shell restart.
  1. The widget's own script agrees nothing is recording. Manually running omarchy-capture-screenrecording --stop-recording (the exact command the indicator's onPressed handler runs when it believes recording is active) hits the script's own screenrecording_active() check (a pgrep -f "^gpu-screen-recorder" call), finds nothing, and exits 1 via the elif [[ $STOP_RECORDING == "true" ]]; exit 1 branch — i.e. the production script's own logic confirms no recording is active.
  1. The indicator's internal `pgrep` call still reports `exitCode: 0` (match found). I temporarily instrumented a local copy of ScreenRecording.qml with console.log calls around refresh() and the statusProc Process, reinstalled it, and restarted the shell (omarchy-restart-shell) while tailing the journal. Every time, statusProc's onExited handler fires with exitCode: 0, and root.recording flips to true — reproduced on repeated restarts.
   [SR-DEBUG] Component.onCompleted
   [SR-DEBUG] refresh() called. bar: true statusProc.running: false
   [SR-DEBUG] statusProc launched
   [SR-DEBUG] statusProc.running changed: true
   [SR-DEBUG] statusProc EXITED, exitCode: 0
   [SR-DEBUG] recording changed to true
   [SR-DEBUG] active changed to true
  1. But the match itself doesn't exist. I then changed the command from pgrep --quiet -f "^gpu-screen-recorder" to pgrep -af "^gpu-screen-recorder" (dropping --quiet, adding -a to print the matched line) and piped stdout through a SplitParser logging every line. exitCode: 0 still fires on every restart, but zero matched lines are ever printed — i.e. pgrep is reporting a match was found while producing no output describing what matched.
  1. Ruled out: no systemd user unit is active (gpu-screen-recorder.service is disabled/inactive (dead)), no Hyprland exec-once entry references the recorder, and grep -r "gpu-screen-recorder" across /usr/share/omarchy only matches the indicator itself and the omarchy-capture-screenrecording script — nothing else in Omarchy ever invokes the binary.

Suspected cause

This system has two monitors, so two ScreenRecording indicator instances mount concurrently at shell startup, each independently constructing an identical Process (pgrep --quiet -f "^gpu-screen-recorder") and setting running = true within the same event loop tick (Component.onCompleted / onBarChanged). Given the exitCode: 0 combined with the total absence of matched output, this looks like a race in Quickshell's Process exit-code delivery when two Process objects with the same command are started back-to-back/concurrently — the exit code from one may be getting cross-delivered, or a stale/default value is being read before the real child has actually reported. I haven't dug into Quickshell's C++ internals to confirm the exact mechanism.

Impact

Purely cosmetic — no real recording ever starts, so there's no risk of an unbounded video file or actual background recording. But the indicator is misleading (looks like an active recording is running for days), and clicking it fires omarchy-capture-screenrecording --stop-recording for no reason.

Suggested fix directions (not attached as a PR — wanted to flag this with full repro evidence first since I haven't been able to confirm the exact mechanism at the Quickshell layer)

  • Share a single status check across all ScreenRecording indicator instances (e.g. a shared/singleton poll) instead of each monitor's indicator spawning its own concurrent identical Process, removing the suspected race by construction.
  • Add a periodic re-poll (the indicator currently only refreshes on bar/indicatorHost signals, so if it does get a false positive once, nothing corrects it afterward).

Happy to help test a fix if useful.

View raw text
## Summary

The `ScreenRecording` bar indicator (`shell/plugins/bar/indicators/ScreenRecording.qml`) shows the "Stop recording" (active) state immediately after every shell/session restart or reboot, even though no `gpu-screen-recorder` process is actually running. This has persisted across multiple real reboots, not just shell restarts, so it isn't a leftover in-memory flag — the false-positive is regenerated fresh every boot.

## Environment

- Omarchy 4.0.2-1 (Arch Linux, Hyprland)
- Dual-monitor setup (two bar instances, so two `ScreenRecording` indicator instances load concurrently at startup)

## Evidence

1. **No real process ever exists.** Direct `/proc` scan for any process whose `exe` symlink resolves to `gpu-screen-recorder`, run repeatedly across restarts and reboots, finds nothing. `pgrep -af "^gpu-screen-recorder"` (unanchored, no `--quiet`) also finds nothing at any point I checked, including a 5-second 100ms-interval poll spanning a full shell restart.

2. **The widget's own script agrees nothing is recording.** Manually running `omarchy-capture-screenrecording --stop-recording` (the exact command the indicator's `onPressed` handler runs when it believes recording is active) hits the script's own `screenrecording_active()` check (a `pgrep -f "^gpu-screen-recorder"` call), finds nothing, and exits 1 via the `elif [[ $STOP_RECORDING == "true" ]]; exit 1` branch — i.e. the production script's own logic confirms no recording is active.

3. **The indicator's internal `pgrep` call still reports `exitCode: 0` (match found).** I temporarily instrumented a local copy of `ScreenRecording.qml` with `console.log` calls around `refresh()` and the `statusProc` `Process`, reinstalled it, and restarted the shell (`omarchy-restart-shell`) while tailing the journal. Every time, `statusProc`'s `onExited` handler fires with `exitCode: 0`, and `root.recording` flips to `true` — reproduced on repeated restarts.

   ```
   [SR-DEBUG] Component.onCompleted
   [SR-DEBUG] refresh() called. bar: true statusProc.running: false
   [SR-DEBUG] statusProc launched
   [SR-DEBUG] statusProc.running changed: true
   [SR-DEBUG] statusProc EXITED, exitCode: 0
   [SR-DEBUG] recording changed to true
   [SR-DEBUG] active changed to true
   ```

4. **But the match itself doesn't exist.** I then changed the command from `pgrep --quiet -f "^gpu-screen-recorder"` to `pgrep -af "^gpu-screen-recorder"` (dropping `--quiet`, adding `-a` to print the matched line) and piped `stdout` through a `SplitParser` logging every line. `exitCode: 0` still fires on every restart, but **zero matched lines are ever printed** — i.e. `pgrep` is reporting a match was found while producing no output describing what matched.

5. Ruled out: no systemd user unit is active (`gpu-screen-recorder.service` is `disabled`/`inactive (dead)`), no Hyprland `exec-once` entry references the recorder, and `grep -r "gpu-screen-recorder"` across `/usr/share/omarchy` only matches the indicator itself and the `omarchy-capture-screenrecording` script — nothing else in Omarchy ever invokes the binary.

## Suspected cause

This system has two monitors, so two `ScreenRecording` indicator instances mount concurrently at shell startup, each independently constructing an identical `Process` (`pgrep --quiet -f "^gpu-screen-recorder"`) and setting `running = true` within the same event loop tick (`Component.onCompleted` / `onBarChanged`). Given the `exitCode: 0` combined with the total absence of matched output, this looks like a race in Quickshell's `Process` exit-code delivery when two `Process` objects with the same command are started back-to-back/concurrently — the exit code from one may be getting cross-delivered, or a stale/default value is being read before the real child has actually reported. I haven't dug into Quickshell's C++ internals to confirm the exact mechanism.

## Impact

Purely cosmetic — no real recording ever starts, so there's no risk of an unbounded video file or actual background recording. But the indicator is misleading (looks like an active recording is running for days), and clicking it fires `omarchy-capture-screenrecording --stop-recording` for no reason.

## Suggested fix directions (not attached as a PR — wanted to flag this with full repro evidence first since I haven't been able to confirm the exact mechanism at the Quickshell layer)

- Share a single status check across all `ScreenRecording` indicator instances (e.g. a shared/singleton poll) instead of each monitor's indicator spawning its own concurrent identical `Process`, removing the suspected race by construction.
- Add a periodic re-poll (the indicator currently only refreshes on `bar`/`indicatorHost` signals, so if it does get a false positive once, nothing corrects it afterward).

Happy to help test a fix if useful.

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/10397· 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.

  • Out of scopeDecided by agents · verified · 2026-10-09 10:50 UTC