From 2f8c4ec6fae7880344dd05e65e7ab00b3d8e133b Mon Sep 17 00:00:00 2001 From: Benedikt Reinartz Date: Tue, 12 Nov 2024 14:40:22 +0100 Subject: [PATCH] Remove caching and prepare for tooltip support --- .../src/components/status_menu.rs | 17 +++++- .../src/subscriptions/status_notifier_item.rs | 55 ++++++++++++++----- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/cosmic-applet-status-area/src/components/status_menu.rs b/cosmic-applet-status-area/src/components/status_menu.rs index eb0f2070..9b5e7f53 100644 --- a/cosmic-applet-status-area/src/components/status_menu.rs +++ b/cosmic-applet-status-area/src/components/status_menu.rs @@ -9,6 +9,7 @@ use crate::subscriptions::status_notifier_item::{IconNameOrPixmap, Layout, Statu pub enum Msg { Icon(Option), Layout(Result), + Tooltip(String), Click(i32, bool), } @@ -16,6 +17,7 @@ pub enum Msg { pub struct State { item: StatusNotifierItem, layout: Option, + tooltip: String, icon: Option, expanded: Option, } @@ -28,6 +30,7 @@ impl State { layout: None, expanded: None, icon: None, + tooltip: Default::default(), }, iced::Task::none(), ) @@ -37,7 +40,11 @@ impl State { match message { Msg::Icon(icon) => { self.icon = icon; - iced::Command::none() + iced::Task::none() + } + Msg::Tooltip(tooltip) => { + self.tooltip = tooltip; + iced::Task::none() } Msg::Layout(layout) => { match layout { @@ -72,11 +79,16 @@ impl State { } pub fn icon_handle(&self) -> icon::Handle { - self.icon.as_ref() + self.icon + .as_ref() .map(|i| i.clone().into()) .unwrap_or_else(|| icon::from_raster_bytes(&[])) } + pub fn tooltip(&self) -> &str { + &self.tooltip + } + pub fn popup_view(&self) -> cosmic::Element { if let Some(layout) = self.layout.as_ref() { layout_view(layout, self.expanded) @@ -88,6 +100,7 @@ impl State { pub fn subscription(&self) -> iced::Subscription { let subs = vec![ self.item.icon_subscription().map(Msg::Icon), + self.item.tooltip_subscription().map(Msg::Tooltip), self.item.layout_subscription().map(Msg::Layout), ]; diff --git a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs index 6ae744bd..6303d1c3 100644 --- a/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs +++ b/cosmic-applet-status-area/src/subscriptions/status_notifier_item.rs @@ -13,7 +13,7 @@ pub struct StatusNotifierItem { name: String, // icon_name: String, // icon_pixmap: Option, - _item_proxy: StatusNotifierItemProxy<'static>, + item_proxy: StatusNotifierItemProxy<'static>, menu_proxy: DBusMenuProxy<'static>, } @@ -55,7 +55,6 @@ impl StatusNotifierItem { }; let item_proxy = StatusNotifierItemProxy::builder(connection) - .cache_properties(zbus::proxy::CacheProperties::Yes) .destination(dest.to_string())? .path(path.to_string())? .build() @@ -70,7 +69,7 @@ impl StatusNotifierItem { Ok(Self { name, - _item_proxy: item_proxy, + item_proxy, menu_proxy, }) } @@ -80,9 +79,9 @@ impl StatusNotifierItem { } pub fn icon_subscription(&self) -> iced::Subscription> { - let item_proxy = self._item_proxy.clone(); - iced::subscription::run_with_id( - format!("status-notifier-newicon-{}", &self.name), + let item_proxy = self.item_proxy.clone(); + Subscription::run_with_id( + format!("status-notifier-icon-{}", &self.name), async move { let initial = futures::stream::once(get_icon(item_proxy.clone())); let updates = item_proxy @@ -96,6 +95,20 @@ impl StatusNotifierItem { ) } + pub fn tooltip_subscription(&self) -> iced::Subscription { + let item_proxy = self.item_proxy.clone(); + Subscription::run_with_id( + format!("status-notifier-tooltip-{}", &self.name), + async move { + let initial = futures::stream::once(get_tooltip(item_proxy.clone())); + let update_stream = item_proxy.receive_new_tooltip().await.unwrap(); + let updates = update_stream.then(move |_| get_tooltip(item_proxy.clone())); + initial.chain(updates) + } + .flatten_stream() + ) + } + // TODO: Only fetch changed part of layout, if that's any faster pub fn layout_subscription(&self) -> iced::Subscription> { let menu_proxy = self.menu_proxy.clone(); @@ -123,20 +136,24 @@ async fn get_layout(menu_proxy: DBusMenuProxy<'static>) -> Result) -> Option { - if let Ok(pixmaps) = item_proxy.icon_pixmap().await { - // TODO Handle icon with multiple sizes? - return Some(IconNameOrPixmap::Pixmap( - pixmaps.into_iter().max_by_key(|i| (i.width, i.height))?, - )); - } +async fn get_tooltip(item_proxy: StatusNotifierItemProxy<'static>) -> String { + item_proxy.tooltip().await.unwrap_or_default() +} +async fn get_icon(item_proxy: StatusNotifierItemProxy<'static>) -> Option { if let Ok(icon_name) = item_proxy.icon_name().await { if icon_name != "" { return Some(IconNameOrPixmap::Name(icon_name)); } } + if let Ok(pixmaps) = item_proxy.icon_pixmap().await { + // TODO Handle icon with multiple sizes + return Some(IconNameOrPixmap::Pixmap( + pixmaps.into_iter().max_by_key(|i| (i.width, i.height))?, + )); + } + None } @@ -149,11 +166,23 @@ trait StatusNotifierItem { #[zbus(property)] fn icon_pixmap(&self) -> zbus::Result>; + #[zbus(property)] + fn title(&self) -> zbus::Result; + + #[zbus(property)] + fn tooltip(&self) -> zbus::Result; + #[zbus(property)] fn menu(&self) -> zbus::Result; + #[zbus(signal)] + fn new_title(&self) -> zbus::Result<()>; + #[zbus(signal)] fn new_icon(&self) -> zbus::Result<()>; + + #[zbus(signal)] + fn new_tooltip(&self) -> zbus::Result<()>; } #[derive(Clone, Debug)]