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

Open
#1,061 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.