Containerpak / Containerpak/cpak
[Feature] Support legacy XEmbed system tray icons on Wayland via SNI bridge
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 191
- Forks
- 3
- Avg merge
- 27m
- Merged PRs (30d)
- 16
Description
Problem
Apps using Qt's QSystemTrayIcon / GTK StatusIcon rely on the XEmbed
protocol (_NET_SYSTEM_TRAY_S0). Under cpak's nested displayX11
(Xwayland/Xephyr), nothing claims that selection, so the tray icon
is created but never rendered anywhere — the app itself needs zero
changes, there's just no tray manager present in the nested display.
Example: fptn-client-gui (Qt), tray icon silently disappears when
packaged for a pure-Wayland session (Niri, Hyprland, Sway).
Proposed solution
Don't reimplement XEmbed↔SNI translation — tools like snixembed
already do exactly this (claim the tray selection, expose a
StatusNotifierItem on D-Bus, replay clicks back via XSendEvent).
This is the same pattern non-containerized Wayland users already
rely on today with unmodified Qt/GTK apps.
Concretely, when displayX11 is set and a new flag is enabled:
"override": {
"displayX11": true,
"trayProxy": "xembed"
}
cpak would:
- Fetch/verify a static snixembed-equivalent binary (same pattern
as the slirp4netns bootstrap) and launch it inside the nested
X session before the app starts. - Widen the existing private desktop D-Bus proxy (currently used
for org.freedesktop.appearance / notifications / openURI) to
also forward org.kde.StatusNotifierItem and
org.kde.StatusNotifierWatcher calls between the bridge and
the host bus.
No pixmap capture or click-translation logic needs to be written —
the bridge already implements both directions; cpak only needs to
supervise its lifecycle and open the D-Bus interface allowlist.
Why this is low risk
Same components (Xwayland tray bridge → SNI → Wayland panel) are
already used unmodified outside containers. This is wiring, not
new protocol work.
Open question
Would you rather scope the D-Bus interface allowlist per-package
(declared permission) or make it a fixed part of trayProxy?
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 by tracing the existing displayX11 handling, the slirp4netns bootstrap, and the private desktop D-Bus proxy mentioned in the issue. Then determine how trayProxy configuration should control bridge startup and the StatusNotifierItem/Watcher allowlist. Done means the bridge is fetched, verified, supervised in the nested X session, and legacy tray icons are visible through the host Wayland panel.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, linux
- Domain
- desktop, operating-systems
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100