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.
Startup cursor restore never runs after a reload wipes its Lua state; pointer stays invisible
Reported by ekollof · filed Oct 10, 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
System details
Omarchy dev channel (dev-linked checkout, integration build db439093), Hyprland 0.56.2, AMD Ryzen AI 9 HX 370 w/ Radeon 890M (GPD G1628-04). Two displays configured: internal eDP-1 panel plus a Vestel TV on DP-1. Session uses a plain Xcursor setup: HYPRCURSOR_THEME unset, XCURSOR_THEME=default, size 24 (/usr/share/icons/default inherits Adwaita).
What is wrong?
After a fresh boot the mouse pointer stays invisible for the whole session (clicks and hover still work). State before touching anything:
gsettings cursor-theme -> 'omarchy-startup'
gsettings cursor-size -> 24
cursor:invisible -> false
cursor:enable_hyprcursor -> true
cursor:sync_gsettings_theme -> trueProbed the compositor's Lua state directly (via hyprctl eval writing through io.open, same method as the reload probe upthread in #14512):
omarchy_startup_cursor_pending -> false
omarchy_startup_cursor -> nilomarchy_startup_cursor_restore() returns on its first line in this state, so no setcursor ever runs — including the final one #14610 adds. The 15 s timer recovery is gone too: hl.timer registrations do not survive a reload either. At the time of probing, DP-1 was no longer in hyprctl monitors (TV off), which points at the trigger: omarchy-hyprland-monitor-watch recover_modeless calls hyprctl reload while a monitor reports no mode — the normal state of a TV that is still waking up at boot. That reload lands while the startup restore is pending, wipes the Lua globals, and the config.reloaded handler then runs in a fresh state, sees monitors, sets pending = false, and the restore is dead from there on.
Recovery verified live
hyprctl setcursor default 24GSettings read back 'default' and the pointer came back immediately.
Relation to #14512 / #14610
Same stuck-omarchy-startup symptom, different path: #14610 fixes the restore ordering when the restore actually runs, but this box never reaches it. The restore needs to not depend on Lua globals — e.g. persist the captured cursor across reloads (runtime-dir file) and treat "the compositor's XCURSOR_THEME is still omarchy-startup" as pending in the fresh-state init.
Happy to turn this into a PR against default/hypr/startup-cursor.lua with coverage in test/shell.d/hyprland-startup-cursor-test.sh.
View raw text
## System details Omarchy dev channel (dev-linked checkout, integration build db439093), Hyprland 0.56.2, AMD Ryzen AI 9 HX 370 w/ Radeon 890M (GPD G1628-04). Two displays configured: internal eDP-1 panel plus a Vestel TV on DP-1. Session uses a plain Xcursor setup: `HYPRCURSOR_THEME` unset, `XCURSOR_THEME=default`, size 24 (`/usr/share/icons/default` inherits Adwaita). ## What is wrong? After a fresh boot the mouse pointer stays invisible for the whole session (clicks and hover still work). State before touching anything: ```text gsettings cursor-theme -> 'omarchy-startup' gsettings cursor-size -> 24 cursor:invisible -> false cursor:enable_hyprcursor -> true cursor:sync_gsettings_theme -> true ``` Probed the compositor's Lua state directly (via `hyprctl eval` writing through `io.open`, same method as the reload probe upthread in #14512): ```text omarchy_startup_cursor_pending -> false omarchy_startup_cursor -> nil ``` `omarchy_startup_cursor_restore()` returns on its first line in this state, so no `setcursor` ever runs — including the final one #14610 adds. The 15 s timer recovery is gone too: `hl.timer` registrations do not survive a reload either. At the time of probing, DP-1 was no longer in `hyprctl monitors` (TV off), which points at the trigger: `omarchy-hyprland-monitor-watch` `recover_modeless` calls `hyprctl reload` while a monitor reports no mode — the normal state of a TV that is still waking up at boot. That reload lands while the startup restore is pending, wipes the Lua globals, and the `config.reloaded` handler then runs in a fresh state, sees monitors, sets `pending = false`, and the restore is dead from there on. ## Recovery verified live ```bash hyprctl setcursor default 24 ``` GSettings read back `'default'` and the pointer came back immediately. ## Relation to #14512 / #14610 Same stuck-`omarchy-startup` symptom, different path: #14610 fixes the restore ordering when the restore actually runs, but this box never reaches it. The restore needs to not depend on Lua globals — e.g. persist the captured cursor across reloads (runtime-dir file) and treat "the compositor's `XCURSOR_THEME` is still `omarchy-startup`" as pending in the fresh-state init. Happy to turn this into a PR against `default/hypr/startup-cursor.lua` with coverage in `test/shell.d/hyprland-startup-cursor-test.sh`.
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-10 13:03 UTC