Skip to content

fix(tray): make the tray work on Linux desktops - #400

Open
cbyrd01 wants to merge 2 commits into
google:mainfrom
cbyrd01:fix/linux-tray
Open

cbyrd01 wants to merge 2 commits into
google:mainfrom
cbyrd01:fix/linux-tray

Conversation

@cbyrd01

@cbyrd01 cbyrd01 commented Nov 10, 2026 •

Copy link
Copy Markdown

Two commits:

  1. fix(tray): tray-icon's Linux backend (libayatana-appindicator) needs GTK initialised before the icon is built and the GTK main loop iterated afterwards. capsem-tray did neither. It now calls gtk::init() and drains pending GTK events on each pass of the existing loop. Without a display it exits 0, as it already does when there is no live service.
  2. fix(service): the service started the tray only on macOS. It now starts it on Linux under the same condition (after the gateway is ready).

gtk 0.18 is already in Cargo.lock through tray-icon and muda; the lock change is one added edge, recorded in tests/citadel/cargo_lock_identity.toml.

Tests. cargo test -p capsem-tray (88 pass) and cargo clippy -p capsem-service -p capsem-tray --bins --tests -- -D warnings are clean. There is no new unit test: both changes are platform wiring with no logic to isolate. Verified on Omarchy (Hyprland) with a build of main plus these commits: the service starts the tray, the icon appears, and its menu opens the app. Run with no display, it logs "no graphical session for the tray; exiting 0" and exits 0.

Runtime library. tray-icon loads libayatana-appindicator3 (or libappindicator3) at run time and panics if neither is installed. The .deb depends on neither (package_runtime_packages in config/gate.toml). On a desktop without one, the tray now starts and panics once into tray.log. From reading spawn_companions, nothing restarts it and the service carries on, but I haven't run that case. I left the dependency list alone. I can add libayatana-appindicator3-1, or probe for the library and exit 0, if you prefer either.

Open question. On a host with no graphical session the service now starts a tray process that immediately exits 0. If you would rather not spawn it at all there, I can gate the spawn on WAYLAND_DISPLAY / DISPLAY instead.

🤖 Generated with Claude Code

tray-icon's Linux backend (libayatana-appindicator) needs GTK
initialised before the icon is built and the GTK main loop iterated
afterwards. capsem-tray did neither, so on Linux it failed at startup
and could never show an icon or deliver a menu click.

Initialise GTK before building the icon and drain pending GTK events on
each pass of the existing loop. Without a display there is no tray to
draw, so exit 0 as the tray already does when there is no live service.

gtk 0.18 is already in the lock through tray-icon and muda; this only
adds the direct edge.
The tray was spawned only on macOS, on the premise that Linux has no
system tray. Linux desktops do (StatusNotifierItem), and capsem-tray now
runs there, so spawn it on Linux under the same condition as on macOS:
after the gateway is ready. On a host with no graphical session the
tray exits 0 by itself, and a missing tray binary was already non-fatal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant