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

Network panel: Identity field steals focus from Passphrase on every Wi-Fi scan (WPA-Enterprise)

Reported by benskigomez · filed Aug 27, 2026 · open at source

Decided: Out of scope — decided by agents · verified 4 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

Network panel: Identity field steals focus from Passphrase on every Wi-Fi scan (WPA-Enterprise)revision 1 · captured 2026-09-28 21:24 UTC via poll

Omarchy 4.0.1-1, Hyprland 0.56.2, quickshell 0.3.1-1, NetworkManager 1.58.1-1.

What happens

Typing a passphrase for a WPA-Enterprise (WPA2 802.1X) network in the network
panel is close to impossible: every second or so the caret jumps out of the
Passphrase field and back up into the Identity (user@domain) field above it.
The typed text isn't lost (it lives on the panel root), but the next keystrokes
land in the wrong field, so you end up with fragments of the passphrase in
Identity and have to start over.

It looks random from the user's side. It isn't — it's once per Wi-Fi scan result.

Why

Two things combine, both in shell/plugins/panels/network/Panel.qml.

  1. syncWifiNetworks() reassigns the ListView's array model on every scan result:
wifiNetworks = Model.sortWifiRows(nets)   // ~line 606

The ListView's model is that plain JS array (~line 1486). Assigning a new
array resets the view, so every delegate is destroyed and recreated — including
the one holding the open credential prompt. scanDone fires this on a 1500ms
timer while the panel is open, and sortWifiRows re-sorts by signal, so an SSID
with several BSSIDs at fluctuating strength churns the list continuously.

  1. On rebuild, idField unconditionally claims focus (~line 1854):
onVisibleChanged:      if (visible) Qt.callLater(forceActiveFocus)
Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)

pwField guards its equivalents with && !row.isEnterprise (~line 1880) so that
identity-first focus works when the prompt opens. But nothing stops idField from
re-grabbing focus on every subsequent rebuild.

This is why the bug is enterprise-only: on a PSK network idField is never visible,
and pwField re-focusing itself after a rebuild is invisible to the user.

The same unguarded onVisibleChanged also defeats failureTimer's explicit
pwField.forceActiveFocus() after a wrong-password attempt — clearing the failure
banner makes idField visible again, and its queued callLater runs last.

Repro

  1. Be in range of a WPA2 802.1X network with several APs advertising the same SSID

(any normal corporate deployment).
2. Open the network panel (SUPER + CTRL + W) and click the enterprise network.
3. Start typing in Passphrase.
4. Roughly every 1.5s the caret jumps up to Identity.

Expected

Once a credential prompt is open, scan churn should not move keyboard focus.

Patch that fixes it locally

Freeze the model while a prompt is open, and stop idField re-claiming focus once
a passphrase has been typed:

-    wifiNetworks = Model.sortWifiRows(nets)
+    if (passwordSsid === "") wifiNetworks = Model.sortWifiRows(nets)
-        onVisibleChanged: if (visible) Qt.callLater(forceActiveFocus)
-        Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)
+        onVisibleChanged: if (visible && root.passwordText.length === 0) Qt.callLater(forceActiveFocus)
+        Component.onCompleted: if (visible && root.passwordText.length === 0) Qt.callLater(forceActiveFocus)

Running with this applied via omarchy plugin clone omarchy.network; the prompt is
stable and the caret stays put. Happy to open a PR if the approach looks right —
preserving focus across the rebuild (rather than freezing the list) may be the
better fix if the list is meant to stay live.

Related

#7264 is a different failure in the same prompt (prompt never opens for a saved
network with a stale PSK), not a duplicate.

System

  • CPU: 11th Gen Intel Core i5-1145G7
  • GPU: Intel TigerLake-LP GT2 [Iris Xe]
  • wpa_supplicant 2:2.12-1
View raw text
**Omarchy 4.0.1-1**, Hyprland 0.56.2, quickshell 0.3.1-1, NetworkManager 1.58.1-1.

## What happens

Typing a passphrase for a **WPA-Enterprise (WPA2 802.1X)** network in the network
panel is close to impossible: every second or so the caret jumps out of the
`Passphrase` field and back up into the `Identity (user@domain)` field above it.
The typed text isn't lost (it lives on the panel root), but the next keystrokes
land in the wrong field, so you end up with fragments of the passphrase in
`Identity` and have to start over.

It looks random from the user's side. It isn't — it's once per Wi-Fi scan result.

## Why

Two things combine, both in `shell/plugins/panels/network/Panel.qml`.

1. `syncWifiNetworks()` reassigns the ListView's array model on every scan result:

```qml
wifiNetworks = Model.sortWifiRows(nets)   // ~line 606
```

The ListView's `model` is that plain JS array (`~line 1486`). Assigning a new
array resets the view, so **every delegate is destroyed and recreated** — including
the one holding the open credential prompt. `scanDone` fires this on a 1500ms
timer while the panel is open, and `sortWifiRows` re-sorts by signal, so an SSID
with several BSSIDs at fluctuating strength churns the list continuously.

2. On rebuild, `idField` unconditionally claims focus (`~line 1854`):

```qml
onVisibleChanged:      if (visible) Qt.callLater(forceActiveFocus)
Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)
```

`pwField` guards its equivalents with `&& !row.isEnterprise` (`~line 1880`) so that
identity-first focus works when the prompt opens. But nothing stops `idField` from
re-grabbing focus on every subsequent rebuild.

This is why the bug is enterprise-only: on a PSK network `idField` is never visible,
and `pwField` re-focusing itself after a rebuild is invisible to the user.

The same unguarded `onVisibleChanged` also defeats `failureTimer`'s explicit
`pwField.forceActiveFocus()` after a wrong-password attempt — clearing the failure
banner makes `idField` visible again, and its queued `callLater` runs last.

## Repro

1. Be in range of a WPA2 802.1X network with several APs advertising the same SSID
   (any normal corporate deployment).
2. Open the network panel (`SUPER + CTRL + W`) and click the enterprise network.
3. Start typing in `Passphrase`.
4. Roughly every 1.5s the caret jumps up to `Identity`.

## Expected

Once a credential prompt is open, scan churn should not move keyboard focus.

## Patch that fixes it locally

Freeze the model while a prompt is open, and stop `idField` re-claiming focus once
a passphrase has been typed:

```diff
-    wifiNetworks = Model.sortWifiRows(nets)
+    if (passwordSsid === "") wifiNetworks = Model.sortWifiRows(nets)
```

```diff
-        onVisibleChanged: if (visible) Qt.callLater(forceActiveFocus)
-        Component.onCompleted: if (visible) Qt.callLater(forceActiveFocus)
+        onVisibleChanged: if (visible && root.passwordText.length === 0) Qt.callLater(forceActiveFocus)
+        Component.onCompleted: if (visible && root.passwordText.length === 0) Qt.callLater(forceActiveFocus)
```

Running with this applied via `omarchy plugin clone omarchy.network`; the prompt is
stable and the caret stays put. Happy to open a PR if the approach looks right —
preserving focus across the rebuild (rather than freezing the list) may be the
better fix if the list is meant to stay live.

## Related

#7264 is a different failure in the same prompt (prompt never opens for a saved
network with a stale PSK), not a duplicate.

## System

- CPU: 11th Gen Intel Core i5-1145G7
- GPU: Intel TigerLake-LP GT2 [Iris Xe]
- wpa_supplicant 2:2.12-1

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:34 UTC