#1659·opensnitch

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

Author: dkIT25Created Aug 24, 2026Updated Sep 2, 2026

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 RegisteredStatusNotifierItemsas 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).