From 034d716e5aa634087dfec83b2c1099a945972b81 Mon Sep 17 00:00:00 2001 From: Daniil Tatianin <99danilt@gmail.com> Date: Mon, 28 Sep 2026 01:50:58 +0300 Subject: [PATCH] Fix tray icon not displayed with GTK-based pystray backends on Linux On Linux, when PyGObject is available, pystray uses its appindicator or gtk backend. With these backends, run_detached() does not display anything by itself: it only schedules the icon creation on the GLib main loop, and expects the application to run that loop. The main loop was never started, so the icon was never displayed and its menu never worked, while the log still reported "Tray icon has been displayed". Without PyGObject, pystray falls back to its xorg backend, which runs its own loop but relies on XEmbed: on Wayland sessions (e.g. KDE Plasma) the icon is shown as a blank square that barely responds to clicks. Start the GLib main loop in a daemon thread when a GTK-based backend is used. Other backends (xorg, win32, darwin) are unchanged. Tested on Fedora 44 with KDE Plasma (Wayland), Python 3.14, pystray 0.19.5. --- main.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/main.py b/main.py index dad5251f..b711f227 100755 --- a/main.py +++ b/main.py @@ -190,6 +190,12 @@ def on_win32_wm_event(hWnd, msg, wParam, lParam): # For platforms != macOS, display the tray icon now with non-blocking function if platform.system() != "Darwin": tray_icon.run_detached() + # GTK-based backends (Linux) only schedule the icon on the GLib main loop: it must be running for the + # icon to appear and respond to clicks + if tray_icon.__module__ in ("pystray._appindicator", "pystray._gtk"): + import threading + from gi.repository import GLib + threading.Thread(target=GLib.MainLoop().run, daemon=True).start() logger.info("Tray icon has been displayed") except: tray_icon = None