НазадДобавить комментарий
Linux (X11): tray icon floats in top-left corner — AppIndicator helper is rejected because it never sends a startup line
БагГотовоМелочьПубличныйDesktop
Автор: n*********@gmail.com
Создан: 20.07.2026, 13:19:58
Версия приложения: 3.3.2
Версия ОС: Linux Mint 22.3
Модель устройства: maibenben s14a
### Summary
On the Linux desktop build, the system tray icon does not embed into the panel.
Instead it appears as a small detached window pinned to the **top-left corner** of
the screen. This is the AWT `SystemTray` fallback being used because the bundled
AppIndicator helper (`incy-tray.py`) is wrongly considered "not usable".
### Environment
- INCY Desktop **3.3.2** (Linux x64, `.deb` install to `/opt/incy`)
- Linux Mint / Cinnamon (`XDG_CURRENT_DESKTOP=X-Cinnamon`), **X11** session
- Ayatana AppIndicator stack present and working:
`python3 -c "import gi; gi.require_version('AyatanaAppIndicator3','0.1'); from gi.repository import AyatanaAppIndicator3"` → OK
### Steps to reproduce
1. Install the Linux desktop build on an X11 Cinnamon session (StatusNotifier/AppIndicator available).
2. Launch INCY.
3. Observe the tray icon.
### Expected
Tray icon embeds into the panel's status area (like other AppIndicator apps, e.g. Spotify).
### Actual
Tray icon renders as a floating 20×20 window in the top-left corner. App log shows:
```
[W/LinuxTray] AppIndicator helper not usable — falling back to AWT
```
### Diagnosis
The AppIndicator path itself works fine on this system. When `incy-tray.py` is run
manually with stdin kept open, it stays alive and correctly registers a
`StatusNotifierItem` on the bus:
```
$ dbus-send --session --print-reply --dest=org.kde.StatusNotifierWatcher \
/StatusNotifierWatcher org.freedesktop.DBus.Properties.Get \
string:org.kde.StatusNotifierWatcher string:RegisteredStatusNotifierItems
...
string ":1.208/org/ayatana/NotificationItem/incy_vpn" # <-- appears while helper runs
```
From the observed process behaviour, the host side (LinuxTray) starts the helper
and then waits (~3 s) for the helper to emit a **first line on stdout** that is not
`UNSUPPORTED`; only then does it consider the helper usable. But on a successful
start, the shipped `incy-tray.py` prints **nothing** to stdout — it only writes on
`CLICK`/`ACTIVATE`. So the host's read blocks, the ~3 s timeout elapses, the healthy
helper is killed, and it falls back to the AWT floating icon.
Confirmed by MITM'ing the helper's pipes: the host sends nothing on the helper's
stdin at startup, and no readiness line ever comes back — exactly a 3.000 s gap
between spawn and the "not usable" log line.
### Proposed fix (helper side, one line)
Have the helper emit a single readiness line right after the indicator is created
successfully (before `Gtk.main()`). Any non-`UNSUPPORTED` line works; the host's
`handleLine` ignores anything that isn't `CLICK `/`ACTIVATE`.
```diff
--- a/incy-tray.py
+++ b/incy-tray.py
@@ -105,6 +105,8 @@
def main() -> None:
tray = Tray()
+ # INCY host waits (readLine, 3s) for a first stdout line that is not "UNSUPPORTED".
+ print("READY", flush=True)
# Middle/secondary click → ACTIVATE (left-click behaviour varies by host).
try:
tray.indicator.connect("secondary-activate", lambda _i: tray.secondary_activate())
```
Verified locally: after this change the log becomes
`[I/LinuxTray] AppIndicator tray started`, the helper stays alive, `incy_vpn`
registers on the StatusNotifierWatcher, and the icon embeds into the Cinnamon panel.
### Alternative (host side)
If you'd rather not require a handshake line, treat the helper as usable when the
process is still alive and hasn't printed `UNSUPPORTED` after the timeout, instead
of requiring a first stdout line. Either fix resolves it.
Комментарии (1)
Команда INCYadmin20.07.2026, 13:27:19
Thanks, fixed in next version