Skip to content

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

Description

@dkIT25

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:

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions