Hi,

In principle, this all sounds great.
This is a problem people have complained about but we've not got far in figuring out what to do. I don't have any view at this early stage on your question about using a shared connection.

The main concerns I'd have are
1) Whether the SNI operates in conformance with the specification for SystemTray/TrayIcon. 2) Using FFM would mean it could not be backported to JDk21u .. but that is a secondary concern. If the work is done and functional, a motivated person could convert to JNI for that.

I suggest the next step is to create a DRAFT PR against JDK mainline.
That will be easier for us to review and try it out before you spend time on polishing it.

-phil


On 6/3/26 5:14 AM, Marco Matessi wrote:
Hello,

I'm Marco Matessi. This is my first OpenJDK contribution; I have
signed the OCA. I've
put together an implementation for JDK-8035556 and would like feedback
on the approach
before opening a formal RFR.

The problem: on Ubuntu 24 and modern Wayland/GNOME desktops the legacy
X11 XEmbed
system tray protocol is no longer supported, so java.awt.TrayIcon is
effectively broken
there (see also JDK-8341144, PR #23329, which skips the test on
Wayland). The de facto
standard on current Linux desktops is the StatusNotifierItem (SNI)
D-Bus protocol used
by KDE, GNOME Shell extensions and AppIndicator.

What I've done: a working SNI peer implemented over D-Bus. When
org.kde.StatusNotifierWatcher is present on the session bus, TrayIcon/SystemTray
delegate to the SNI peer; otherwise they fall back to the existing X11
XEmbed peer.
XToolkit.createTrayIcon/createSystemTray/isTraySupported dispatch on that basis.

The D-Bus layer uses Panama FFM (java.lang.foreign) against
libdbus-1.so.3, with no
new JNI code and no new native build artifacts. New classes live in sun.awt.X11:
SNIDBusLib (FFM bindings), SNIMsg (DBusMessage wrapper), SNIDBusConn (session
connection + dispatch loop), SNITrayIconPeer (org.kde.StatusNotifierItem +
com.canonical.dbusmenu) and SNISystemTrayPeer. The dispatch loop runs on its own
platform thread, independent of the GTK L&F.

Why FFM rather than GDBus/JNI:
- It follows the declared direction away from JNI toward Panama FFM; new C in
   libawt_xawt would go the other way.
- libdbus-1 is not deprecated. GDBus is a wrapper over it, not a replacement.
- SystemTray should not depend on the Look&Feel; a GDBus/GTK path
would force GTK
   init even for Metal/Nimbus apps.
- dbus_bus_get_private yields a separate connection, so there's no
GMainLoop conflict
   with any GTK-internal D-Bus usage.

The implementation has been built and tested on Ubuntu 24.04 (GNOME, with the
AppIndicator shell extension) and includes three jtreg regression tests
(SNITrayIconTest, SNITrayIconPropertiesTest, SNIFallbackTest).

Two open items I'd like input on: currently there is one private
connection and one
dispatch thread per peer; a singleton shared connection is cleaner and
I'll implement
it based on feedback. SNITrayIconPeer is ~850 lines and I plan to split out an
SNIDBusMenu class.

Code (fork, branch JDK-8035556): https://github.com/basix86/jdk

I'd appreciate any guidance on the overall approach.

Thanks,
Marco Matessi

Reply via email to