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.
gapsOut always reads the top gaps_out value, breaks bar-widget dropdown spacing with asymmetric gaps
Reported by salomondc · filed Aug 26, 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?
- 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
What happened
Style.gapsOut (shell/Commons/Style.qml, applyGapsOutJson) computes the popup-to-bar gap used by every bar-widget dropdown (Ui/KeyboardPanel.qml:43, property int margin: Style.gapsOut) from hyprctl getoption general:gaps_out's css string, but it only ever reads the first number:
function applyGapsOutJson(raw) {
try {
var json = JSON.parse(raw || "{}")
var css = String(json.css || "")
var parts = css.match(/-?\d+(?:\.\d+)?/g) || []
var n = parts.length > 0 ? Number(parts[0]) : Number(json.int)
if (isFinite(n) && n >= 0) gapsOut = Math.max(0, Math.round(n / 2))
} catch (e) {
// hyprctl missing / Hyprland not running — leave the previous value.
}
}Hyprland reports gaps_out in CSS shorthand order (top, right, bottom, left), so parts[0] is always the top value — regardless of where the bar is actually docked, or which edge of gaps_out a user has customized.
This is silently correct as long as all four gaps_out edges are equal, which is the shipped default (gaps_out = 10 in default/hypr/looknfeel.lua) and the common case. It breaks for anyone who sets an asymmetric gaps_out — a fully valid, native Hyprland option (general:gaps_out has always accepted 4 edge values) that looknfeel.lua's hl.config passes straight through, e.g.:
gaps_out = { top = 0, left = 28, right = 28, bottom = 28 },No custom bar plugin is needed to hit this — the repro below only touches ~/.config/hypr/looknfeel.lua and opens a stock omarchy.audio-style panel. (I originally wrote this up against a custom bar plugin of mine that zeroes out whichever edge it's docked against — that plugin isn't part of stock Omarchy, so I've dropped the reference to it below. The underlying bug is independent of it.) Whenever gaps_out.top happens to be smaller than the other edges — for any reason, not just bar-docking — every bar-widget dropdown's gap shrinks to round(gaps_out.top / 2) instead of the intended ambient gap, while leaving top alone (even with other edges asymmetric) hides the bug entirely. It reads as "the dropdown gap is sometimes just missing" with no obvious trigger, because it silently tracks whatever gaps_out.top is instead of the general ambient gap size.
Expected
The popup-gap token should reflect the ambient/general gap Hyprland is using, not specifically whatever gaps_out.top happens to be. Taking the max of the four edges is more robust — for the common symmetric case it's identical to today's behavior, and for an asymmetric config it correctly ignores whichever single edge has been zeroed out.
Repro
- Give
gaps_outasymmetric values, e.g. in~/.config/hypr/looknfeel.lua:
gaps_out = { top = 0, left = 28, right = 28, bottom = 28 }, (hyprctl reload)
2. Open any bar-widget dropdown anchored to the top edge (e.g. the audio widget's panel).
3. The panel renders flush against the bar — no gap — because Style.gapsOut read gaps_out.top = 0.
4. Set top back to a nonzero value (or move the 0 to a different edge) and the gap reappears — even though nothing about the actual bar-to-window gap for a top-docked bar changed.
Before / after
<img width="500" alt="Image" src="https://github.com/user-attachments/assets/4348a0a4-c668-491b-aa91-239c6c1cd1e8" />
Locally patching applyGapsOutJson to use Math.max.apply(null, parts.map(Number)) instead of Number(parts[0]) fixes it — same top-docked audio dropdown, gaps_out = { top: 0, left: 28, right: 28, bottom: 28 } in both, before (flush, top image) vs. after (gap restored, bottom image) that one-line change. Screenshot attached below.
System info
- Omarchy version: 4.0.1-1 (stable channel)
- Hyprland 0.56.2
uname -a: Linux 7.1.9-arch1-2 x86_64- GPU: NVIDIA GeForce RTX 2060 SUPER (nvidia driver)
(Note: this install doesn't have an omarchy debug command to attach a fuller diagnostic bundle — omarchy commands --all doesn't list one on this version.)
View raw text
## What happened
`Style.gapsOut` (`shell/Commons/Style.qml`, `applyGapsOutJson`) computes the popup-to-bar gap used by every bar-widget dropdown (`Ui/KeyboardPanel.qml:43`, `property int margin: Style.gapsOut`) from `hyprctl getoption general:gaps_out`'s `css` string, but it only ever reads the **first** number:
```qml
function applyGapsOutJson(raw) {
try {
var json = JSON.parse(raw || "{}")
var css = String(json.css || "")
var parts = css.match(/-?\d+(?:\.\d+)?/g) || []
var n = parts.length > 0 ? Number(parts[0]) : Number(json.int)
if (isFinite(n) && n >= 0) gapsOut = Math.max(0, Math.round(n / 2))
} catch (e) {
// hyprctl missing / Hyprland not running — leave the previous value.
}
}
```
Hyprland reports `gaps_out` in CSS shorthand order (top, right, bottom, left), so `parts[0]` is always the **top** value — regardless of where the bar is actually docked, or which edge of `gaps_out` a user has customized.
This is silently correct as long as all four `gaps_out` edges are equal, which is the shipped default (`gaps_out = 10` in `default/hypr/looknfeel.lua`) and the common case. It breaks for anyone who sets an asymmetric `gaps_out` — a fully valid, native Hyprland option (`general:gaps_out` has always accepted 4 edge values) that `looknfeel.lua`'s `hl.config` passes straight through, e.g.:
```lua
gaps_out = { top = 0, left = 28, right = 28, bottom = 28 },
```
No custom bar plugin is needed to hit this — the repro below only touches `~/.config/hypr/looknfeel.lua` and opens a stock `omarchy.audio`-style panel. (I originally wrote this up against a custom bar plugin of mine that zeroes out whichever edge it's docked against — that plugin isn't part of stock Omarchy, so I've dropped the reference to it below. The underlying bug is independent of it.) Whenever `gaps_out.top` happens to be smaller than the other edges — for any reason, not just bar-docking — every bar-widget dropdown's gap shrinks to `round(gaps_out.top / 2)` instead of the intended ambient gap, while leaving `top` alone (even with other edges asymmetric) hides the bug entirely. It reads as "the dropdown gap is sometimes just missing" with no obvious trigger, because it silently tracks whatever `gaps_out.top` is instead of the general ambient gap size.
## Expected
The popup-gap token should reflect the ambient/general gap Hyprland is using, not specifically whatever `gaps_out.top` happens to be. Taking the max of the four edges is more robust — for the common symmetric case it's identical to today's behavior, and for an asymmetric config it correctly ignores whichever single edge has been zeroed out.
## Repro
1. Give `gaps_out` asymmetric values, e.g. in `~/.config/hypr/looknfeel.lua`:
```lua
gaps_out = { top = 0, left = 28, right = 28, bottom = 28 },
```
(`hyprctl reload`)
2. Open any bar-widget dropdown anchored to the top edge (e.g. the audio widget's panel).
3. The panel renders flush against the bar — no gap — because `Style.gapsOut` read `gaps_out.top = 0`.
4. Set `top` back to a nonzero value (or move the `0` to a different edge) and the gap reappears — even though nothing about the *actual* bar-to-window gap for a top-docked bar changed.
## Before / after
<img width="500" alt="Image" src="https://github.com/user-attachments/assets/4348a0a4-c668-491b-aa91-239c6c1cd1e8" />
Locally patching `applyGapsOutJson` to use `Math.max.apply(null, parts.map(Number))` instead of `Number(parts[0])` fixes it — same top-docked audio dropdown, `gaps_out = { top: 0, left: 28, right: 28, bottom: 28 }` in both, before (flush, top image) vs. after (gap restored, bottom image) that one-line change. Screenshot attached below.
## System info
- Omarchy version: 4.0.1-1 (stable channel)
- Hyprland 0.56.2
- `uname -a`: Linux 7.1.9-arch1-2 x86_64
- GPU: NVIDIA GeForce RTX 2060 SUPER (nvidia driver)
(Note: this install doesn't have an `omarchy debug` command to attach a fuller diagnostic bundle — `omarchy commands --all` doesn't list one on this version.)
- 4348a0a4-c668-491b-aa91-239c6c1cd1e8
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 09:13 UTC