diff --git a/CHANGELOG.md b/CHANGELOG.md index 3710363e..85ab2068 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to eww will be listed here, starting at changes since versio - Fix values in the `EWW_NET` variable (By: mario-kr) - Fix the gtk `expander` widget (By: ovalkonia) - Fix wayland monitor names support (By: dragonnn) +- Load systray items that are registered without a path (By: Kage-Yami) ### Features - Update rust toolchain to 1.81.0 (By: w-lfchen) diff --git a/Cargo.lock b/Cargo.lock index 01f65986..7c039845 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -230,7 +230,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -265,7 +265,7 @@ checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -424,7 +424,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -584,7 +584,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -716,7 +716,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -727,7 +727,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -811,7 +811,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "unicode-xid", ] @@ -897,7 +897,7 @@ checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1029,7 +1029,7 @@ checksum = "311a6d2f1f9d60bff73d2c78a0af97ed27f79672f15c238192a5bbb64db56d00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1171,7 +1171,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1394,7 +1394,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1520,7 +1520,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -1999,6 +1999,8 @@ dependencies = [ "dbusmenu-gtk3", "gtk", "log", + "quick-xml", + "serde", "thiserror", "tokio", "zbus", @@ -2179,7 +2181,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2360,6 +2362,16 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1190fd18ae6ce9e137184f207593877e70f39b015040156b1e05081cdfe3733a" +[[package]] +name = "quick-xml" +version = "0.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f22f29bdff3987b4d8632ef95fd6424ec7e4e0a57e2f4fc63e489e75357f6a03" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "quote" version = "1.0.37" @@ -2456,7 +2468,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2565,22 +2577,22 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2603,7 +2615,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2723,7 +2735,7 @@ checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2790,7 +2802,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2806,9 +2818,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.79" +version = "2.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" dependencies = [ "proc-macro2", "quote", @@ -2911,7 +2923,7 @@ checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -2941,7 +2953,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -3021,7 +3033,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -3151,7 +3163,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "wasm-bindgen-shared", ] @@ -3173,7 +3185,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -3264,7 +3276,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -3275,7 +3287,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] @@ -3590,7 +3602,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn 2.0.87", ] [[package]] diff --git a/crates/notifier_host/Cargo.toml b/crates/notifier_host/Cargo.toml index c4fd64f6..e1dc048e 100644 --- a/crates/notifier_host/Cargo.toml +++ b/crates/notifier_host/Cargo.toml @@ -10,6 +10,8 @@ homepage = "https://github.com/elkowar/eww" [dependencies] dbusmenu-gtk3 = "0.1.0" +quick-xml = { version = "0.37.1", features = ["serialize"] } +serde = "1.0.215" gtk.workspace = true log.workspace = true diff --git a/crates/notifier_host/src/item.rs b/crates/notifier_host/src/item.rs index a6cb2afb..889937d4 100644 --- a/crates/notifier_host/src/item.rs +++ b/crates/notifier_host/src/item.rs @@ -1,6 +1,8 @@ use crate::*; use gtk::{self, prelude::*}; +use serde::Deserialize; +use zbus::fdo::IntrospectableProxy; /// Recognised values of [`org.freedesktop.StatusNotifierItem.Status`]. /// @@ -61,7 +63,12 @@ impl Item { if let Some((addr, path)) = service.split_once('/') { (addr.to_owned(), format!("/{}", path)) } else if service.starts_with(':') { - (service[0..6].to_owned(), names::ITEM_OBJECT.to_owned()) + ( + service.to_owned(), + resolve_pathless_address(con, service, "/".to_owned()) + .await? + .ok_or_else(|| zbus::Error::Failure(format!("no StatusNotifierItem found for {service}")))?, + ) } else { return Err(zbus::Error::Address(service.to_owned())); } @@ -105,3 +112,59 @@ impl Item { load_icon_from_sni(&self.sni, size, scale).await } } + +#[derive(Deserialize)] +struct DBusNode { + #[serde(default)] + interface: Vec, + + #[serde(default)] + node: Vec, + + #[serde(rename = "@name")] + name: Option, +} + +#[derive(Deserialize)] +struct DBusInterface { + #[serde(rename = "@name")] + name: String, +} + +async fn resolve_pathless_address(con: &zbus::Connection, service: &str, path: String) -> zbus::Result> { + let introspection_xml = + IntrospectableProxy::builder(con).destination(service)?.path(path.as_str())?.build().await?.introspect().await?; + + let dbus_node = + quick_xml::de::from_str::(&introspection_xml).map_err(|err| zbus::Error::Failure(err.to_string()))?; + + if dbus_node.interface.iter().any(|interface| interface.name == "org.kde.StatusNotifierItem") { + // This item implements the desired interface, so bubble it back up + Ok(Some(path)) + } else { + for node in dbus_node.node { + if let Some(name) = node.name { + if name == "StatusNotifierItem" { + // If this exists, then there's a good chance DBus may not think anything + // implements the desired interface, so just bubble this up instead. + return Ok(Some(join_to_path(&path, name))); + } + + let path = Box::pin(resolve_pathless_address(con, service, join_to_path(&path, name))).await?; + + if path.is_some() { + // Return the first item found from a child + return Ok(path); + } + } + } + + // No children had the item we want... + Ok(None) + } +} + +fn join_to_path(path: &str, name: String) -> String { + // Make sure we don't double-up on the leading slash + format!("{path}/{name}", path = if path == "/" { "" } else { path }) +}