zbus update

This commit is contained in:
Ashley Wulber 2024-05-16 21:29:28 -04:00 committed by Michael Murphy
parent 2e9660f2a8
commit 87250b5e50
23 changed files with 613 additions and 484 deletions

834
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -48,7 +48,7 @@ libcosmic = { git = "https://github.com/pop-os/libcosmic", default-features = fa
rust-embed = "8.3"
rust-embed-utils = "8.3.0"
rustix = { version = "0.38", features = ["fs", "process"] }
zbus = { version = "3.15", default-features = false, features = ["tokio"] }
zbus = { version = "4.2.1", default-features = false, features = ["tokio"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tracing-log = "0.2.0"
@ -60,6 +60,9 @@ lto = "fat"
[workspace.metadata.cargo-machete]
ignored = ["libcosmic"]
# [patch."https://github.com/pop-os/libcosmic"]
# cosmic-config = { git = "https://github.com/pop-os/libcosmic//" }
# libcosmic = { git = "https://github.com/pop-os/libcosmic//" }
[patch."https://github.com/Smithay/client-toolkit"]
sctk = { git = "https://github.com/smithay/client-toolkit//", package = "smithay-client-toolkit", rev = "3bed072" }

View file

@ -13,7 +13,7 @@ futures.workspace = true
i18n-embed.workspace = true
i18n-embed-fl.workspace = true
image = { version = "0.25.0", default-features = false }
itertools = "0.12.1"
itertools = "0.13.0"
libcosmic.workspace = true
memmap2 = "0.9.4"
once_cell = "1.19"
@ -22,7 +22,13 @@ rust-embed.workspace = true
rustix.workspace = true
serde = { version = "1.0", features = ["derive"] }
switcheroo-control = { git = "https://github.com/pop-os/dbus-settings-bindings" }
tokio = { version = "1.36.0", features = ["sync", "rt", "rt-multi-thread", "macros", "process"] }
tokio = { version = "1.36.0", features = [
"sync",
"rt",
"rt-multi-thread",
"macros",
"process",
] }
tracing-log.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true

View file

@ -13,7 +13,7 @@ libpulse-binding = "2.28.1"
mpris2-zbus = { git = "https://github.com/pop-os/dbus-settings-bindings" }
rust-embed.workspace = true
serde = "1.0.197"
tokio = { version = "1.36.0", features=["full"] }
tokio = { version = "1.36.0", features = ["full"] }
tracing-log.workspace = true
tracing-subscriber.workspace = true
tracing.workspace = true

View file

@ -106,7 +106,7 @@ impl MprisPlayer {
}
fn name(&self) -> &BusName {
self.player.destination()
self.player.inner().destination()
}
}

View file

@ -18,11 +18,12 @@
//!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "com.system76.PowerDaemon",
default_path = "/com/system76/PowerDaemon"
default_path = "/com/system76/PowerDaemon",
assume_defaults = true
)]
trait PowerDaemon {
/// Balanced method
@ -70,10 +71,10 @@ trait PowerDaemon {
fn set_graphics_power(&self, power: bool) -> zbus::Result<()>;
/// HotPlugDetect signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn hot_plug_detect(&self, port: u64) -> zbus::Result<()>;
/// PowerProfileSwitch signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn power_profile_switch(&self, profile: &str) -> zbus::Result<()>;
}

View file

@ -10,9 +10,9 @@
//! section of the zbus documentation.
//!
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.freedesktop.UPower.PowerProfiles",
default_path = "/org/freedesktop/UPower/PowerProfiles",
assume_defaults = true
@ -25,40 +25,40 @@ trait PowerProfiles {
fn release_profile(&self, cookie: u32) -> zbus::Result<()>;
/// ProfileReleased signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn profile_released(&self, cookie: u32) -> zbus::Result<()>;
/// Actions property
#[dbus_proxy(property)]
#[zbus(property)]
fn actions(&self) -> zbus::Result<Vec<String>>;
/// ActiveProfile property
#[dbus_proxy(property)]
#[zbus(property)]
fn active_profile(&self) -> zbus::Result<String>;
#[dbus_proxy(property)]
#[zbus(property)]
fn set_active_profile(&self, value: &str) -> zbus::Result<()>;
/// ActiveProfileHolds property
#[dbus_proxy(property)]
#[zbus(property)]
fn active_profile_holds(
&self,
) -> zbus::Result<Vec<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>>;
/// PerformanceDegraded property
#[dbus_proxy(property)]
#[zbus(property)]
fn performance_degraded(&self) -> zbus::Result<String>;
/// PerformanceInhibited property
#[dbus_proxy(property)]
#[zbus(property)]
fn performance_inhibited(&self) -> zbus::Result<String>;
/// Profiles property
#[dbus_proxy(property)]
#[zbus(property)]
fn profiles(
&self,
) -> zbus::Result<Vec<std::collections::HashMap<String, zbus::zvariant::OwnedValue>>>;
/// Version property
#[dbus_proxy(property)]
#[zbus(property)]
fn version(&self) -> zbus::Result<String>;
}

View file

@ -19,7 +19,7 @@ use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
const BACKLIGHT_SYSDIR: &str = "/sys/class/backlight";
#[zbus::dbus_proxy(
#[zbus::proxy(
default_service = "org.freedesktop.login1",
interface = "org.freedesktop.login1.Session",
default_path = "/org/freedesktop/login1/session/auto"

View file

@ -3,11 +3,12 @@
//! This code was generated by `zbus-xmlgen` `2.0.1` from DBus introspection data.
//! Source: `Interface '/org/freedesktop/UPower' from service 'org.freedesktop.UPower' on system bus`.
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
default_service = "org.freedesktop.UPower",
interface = "org.freedesktop.UPower"
interface = "org.freedesktop.UPower",
default_path = "/org/freedesktop/UPower"
)]
trait UPower {
/// EnumerateDevices method
@ -20,26 +21,26 @@ trait UPower {
fn get_display_device(&self) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
/// DeviceAdded signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn device_added(&self, device: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// DeviceRemoved signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn device_removed(&self, device: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// DaemonVersion property
#[dbus_proxy(property)]
#[zbus(property)]
fn daemon_version(&self) -> zbus::Result<String>;
/// LidIsClosed property
#[dbus_proxy(property)]
#[zbus(property)]
fn lid_is_closed(&self) -> zbus::Result<bool>;
/// LidIsPresent property
#[dbus_proxy(property)]
#[zbus(property)]
fn lid_is_present(&self) -> zbus::Result<bool>;
/// OnBattery property
#[dbus_proxy(property)]
#[zbus(property)]
fn on_battery(&self) -> zbus::Result<bool>;
}

View file

@ -10,10 +10,10 @@ use cosmic::iced::{
};
use std::{fmt::Debug, hash::Hash};
use zbus::dbus_proxy;
use zbus::proxy;
use crate::upower::UPowerProxy;
#[dbus_proxy(
#[proxy(
default_service = "org.freedesktop.UPower",
interface = "org.freedesktop.UPower.Device"
)]
@ -33,123 +33,123 @@ trait Device {
fn refresh(&self) -> zbus::Result<()>;
/// BatteryLevel property
#[dbus_proxy(property)]
#[zbus(property)]
fn battery_level(&self) -> zbus::Result<u32>;
/// Capacity property
#[dbus_proxy(property)]
#[zbus(property)]
fn capacity(&self) -> zbus::Result<f64>;
/// ChargeCycles property
#[dbus_proxy(property)]
#[zbus(property)]
fn charge_cycles(&self) -> zbus::Result<i32>;
/// Energy property
#[dbus_proxy(property)]
#[zbus(property)]
fn energy(&self) -> zbus::Result<f64>;
/// EnergyEmpty property
#[dbus_proxy(property)]
#[zbus(property)]
fn energy_empty(&self) -> zbus::Result<f64>;
/// EnergyFull property
#[dbus_proxy(property)]
#[zbus(property)]
fn energy_full(&self) -> zbus::Result<f64>;
/// EnergyFullDesign property
#[dbus_proxy(property)]
#[zbus(property)]
fn energy_full_design(&self) -> zbus::Result<f64>;
/// EnergyRate property
#[dbus_proxy(property)]
#[zbus(property)]
fn energy_rate(&self) -> zbus::Result<f64>;
/// HasHistory property
#[dbus_proxy(property)]
#[zbus(property)]
fn has_history(&self) -> zbus::Result<bool>;
/// HasStatistics property
#[dbus_proxy(property)]
#[zbus(property)]
fn has_statistics(&self) -> zbus::Result<bool>;
/// IconName property
#[dbus_proxy(property)]
#[zbus(property)]
fn icon_name(&self) -> zbus::Result<String>;
/// IsPresent property
#[dbus_proxy(property)]
#[zbus(property)]
fn is_present(&self) -> zbus::Result<bool>;
/// IsRechargeable property
#[dbus_proxy(property)]
#[zbus(property)]
fn is_rechargeable(&self) -> zbus::Result<bool>;
/// Luminosity property
#[dbus_proxy(property)]
#[zbus(property)]
fn luminosity(&self) -> zbus::Result<f64>;
/// Model property
#[dbus_proxy(property)]
#[zbus(property)]
fn model(&self) -> zbus::Result<String>;
/// NativePath property
#[dbus_proxy(property)]
#[zbus(property)]
fn native_path(&self) -> zbus::Result<String>;
/// Online property
#[dbus_proxy(property)]
#[zbus(property)]
fn online(&self) -> zbus::Result<bool>;
/// Percentage property
#[dbus_proxy(property)]
#[zbus(property)]
fn percentage(&self) -> zbus::Result<f64>;
/// PowerSupply property
#[dbus_proxy(property)]
#[zbus(property)]
fn power_supply(&self) -> zbus::Result<bool>;
/// Serial property
#[dbus_proxy(property)]
#[zbus(property)]
fn serial(&self) -> zbus::Result<String>;
/// State property
#[dbus_proxy(property)]
#[zbus(property)]
fn state(&self) -> zbus::Result<u32>;
/// Technology property
#[dbus_proxy(property)]
#[zbus(property)]
fn technology(&self) -> zbus::Result<u32>;
/// Temperature property
#[dbus_proxy(property)]
#[zbus(property)]
fn temperature(&self) -> zbus::Result<f64>;
/// TimeToEmpty property
#[dbus_proxy(property)]
#[zbus(property)]
fn time_to_empty(&self) -> zbus::Result<i64>;
/// TimeToFull property
#[dbus_proxy(property)]
#[zbus(property)]
fn time_to_full(&self) -> zbus::Result<i64>;
/// Type property
#[dbus_proxy(property)]
#[zbus(property)]
fn type_(&self) -> zbus::Result<u32>;
/// UpdateTime property
#[dbus_proxy(property)]
#[zbus(property)]
fn update_time(&self) -> zbus::Result<u64>;
/// Vendor property
#[dbus_proxy(property)]
#[zbus(property)]
fn vendor(&self) -> zbus::Result<String>;
/// Voltage property
#[dbus_proxy(property)]
#[zbus(property)]
fn voltage(&self) -> zbus::Result<f64>;
/// WarningLevel property
#[dbus_proxy(property)]
#[zbus(property)]
fn warning_level(&self) -> zbus::Result<u32>;
}
@ -194,7 +194,8 @@ async fn start_listening(
if let Ok(devices) = upower.enumerate_devices().await {
let mut has_battery = false;
for device in devices {
let Ok(d) = DeviceProxy::builder(upower.connection()).path(device) else {
let Ok(d) = DeviceProxy::builder(upower.inner().connection()).path(device)
else {
continue;
};
let Ok(d) = d.build().await else {

View file

@ -6,9 +6,9 @@
use cosmic::iced::{self, futures::SinkExt, subscription};
use std::{fmt::Debug, hash::Hash};
use tokio::sync::mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender};
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
default_service = "org.freedesktop.UPower",
interface = "org.freedesktop.UPower.KbdBacklight",
default_path = "/org/freedesktop/UPower/KbdBacklight"
@ -24,11 +24,11 @@ trait KbdBacklight {
fn set_brightness(&self, value: i32) -> zbus::Result<()>;
/// BrightnessChanged signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn brightness_changed(&self, value: i32) -> zbus::Result<()>;
/// BrightnessChangedWithSource signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn brightness_changed_with_source(&self, value: i32, source: &str) -> zbus::Result<()>;
}

View file

@ -13,7 +13,7 @@ futures.workspace = true
futures-util.workspace = true
i18n-embed-fl.workspace = true
i18n-embed.workspace = true
itertools = "0.12.1"
itertools = "0.13.0"
libcosmic.workspace = true
rust-embed.workspace = true
tokio = { version = "1.36.0", features = ["full"] }

View file

@ -41,7 +41,7 @@ pub async fn handle_wireless_device(device: WirelessDevice<'_>) -> zbus::Result<
strength,
state,
working: false,
path: ap.path().to_owned(),
path: ap.inner().path().to_owned(),
},
);
}

View file

@ -23,7 +23,7 @@ use futures::{
};
use tokio::process::Command;
use zbus::{
zvariant::{self, Value},
zvariant::{self, OwnedValue, Value},
Connection,
};
@ -452,7 +452,9 @@ impl NetworkManagerState {
let map = (
s.0.to_string(),
s.1.iter()
.map(|(k, v)| (k.to_string(), v.clone().into()))
.filter_map(|(k, v)| {
OwnedValue::try_from(v).map(|v| (k.to_string(), v)).ok()
})
.collect::<HashMap<_, _>>(),
);
map
@ -463,15 +465,13 @@ impl NetworkManagerState {
nm.activate_connection(known_conn, &device).await?
} else {
let (_, active_conn) = nm
.add_and_activate_connection(conn_settings, device.path(), &ap.path)
.add_and_activate_connection(conn_settings, device.inner().path(), &ap.path)
.await?;
let dummy = ActiveConnectionProxy::new(&conn).await?;
let dummy = ActiveConnectionProxy::new(&conn, active_conn).await?;
let active = ActiveConnectionProxy::builder(&conn)
.path(active_conn)
.destination(dummy.inner().destination().to_owned())
.unwrap()
.destination(dummy.destination().to_owned())
.unwrap()
.interface(dummy.interface().to_owned())
.interface(dummy.inner().interface().to_owned())
.unwrap()
.build()
.await

View file

@ -17,13 +17,24 @@ tokio = { version = "1.36.0", features = [
"io-util",
"io-std",
] }
cosmic-notifications-config = { git = "https://github.com/pop-os/cosmic-notifications" }
cosmic-notifications-util = { git = "https://github.com/pop-os/cosmic-notifications" }
i18n-embed-fl.workspace = true
i18n-embed.workspace = true
rust-embed.workspace = true
tracing-log.workspace = true
cosmic-notifications-config = { git = "https://github.com/pop-os/cosmic-notifications" }
# cosmic-notifications-util = { path = "../../cosmic-notifications-daemon/cosmic-notifications-util" }
# cosmic-notifications-config = { path = "../../cosmic-notifications-daemon/cosmic-notifications-config" }
tracing = "0.1"
ron = "0.8"
sendfd = { version = "0.4", features = ["tokio"] }
bytemuck = "1"
tracing-subscriber.workspace = true
tracing.workspace = true
url = "2.5.0"
tracing-log.workspace = true
zbus.workspace = true
zbus.features = ["tokio", "p2p"]
# Application i18n
i18n-embed = { version = "0.13.4", features = [
"fluent-system",
"desktop-requester",
] }
i18n-embed-fl = "0.6.4"
rust-embed = "6.3.0"
rust-embed-utils = "7.5.0"
url = "2.5.0"

View file

@ -19,9 +19,9 @@
//!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "org.freedesktop.Notifications",
default_service = "org.freedesktop.Notifications",
default_path = "/org/freedesktop/Notifications"
@ -50,10 +50,10 @@ trait Notifications {
) -> zbus::Result<u32>;
/// ActionInvoked signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn action_invoked(&self, id: u32, action_key: &str) -> zbus::Result<()>;
/// NotificationClosed signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn notification_closed(&self, id: u32, reason: u32) -> zbus::Result<()>;
}

View file

@ -13,9 +13,9 @@ use std::{
use tracing::{error, trace};
use zbus::{
dbus_proxy,
connection::Builder,
export::futures_util::{SinkExt, StreamExt},
ConnectionBuilder,
proxy,
};
#[derive(Debug)]
@ -80,13 +80,13 @@ pub fn notifications(proxy: NotificationsAppletProxy<'static>) -> Subscription<N
)
}
#[dbus_proxy(
#[proxy(
default_service = "com.system76.NotificationsApplet",
interface = "com.system76.NotificationsApplet",
default_path = "/com/system76/NotificationsApplet"
)]
trait NotificationsApplet {
#[dbus_proxy(signal)]
#[zbus(signal)]
fn notify(
&self,
app_name: &str,
@ -108,7 +108,7 @@ pub async fn get_proxy() -> anyhow::Result<NotificationsAppletProxy<'static>> {
let stream = unsafe { std::os::unix::net::UnixStream::from_raw_fd(raw_fd) };
stream.set_nonblocking(true)?;
let stream = tokio::net::UnixStream::from_std(stream)?;
let conn = ConnectionBuilder::socket(stream).p2p().build().await?;
let conn = Builder::socket(stream).p2p().build().await?;
trace!("Applet connection created");
let proxy = NotificationsAppletProxy::new(&conn).await?;

View file

@ -8,7 +8,7 @@ license = "GPL-3.0"
i18n-embed-fl.workspace = true
i18n-embed.workspace = true
libcosmic.workspace = true
logind-zbus = "3.1"
logind-zbus = "4.0.3"
once_cell = "1.19.0"
rust-embed.workspace = true
rustix.workspace = true

View file

@ -1,9 +1,9 @@
// Copyright 2023 System76 <info@system76.com>
// SPDX-License-Identifier: GPL-3.0-only
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(
#[proxy(
interface = "com.system76.CosmicSession",
default_service = "com.system76.CosmicSession",
default_path = "/com/system76/CosmicSession"

View file

@ -21,9 +21,9 @@
//!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.
use zbus::dbus_proxy;
use zbus::proxy;
#[dbus_proxy(interface = "org.gnome.SessionManager", assume_defaults = true)]
#[proxy(interface = "org.gnome.SessionManager", assume_defaults = true)]
trait SessionManager {
/// CanRebootToFirmwareSetup method
fn can_reboot_to_firmware_setup(&self) -> zbus::Result<bool>;
@ -99,42 +99,42 @@ trait SessionManager {
fn unregister_client(&self, client_id: &zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// ClientAdded signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn client_added(&self, id: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// ClientRemoved signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn client_removed(&self, id: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// InhibitorAdded signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn inhibitor_added(&self, id: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// InhibitorRemoved signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn inhibitor_removed(&self, id: zbus::zvariant::ObjectPath<'_>) -> zbus::Result<()>;
/// SessionOver signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn session_over(&self) -> zbus::Result<()>;
/// SessionRunning signal
#[dbus_proxy(signal)]
#[zbus(signal)]
fn session_running(&self) -> zbus::Result<()>;
/// InhibitedActions property
#[dbus_proxy(property)]
#[zbus(property)]
fn inhibited_actions(&self) -> zbus::Result<u32>;
/// Renderer property
#[dbus_proxy(property)]
#[zbus(property)]
fn renderer(&self) -> zbus::Result<String>;
/// SessionIsActive property
#[dbus_proxy(property)]
#[zbus(property)]
fn session_is_active(&self) -> zbus::Result<bool>;
/// SessionName property
#[dbus_proxy(property)]
#[zbus(property)]
fn session_name(&self) -> zbus::Result<String>;
}

View file

@ -106,16 +106,16 @@ async fn get_layout(menu_proxy: DBusMenuProxy<'static>) -> Result<Layout, String
}
}
#[zbus::dbus_proxy(interface = "org.kde.StatusNotifierItem")]
#[zbus::proxy(interface = "org.kde.StatusNotifierItem")]
trait StatusNotifierItem {
#[dbus_proxy(property)]
#[zbus(property)]
fn icon_name(&self) -> zbus::Result<String>;
// https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/Icons
#[dbus_proxy(property)]
#[zbus(property)]
fn icon_pixmap(&self) -> zbus::Result<Vec<Icon>>;
#[dbus_proxy(property)]
#[zbus(property)]
fn menu(&self) -> zbus::Result<zvariant::OwnedObjectPath>;
}
@ -224,7 +224,7 @@ impl Layout {
}
}
#[zbus::dbus_proxy(interface = "com.canonical.dbusmenu")]
#[zbus::proxy(interface = "com.canonical.dbusmenu")]
trait DBusMenu {
fn get_layout(
&self,
@ -236,6 +236,6 @@ trait DBusMenu {
fn event(&self, id: i32, event_id: &str, data: &OwnedValue, timestamp: u32)
-> zbus::Result<()>;
#[dbus_proxy(signal)]
#[zbus(signal)]
fn layout_updated(&self, revision: u32, parent: i32) -> zbus::Result<()>;
}

View file

@ -10,7 +10,7 @@ use crate::subscriptions::status_notifier_item::StatusNotifierItem;
// TODO: Don't use trait object
pub type EventStream = Pin<Box<dyn Stream<Item = Event> + Send>>;
#[zbus::dbus_proxy(
#[zbus::proxy(
interface = "org.kde.StatusNotifierWatcher",
default_service = "org.kde.StatusNotifierWatcher",
default_path = "/StatusNotifierWatcher"
@ -18,13 +18,13 @@ pub type EventStream = Pin<Box<dyn Stream<Item = Event> + Send>>;
trait StatusNotifierWatcher {
fn register_status_notifier_host(&self, name: &str) -> zbus::Result<()>;
#[dbus_proxy(property)]
#[zbus(property)]
fn registered_status_notifier_items(&self) -> zbus::Result<Vec<String>>;
#[dbus_proxy(signal)]
#[zbus(signal)]
fn status_notifier_item_registered(&self, name: &str) -> zbus::Result<()>;
#[dbus_proxy(signal)]
#[zbus(signal)]
fn status_notifier_item_unregistered(&self, name: &str) -> zbus::Result<()>;
}

View file

@ -30,7 +30,7 @@ impl StatusNotifierWatcher {
#[zbus(header)] hdr: MessageHeader<'_>,
#[zbus(signal_context)] ctxt: SignalContext<'_>,
) {
let sender = hdr.sender().unwrap().unwrap();
let sender = hdr.sender().unwrap();
let service = if service.starts_with('/') {
format!("{}{}", sender, service)
} else {