fix: Load systray items that are registered without a path (#1230)

Co-authored-by: ElKowar <dev@elkowar.dev>
This commit is contained in:
Joel S 2025-02-06 05:14:49 +10:00 committed by GitHub
parent c6decc815a
commit 49b3066a6a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 111 additions and 33 deletions

View file

@ -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)
- `get_locale` now follows POSIX standard for locale selection (By: mirhahn, w-lfchen)
### Features

76
Cargo.lock generated
View file

@ -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]]

View file

@ -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

View file

@ -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<DBusInterface>,
#[serde(default)]
node: Vec<DBusNode>,
#[serde(rename = "@name")]
name: Option<String>,
}
#[derive(Deserialize)]
struct DBusInterface {
#[serde(rename = "@name")]
name: String,
}
async fn resolve_pathless_address(con: &zbus::Connection, service: &str, path: String) -> zbus::Result<Option<String>> {
let introspection_xml =
IntrospectableProxy::builder(con).destination(service)?.path(path.as_str())?.build().await?.introspect().await?;
let dbus_node =
quick_xml::de::from_str::<DBusNode>(&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 })
}