evilsocket / evilsocket/opensnitch

Tray icon never appears when the StatusNotifierHost registers after UI startup (tray availability is only checked once)

Open
#1,659 1 comment 2 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.