Skip to content

fix(desktop): show tray icon on linux sessions without xembed tray - #1563

Open
sannidhyaroy wants to merge 1 commit into
AChep:masterfrom
sannidhyaroy:fix/linux-tray-availability
Open

fix(desktop): show tray icon on linux sessions without xembed tray#1563
sannidhyaroy wants to merge 1 commit into
AChep:masterfrom
sannidhyaroy:fix/linux-tray-availability

Conversation

@sannidhyaroy

Copy link
Copy Markdown

Summary

isTraySupported reports whether the legacy XEmbed system tray is available, but the tray icon is a StatusNotifierItem published on the session bus. Compose Native Tray's Linux backend speaks SNI over sd-bus and never touches AWT. The XEmbed tray is missing on sessions that implement only the modern protocol, and inside the Flatpak sandbox, so the tray icon and Close to tray were silently disabled there even though both of them work. With Close to tray enabled, closing the window quit the app instead of collapsing it into the tray.

Changes

  • desktopApp/src/jvmMain/kotlin/com/artemchep/keyguard/Main.kt: gate the tray on isTrayAvailable, which reports true on Linux and defers to isTraySupported everywhere else.
  • desktopApp/flatpak/com.artemchep.keyguard.yml: own the well-known name the tray backend requests before it registers the icon with the watcher.

Platform impact

Target Effect
Android, Wear OS, iOS None. Main.kt is desktop-only, and the Close to tray setting is already gated on Platform.Desktop.
Windows, macOS No behaviour change. Both still take the isTraySupported branch.
Linux (deb, AppImage, AUR) Tray and Close to tray now work on sessions with no XEmbed tray manager.
Linux (Flatpak) Needs both changes; the manifest line affects only the Flatpak artifact.

Why not probe AWT on Linux

java.awt.SystemTray.isSupported() answers a question about the XEmbed tray, which this app does not use. Measured with the same JDK 21 on GNOME 50 (Wayland, AppIndicator extension):

SystemTray.isSupported() XSystemTrayPeer.isAvailable()
host true true
inside the Flatpak sandbox false false

The same should apply to any session that ships only an SNI host, such as a Wayland compositor with waybar, where the icon works but AWT reports no tray. I have not measured that case.

Why the Flatpak needs --own-name

libLinuxTray.so calls sd_bus_request_name("org.kde.StatusNotifierItem-<pid>-1") and aborts if that fails. Inside the sandbox, without the name granted:

sni: failed to request bus name 'org.kde.StatusNotifierItem-2-1': No route to host
nativeRun=-113

With it granted, the item registers with the watcher and the icon appears. The number is the app's PID inside the sandbox, which is why the name cannot be spelled more generally. --own-name=org.kde.StatusNotifierItem-* is rejected by Flatpak as an invalid name, and --own-name=org.kde.* trips finish-args-own-name-wildcard-org.kde in flatpak-builder-lint.

This line can be dropped once the tray backend registers the item under the unique connection name when RequestName fails, the way Qt/KNotifications, libayatana-appindicator and Chromium do, which is also why other Flathub apps ship tray icons with only --talk-name=org.kde.StatusNotifierWatcher.

Testing

On openSUSE Slowroll, GNOME 50 (Wayland) with the AppIndicator extension:

  • Built the Flatpak from this branch and installed it; the tray icon appears in the top bar and Close to tray collapses the window into it.
  • Confirmed the exported metadata carries the permission: org.kde.StatusNotifierItem-2-1=own alongside the existing org.kde.StatusNotifierWatcher=talk.
  • Drove the tray backend directly inside the sandbox: registration fails with the error quoted above without the permission, and succeeds with it, with the item showing up in org.kde.StatusNotifierWatcher.RegisteredStatusNotifierItems and its menu callbacks reaching the sandboxed process.

Refs #1248: the same Close to tray flow on a Flatpak install. The missing bus name ownership is a plausible cause of the icon being unresponsive there, but that report is from KDE Plasma on an older version, and the duplicate instance behaviour it also describes is a separate matter I have not verified, so I have not marked it as closed.

NOTE: Diagnosis, testing and descriptions were done by Claude Opus 5 xhigh. All AI-assisted work has been overseen and reviewed by me.

`isTraySupported` reports whether the legacy XEmbed system tray is available, but our tray icon is a `StatusNotifierItem` published on the session bus. The XEmbed tray is missing on sessions that implement only the modern protocol, as well as inside the Flatpak sandbox, so the tray icon and the close to tray option were silently disabled there even though both of them work.

The Flatpak build also has to own the well known name that the tray backend requests before it registers the icon with the watcher, otherwise the backend fails with:
```
sni: failed to request bus name
'org.kde.StatusNotifierItem-2-1': No route to host
```

The `--own-name` can be dropped once the backend registers the icon under the unique connection name instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@sannidhyaroy

Copy link
Copy Markdown
Author

I have read the CLA Document and I hereby sign the CLA

github-actions Bot added a commit that referenced this pull request Sep 2, 2026
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