status-area: Handle changes to icon properties
It seems status icons, at least some, don't send property change notifications. So we can't rely on that, and have to disable caching. And handle the `NewIcon` signal defined in https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem I'm not sure whether or not there's a *good* reason it works this way, but regardless I see `nm-applet` and `ibus` update their icons as they should after these changes.
This commit is contained in:
parent
7fdaf839e0
commit
2a939e5a11
2 changed files with 83 additions and 38 deletions
|
|
@ -7,11 +7,12 @@ use cosmic::{
|
|||
widget::icon,
|
||||
};
|
||||
|
||||
use crate::subscriptions::status_notifier_item::{Layout, StatusNotifierItem};
|
||||
use crate::subscriptions::status_notifier_item::{IconUpdate, Layout, StatusNotifierItem};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Msg {
|
||||
Layout(Result<Layout, String>),
|
||||
Icon(IconUpdate),
|
||||
Click(i32, bool),
|
||||
}
|
||||
|
||||
|
|
@ -19,6 +20,9 @@ pub struct State {
|
|||
item: StatusNotifierItem,
|
||||
layout: Option<Layout>,
|
||||
expanded: Option<i32>,
|
||||
icon_name: String,
|
||||
// TODO handle icon with multiple sizes?
|
||||
icon_pixmap: Option<icon::Handle>,
|
||||
}
|
||||
|
||||
impl State {
|
||||
|
|
@ -28,6 +32,8 @@ impl State {
|
|||
item,
|
||||
layout: None,
|
||||
expanded: None,
|
||||
icon_name: String::new(),
|
||||
icon_pixmap: None,
|
||||
},
|
||||
iced::Task::none(),
|
||||
)
|
||||
|
|
@ -44,6 +50,27 @@ impl State {
|
|||
}
|
||||
iced::Task::none()
|
||||
}
|
||||
Msg::Icon(update) => {
|
||||
match update {
|
||||
IconUpdate::Name(name) => {
|
||||
self.icon_name = name;
|
||||
}
|
||||
IconUpdate::Pixmap(icons) => {
|
||||
self.icon_pixmap = icons
|
||||
.into_iter()
|
||||
.max_by_key(|i| (i.width, i.height))
|
||||
.map(|mut i| {
|
||||
// Convert ARGB to RGBA
|
||||
for pixel in i.bytes.chunks_exact_mut(4) {
|
||||
pixel.rotate_left(1);
|
||||
}
|
||||
icon::from_raster_pixels(i.width as u32, i.height as u32, i.bytes)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
iced::Task::none()
|
||||
}
|
||||
Msg::Click(id, is_submenu) => {
|
||||
let menu_proxy = self.item.menu_proxy().clone();
|
||||
tokio::spawn(async move {
|
||||
|
|
@ -68,11 +95,11 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn icon_name(&self) -> &str {
|
||||
self.item.icon_name()
|
||||
&self.icon_name
|
||||
}
|
||||
|
||||
pub fn icon_pixmap(&self) -> Option<&icon::Handle> {
|
||||
self.item.icon_pixmap()
|
||||
self.icon_pixmap.as_ref()
|
||||
}
|
||||
|
||||
pub fn popup_view(&self) -> cosmic::Element<Msg> {
|
||||
|
|
@ -84,7 +111,10 @@ impl State {
|
|||
}
|
||||
|
||||
pub fn subscription(&self) -> iced::Subscription<Msg> {
|
||||
self.item.layout_subscription().map(Msg::Layout)
|
||||
iced::Subscription::batch([
|
||||
self.item.layout_subscription().map(Msg::Layout),
|
||||
self.item.icon_subscription().map(Msg::Icon),
|
||||
])
|
||||
}
|
||||
|
||||
pub fn opened(&self) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue