mathoudebine / mathoudebine/turing-smart-screen-python
Tray icon never appears on Linux with the GTK or AppIndicator backend: run_detached() does not start a GLib main loop
Nobody has claimed this yet.
- Dominant language
- Rich Text Format
- Stars
- 2.3k
- Forks
- 412
- Avg merge
- 21h 10m
- Merged PRs (30d)
- 7
Description
Hardware: Turing Smart Screen 8.8 inch (USB)
OS: CachyOS (Arch), KDE Plasma 6, Wayland, Python 3.14
Commit: 262a28a
On KDE Plasma 6 the tray icon first showed up as a plain green rectangle
that could not be clicked. After installing libayatana-appindicator and
setting PYSTRAY_BACKEND=appindicator, the icon disappeared entirely, even
though the log still says "Tray icon has been displayed".
The reason is in pystray. In lib/pystray/_util/gtk.py, _run_detached()
does not start a main loop:
def _run_detached(self):
self._initialize()
atexit.register(lambda: self._finalize())
But _show, _update_icon and _update_menu are all decorated with @mainloop,
which schedules them through GObject.idle_add. With no running GLib main
loop those callbacks never execute, so the indicator object is created but
never registered.
This is confirmed on the D-Bus side. After starting main.py, the item is
absent from the watcher:
busctl --user call org.kde.StatusNotifierWatcher /StatusNotifierWatcher
org.freedesktop.DBus.Properties Get ss
org.kde.StatusNotifierWatcher RegisteredStatusNotifierItems
The green rectangle came from the xorg backend, which needs no main loop.
Plasma 6 removed xembedsniproxy, so XEmbed icons can no longer be drawn
properly, which is why it looked like a blank block.
Workaround that fixed it for me, in main.py, replacing
tray_icon.run_detached() on Linux:
import threading
threading.Thread(target=tray_icon.run, daemon=True).start()
_run() creates and runs its own GLib.MainLoop, and pystray already wraps
signal.signal in try/except ValueError so it tolerates a non-main thread.
The icon then registers correctly and the Configure and Exit menu works.
I am not sure what the cleanest fix is for the project, since this affects
Windows and macOS differently, but the current behaviour on Linux is that
the tray icon silently does not appear.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/pystray/_util/gtk.py and inspect _run_detached alongside the @mainloop methods _show, _update_icon, and _update_menu. Reproduce the Linux GTK or AppIndicator path and check RegisteredStatusNotifierItems with busctl. Done means the detached path runs the required callbacks and the tray icon and its Configure and Exit menu work on KDE Plasma 6.
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
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100