evilsocket / evilsocket/opensnitch
Tray icon never appears when the StatusNotifierHost registers after UI startup (tray availability is only checked once)
- Dominant language
- Python
- Stars
- 14.1k
- Forks
- 665
- PR merge metrics
- No merged PRs in 30d
Description
### Describe the bug
`opensnitch-ui` creates its `QSystemTrayIcon` exactly once during startup
(`_setup_tray()`, `service.py` L219 in v1.7.2). Qt decides at icon creation
time which backend to use: if the StatusNotifier **host** is not registered
yet (`IsStatusNotifierHostRegistered` on `org.kde.StatusNotifierWatcher`),
Qt silently falls back to XEmbed — which does not exist on Wayland — and
never switches back. Result: no tray icon for the whole session, even though
a fully working tray appears a moment later.
The existing 10 s fallback (`_show_gui_if_tray_not_available()`, L258) only
opens the stats window; it does not retry the tray registration.
This is easy to hit with bars/shells that claim the
`org.kde.StatusNotifierWatcher` **name** early in their startup but register
the **host** only after their UI has finished loading (e.g. Quickshell /
DankMaterialShell). XDG autostart then races the bar on every login: the
watcher name is already on the bus, but the host isn't there yet when
opensnitch-ui performs its one-shot check.
### To Reproduce
1. Wayland session (Hyprland) with a Quickshell-based bar (DankMaterialShell), opensnitch-ui in XDG autostart.
2. Log in. opensnitch-ui starts ~1 s before the bar's tray host is registered.
3. `busctl --user get-property org.kde.StatusNotifierWatcher /StatusNotifierWatcher org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems` → `as 0` although opensnitch-ui is running; no icon for the whole session.
4. `systemctl --user restart` of the UI (after the bar is up) → icon appears immediately.
### Expected behavior
The UI should (re-)register its tray icon when a StatusNotifier host becomes
available after startup — e.g. via a `QDBusServiceWatcher` on
`org.kde.StatusNotifierWatcher` plus re-checking `IsStatusNotifierHostRegistered`,
recreating the `QSystemTrayIcon` when the host appears. GTK apps and most
Electron apps handle this; any once-only check loses the race by design.
### Workaround
systemd user drop-in for the autostart unit that delays the UI until the
host is registered:
```ini
[Service]
ExecStartPre=/bin/sh -c 'for i in $(seq 100); do busctl --user get-property org.kde.StatusNotifierWatcher /StatusNotifierWatcher org.kde.StatusNotifierWatcher IsStatusNotifierHostRegistered 2>/dev/null | grep -q true && exit 0; sleep 0.1; done'
```
Note: waiting for the watcher *name* alone is not sufficient (see above) —
the host property is the condition Qt actually checks.
### Environment
- OpenSnitch 1.7.2 (daemon + UI), Arch Linux / CachyOS
- Qt 5.15.18, PyQt 5.15.11, running via XWayland (`xcb` platform; Wayland plugin not found)
- Hyprland + DankMaterialShell 1.5.3 (Quickshell 0.3.1) as StatusNotifier watcher/host
Related: #940 (`--background` helps starting without a tray, but does not
make the icon appear once a tray shows up later).
Contributor guide
No contributing guide indexed for this repository
Research direction
Start in service.py at _setup_tray() around line 219 and review _show_gui_if_tray_not_available() around line 258. Reproduce the Wayland startup race with a delayed StatusNotifier host, then trace the existing QSystemTrayIcon setup and the suggested QDBusServiceWatcher approach. Done means the tray icon appears after the host registers without restarting opensnitch-ui, while the 10-second fallback still behaves as expected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100