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

Shell background: setInstant flashes black until the new image decodes

Reported by mattroe · filed Oct 2, 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

Shell background: setInstant flashes black until the new image decodesrevision 1 · captured 2026-10-02 15:59 UTC via poll

System details

Dell XPS 13 (Intel Core 5 320), Omarchy 4.0.4, quickshell 0.3.1, Qt 6.11.2

What's wrong?

omarchy-shell background setInstant <path> blanks the desktop to black until the new image has decoded, so every instant switch to a large wallpaper flashes black. background set (the wiping transition) doesn't, because it keeps the old frame up until the new one is Ready.

In shell/plugins/background/Background.qml, the instant branch of transitionBackground() points displayedBackground straight at the new path. The base Image is asynchronous: true, so it drops the old picture and paints nothing until the new file decodes. Nothing sits behind it except the transparent panel, so the screen shows black for that time. For a 2560×1440 PNG of a few MB, that's a visible flash of 100 ms or more.

Steps to reproduce

  1. Put two large PNGs (a few MB each) in a theme's backgrounds/.
  2. Alternate between them with omarchy-shell background setInstant /path/to/a.png and omarchy-shell background setInstant /path/to/b.png. Calling it from a Hyprland workspace.active handler, to give each workspace its own wallpaper, shows the flash on every workspace switch.
  3. The desktop goes black briefly on each switch. Running the same steps with background set gives no flash.

Suggested fix

Qt 6.8 added `Image.retainWhileLoading`, which keeps showing the current image until the new source is ready. One line on the base Image:

Image {
  id: base
  ...
  asynchronous: true
  cache: true
  retainWhileLoading: true

I checked this outside the shell with a minimal QML scene on Qt 6.11.2 (offscreen platform): an asynchronous Image swapping between two 2560×1440 PNGs, with frames grabbed while the second one loads.

  • Without retainWhileLoading, every grabbed frame was pure black (mean brightness 0 in all 6 samples).
  • With retainWhileLoading: true, the frame still showed the previous image (mean brightness 51, the old wallpaper).

The transition path should be unaffected: it already keeps incomingBackground visible until base reports Ready.

View raw text
### System details

Dell XPS 13 (Intel Core 5 320), Omarchy 4.0.4, quickshell 0.3.1, Qt 6.11.2

### What's wrong?

`omarchy-shell background setInstant <path>` blanks the desktop to black until the new image has decoded, so every instant switch to a large wallpaper flashes black. `background set` (the wiping transition) doesn't, because it keeps the old frame up until the new one is `Ready`.

In `shell/plugins/background/Background.qml`, the instant branch of `transitionBackground()` points `displayedBackground` straight at the new path. The `base` Image is `asynchronous: true`, so it drops the old picture and paints nothing until the new file decodes. Nothing sits behind it except the transparent panel, so the screen shows black for that time. For a 2560×1440 PNG of a few MB, that's a visible flash of 100 ms or more.

**Steps to reproduce**

1. Put two large PNGs (a few MB each) in a theme's `backgrounds/`.
2. Alternate between them with `omarchy-shell background setInstant /path/to/a.png` and `omarchy-shell background setInstant /path/to/b.png`. Calling it from a Hyprland `workspace.active` handler, to give each workspace its own wallpaper, shows the flash on every workspace switch.
3. The desktop goes black briefly on each switch. Running the same steps with `background set` gives no flash.

**Suggested fix**

Qt 6.8 added [`Image.retainWhileLoading`](https://doc.qt.io/qt-6/qml-qtquick-image.html#retainWhileLoading-prop), which keeps showing the current image until the new source is ready. One line on the `base` Image:

```qml
Image {
  id: base
  ...
  asynchronous: true
  cache: true
  retainWhileLoading: true
```

I checked this outside the shell with a minimal QML scene on Qt 6.11.2 (offscreen platform): an `asynchronous` Image swapping between two 2560×1440 PNGs, with frames grabbed while the second one loads.

- Without `retainWhileLoading`, every grabbed frame was pure black (mean brightness 0 in all 6 samples).
- With `retainWhileLoading: true`, the frame still showed the previous image (mean brightness 51, the old wallpaper).

The transition path should be unaffected: it already keeps `incomingBackground` visible until `base` reports `Ready`.

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.

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