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

Dropbox widget hides the tray icon without replacing its menu: no Preferences, no Quit, and the login button does nothing

Reported by adnanmur · filed Aug 18, 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

Dropbox widget hides the tray icon without replacing its menu: no Preferences, no Quit, and the login button does nothingrevision 1 · captured 2026-09-28 21:29 UTC via poll

Summary

The omarchy.dropbox bar widget hides Dropbox's own tray icon, but it does not
provide the actions that icon carried. With the widget in the bar there is no
way to reach Dropbox Preferences and no way to quit Dropbox from the desktop.

A separate defect in the same widget means the login button cannot log in at
all, so a fresh Dropbox install cannot be linked from the bar.

Nothing crashes and nothing is logged, which is what makes this hard to spot:
the account still syncs perfectly while the UI in front of it does nothing.

1. The tray icon is suppressed and its menu is not replaced

shell/plugins/bar/widgets/TrayModel.js:

function ownedByOmarchy(item, layout) {
  return itemNamed(item, "localsend")
    || (layoutHasWidget(layout, "omarchy.dropbox") && itemNamed(item, "dropbox"))
}

With the widget in the bar, the tray drops Dropbox's StatusNotifierItem. Read
off DBus, that item's menu contains:

Open Dropbox Folder / Launch Dropbox Website / <team> / <account email> /
<usage> / Recently Changed Files / Pause Syncing / Snooze Notifications /
Preferences... / Help Center / Export Debug Logs / Quit Dropbox

The widget that replaces it binds three mouse buttons and nothing else
(shell/plugins/panels/dropbox/Panel.qml):

onPressed: function(buttonCode) {
  if (buttonCode === Qt.RightButton) dropbox.refresh()
  else if (buttonCode === Qt.MiddleButton) dropbox.login()
  else root.toggle()
}

Right-click fires a silent refresh, which reads as a dead click. Preferences and
Quit appear nowhere in the widget, and dropbox-cli has no equivalent for
either — its commands are autostart, exclude, filestatus, lansync, ls, proxy,
running, sharelink, start, status, stop, throttle, update, version.

The only remaining routes are dropbox-cli stop in a terminal, or driving
Dropbox's com.canonical.dbusmenu interface by hand.

Expected: if the widget takes the tray icon's place, it should offer the
tray icon's actions — at minimum Preferences and Quit.

2. The login button cannot log in

shell/plugins/panels/dropbox/Service.qml:

function login() {
  if (!installed || loginProcess.running) return
  ...
  loginProcess.command = ["dropbox-cli", "start"]
  loginProcess.running = true
}

The output is then scraped for a URL:

function openAuthUrlFrom(text) {
  var match = String(text || "").match(/https?:\/\/\S+/)
  ...
}

But dropbox-cli start only prints Starting Dropbox...Done!. The
account-link URL is written by dropboxd, not by the CLI. No URL is ever
matched, so Qt.openUrlExternally is never called, no browser opens, and no
error is surfaced. The button does nothing.

Steps to reproduce: on a machine with no linked Dropbox account, install the
Dropbox service, click "Login to Dropbox" in the widget. Nothing happens.

Expected: the browser opens Dropbox's account-link page.

3. authenticated is derived from a folder that does not exist yet

shell/plugins/panels/dropbox/status.py:

authenticated = account_path != "" and Path(account_path).exists()

account_path comes from ~/.dropbox/info.json, but the folder itself is not
created until the first sync. Until then authenticated is false and the panel
shows the login button from defect 2 — the one that does nothing. A new account
cannot get past this state from the bar.

4. The status helper walks the whole Dropbox tree on every poll

Same file:

used, files = scan_dropbox(account_path, limit) if authenticated else (0, [])

scan_dropbox runs os.walk over the entire account with no time or count
budget, and Service.qml calls it on a repeating timer with a default interval
of 60 seconds.

On a Business account here that is 860,630 files walked per poll, once a
minute, for a usage figure and 25 recent filenames. command_output has a
4-second timeout but the walk itself has none.

Expected: a bounded walk, a cached total, or a much longer interval.

Also worth a look

~/.config/omarchy/shell.json on this machine had a pinned tray entry of
"dropbox-client-3116". Dropbox's SNI id is dropbox-client-<pid>, so a pin
written for one daemon can never match after a restart. Pinning the Dropbox tray
icon cannot work as things stand.

System

Omarchy4.0.0-1
Hyprland0.56.2
quickshell0.3.0.r20.g28771c7-1
dropbox264.4.3421-1 (self-updates to 266.3.3869 in ~/.dropbox-dist)
dropbox-cli2024.04.17-2
HardwareRyzen 9800X3D, RTX 5080, X870 AORUS ELITE WIFI7

Workaround

For anyone hitting this before a fix: dropbox-cli stop quits the daemon, and
Preferences can be opened by clicking the item on Dropbox's dbusmenu directly.
Both the item id and the numeric menu ids change between calls, so they have to
be resolved each time:

read -r BUS PID < <(busctl --user list | awk '$0 ~ / dropbox / {print $1, $2; exit}')
OBJ="/org/ayatana/NotificationItem/dropbox_client_${PID}/Menu"
ID=$(busctl --user call "$BUS" "$OBJ" com.canonical.dbusmenu GetLayout iias 0 -- 1 1 label |
       tr ')' '\n' | grep -F '"Preferences..."' | head -1 | awk '{print $1}')
busctl --user call "$BUS" "$OBJ" com.canonical.dbusmenu Event isvu "$ID" clicked s "" 0

I am happy to open a PR for any or all of these if the approach is agreed.

View raw text
## Summary

The `omarchy.dropbox` bar widget hides Dropbox's own tray icon, but it does not
provide the actions that icon carried. With the widget in the bar there is no
way to reach Dropbox Preferences and no way to quit Dropbox from the desktop.

A separate defect in the same widget means the login button cannot log in at
all, so a fresh Dropbox install cannot be linked from the bar.

Nothing crashes and nothing is logged, which is what makes this hard to spot:
the account still syncs perfectly while the UI in front of it does nothing.

## 1. The tray icon is suppressed and its menu is not replaced

`shell/plugins/bar/widgets/TrayModel.js`:

```js
function ownedByOmarchy(item, layout) {
  return itemNamed(item, "localsend")
    || (layoutHasWidget(layout, "omarchy.dropbox") && itemNamed(item, "dropbox"))
}
```

With the widget in the bar, the tray drops Dropbox's StatusNotifierItem. Read
off DBus, that item's menu contains:

```
Open Dropbox Folder / Launch Dropbox Website / <team> / <account email> /
<usage> / Recently Changed Files / Pause Syncing / Snooze Notifications /
Preferences... / Help Center / Export Debug Logs / Quit Dropbox
```

The widget that replaces it binds three mouse buttons and nothing else
(`shell/plugins/panels/dropbox/Panel.qml`):

```qml
onPressed: function(buttonCode) {
  if (buttonCode === Qt.RightButton) dropbox.refresh()
  else if (buttonCode === Qt.MiddleButton) dropbox.login()
  else root.toggle()
}
```

Right-click fires a silent refresh, which reads as a dead click. Preferences and
Quit appear nowhere in the widget, and `dropbox-cli` has no equivalent for
either — its commands are autostart, exclude, filestatus, lansync, ls, proxy,
running, sharelink, start, status, stop, throttle, update, version.

The only remaining routes are `dropbox-cli stop` in a terminal, or driving
Dropbox's `com.canonical.dbusmenu` interface by hand.

**Expected:** if the widget takes the tray icon's place, it should offer the
tray icon's actions — at minimum Preferences and Quit.

## 2. The login button cannot log in

`shell/plugins/panels/dropbox/Service.qml`:

```qml
function login() {
  if (!installed || loginProcess.running) return
  ...
  loginProcess.command = ["dropbox-cli", "start"]
  loginProcess.running = true
}
```

The output is then scraped for a URL:

```qml
function openAuthUrlFrom(text) {
  var match = String(text || "").match(/https?:\/\/\S+/)
  ...
}
```

But `dropbox-cli start` only prints `Starting Dropbox...Done!`. The
account-link URL is written by **dropboxd**, not by the CLI. No URL is ever
matched, so `Qt.openUrlExternally` is never called, no browser opens, and no
error is surfaced. The button does nothing.

**Steps to reproduce:** on a machine with no linked Dropbox account, install the
Dropbox service, click "Login to Dropbox" in the widget. Nothing happens.

**Expected:** the browser opens Dropbox's account-link page.

## 3. `authenticated` is derived from a folder that does not exist yet

`shell/plugins/panels/dropbox/status.py`:

```python
authenticated = account_path != "" and Path(account_path).exists()
```

`account_path` comes from `~/.dropbox/info.json`, but the folder itself is not
created until the first sync. Until then `authenticated` is false and the panel
shows the login button from defect 2 — the one that does nothing. A new account
cannot get past this state from the bar.

## 4. The status helper walks the whole Dropbox tree on every poll

Same file:

```python
used, files = scan_dropbox(account_path, limit) if authenticated else (0, [])
```

`scan_dropbox` runs `os.walk` over the entire account with no time or count
budget, and `Service.qml` calls it on a repeating timer with a default interval
of 60 seconds.

On a Business account here that is **860,630 files walked per poll**, once a
minute, for a usage figure and 25 recent filenames. `command_output` has a
4-second timeout but the walk itself has none.

**Expected:** a bounded walk, a cached total, or a much longer interval.

## Also worth a look

`~/.config/omarchy/shell.json` on this machine had a pinned tray entry of
`"dropbox-client-3116"`. Dropbox's SNI id is `dropbox-client-<pid>`, so a pin
written for one daemon can never match after a restart. Pinning the Dropbox tray
icon cannot work as things stand.

## System

| | |
|---|---|
| Omarchy | 4.0.0-1 |
| Hyprland | 0.56.2 |
| quickshell | 0.3.0.r20.g28771c7-1 |
| dropbox | 264.4.3421-1 (self-updates to 266.3.3869 in `~/.dropbox-dist`) |
| dropbox-cli | 2024.04.17-2 |
| Hardware | Ryzen 9800X3D, RTX 5080, X870 AORUS ELITE WIFI7 |

## Workaround

For anyone hitting this before a fix: `dropbox-cli stop` quits the daemon, and
Preferences can be opened by clicking the item on Dropbox's dbusmenu directly.
Both the item id and the numeric menu ids change between calls, so they have to
be resolved each time:

```bash
read -r BUS PID < <(busctl --user list | awk '$0 ~ / dropbox / {print $1, $2; exit}')
OBJ="/org/ayatana/NotificationItem/dropbox_client_${PID}/Menu"
ID=$(busctl --user call "$BUS" "$OBJ" com.canonical.dbusmenu GetLayout iias 0 -- 1 1 label |
       tr ')' '\n' | grep -F '"Preferences..."' | head -1 | awk '{print $1}')
busctl --user call "$BUS" "$OBJ" com.canonical.dbusmenu Event isvu "$ID" clicked s "" 0
```

I am happy to open a PR for any or all of these if the approach is agreed.

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 04:44 UTC