From d11d7440326fbfec5084bfbad076bf5252b8f185 Mon Sep 17 00:00:00 2001 From: FTCHD <144691102+FTCHD@users.noreply.github.com> Date: Tue, 14 Oct 2025 02:06:50 +0200 Subject: [PATCH] better tray check on linux Signed-off-by: FTCHD <144691102+FTCHD@users.noreply.github.com> --- src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/src/lib.rs | 64 ++++++++++++++++++++++++++++---------------- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index c0a976b..58ec29c 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -284,6 +284,7 @@ dependencies = [ "tauri-plugin-single-instance", "tauri-plugin-store", "tauri-plugin-updater", + "x11rb", "zbus", "zip 0.6.6", ] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 011826d..5b07d94 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -51,3 +51,4 @@ cocoa = "0.26" [target.'cfg(target_os = "linux")'.dependencies] zbus = { version = "5" } +x11rb = "0.13" diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 810c069..a344e30 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -27,34 +27,52 @@ fn is_tray_supported() -> bool { use zbus::blocking::{Connection, Proxy}; use zbus::names::BusName; - let conn = match Connection::session() { - Ok(c) => c, - Err(_) => return false, - }; + if let Ok(conn) = Connection::session() { + if let Ok(dbus) = DBusProxy::new(&conn) { + let candidates = [ + "org.kde.StatusNotifierWatcher", + "org.freedesktop.StatusNotifierWatcher", + ]; - let dbus = match DBusProxy::new(&conn) { - Ok(p) => p, - Err(_) => return false, - }; + for name in candidates { + let bus_name = match BusName::try_from(name) { + Ok(n) => n, + Err(_) => continue, + }; + if dbus.name_has_owner(bus_name).unwrap_or(false) { + // Try to read the property; if it fails but watcher exists, assume true + if let Ok(proxy) = Proxy::new(&conn, name, "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher") { + if let Ok(registered) = proxy.get_property::("IsStatusNotifierHostRegistered") { + return registered; + } + } + return true; + } + } + } + } - let candidates = [ - "org.kde.StatusNotifierWatcher", - "org.freedesktop.StatusNotifierWatcher", - ]; + // legacy XEmbed tray (X11 _NET_SYSTEM_TRAY_Sn) + { + use std::env; + use x11rb::protocol::xproto::ConnectionExt; - for name in candidates { - let bus_name = match BusName::try_from(name) { - Ok(n) => n, - Err(_) => continue, - }; - if dbus.name_has_owner(bus_name).unwrap_or(false) { - // Try to read the property; if it fails but watcher exists, assume true - if let Ok(proxy) = Proxy::new(&conn, name, "/StatusNotifierWatcher", "org.kde.StatusNotifierWatcher") { - if let Ok(registered) = proxy.get_property::("IsStatusNotifierHostRegistered") { - return registered; + // If Wayland-only (no X server), no legacy tray will exist + if env::var_os("WAYLAND_DISPLAY").is_some() && env::var_os("DISPLAY").is_none() { + return false; + } + + if let Ok((conn, screen_num)) = x11rb::connect(None) { + let sel_name = format!("_NET_SYSTEM_TRAY_S{}", screen_num); + if let Ok(atom_cookie) = conn.intern_atom(false, sel_name.as_bytes()) { + if let Ok(atom_reply) = atom_cookie.reply() { + if let Ok(owner_cookie) = conn.get_selection_owner(atom_reply.atom) { + if let Ok(owner_reply) = owner_cookie.reply() { + return owner_reply.owner != 0; + } + } } } - return true; } }