status-area: Use struct instead of enum for IconUpdate

This commit is contained in:
Ian Douglas Scott 2025-11-04 10:25:57 -08:00 committed by Jacob Kauffmann
parent e2dcfeac7c
commit e7e275abf7
2 changed files with 27 additions and 42 deletions

View file

@ -61,29 +61,23 @@ impl State {
iced::Task::none() iced::Task::none()
} }
Msg::Icon(update) => { Msg::Icon(update) => {
match update { self.icon_name = update.name.unwrap_or_default();
IconUpdate::Name(name) => { self.icon_pixmap = update.pixmap.and_then(|icons| icons
self.icon_name = name; .into_iter()
} .max_by_key(|i| (i.width, i.height))
IconUpdate::Pixmap(icons) => { .map(|mut i| {
self.icon_pixmap = icons if i.width <= 0 || i.height <= 0 || i.bytes.is_empty() {
.into_iter() // App sent invalid icon data during initialization - show placeholder until NewIcon signal
.max_by_key(|i| (i.width, i.height)) eprintln!("Skipping invalid icon: {}x{} with {} bytes, app may still be initializing",
.map(|mut i| { i.width, i.height, i.bytes.len());
if i.width <= 0 || i.height <= 0 || i.bytes.is_empty() { return icon::from_name("dialog-question").symbolic(true).handle();
// App sent invalid icon data during initialization - show placeholder until NewIcon signal }
eprintln!("Skipping invalid icon: {}x{} with {} bytes, app may still be initializing", // Convert ARGB to RGBA
i.width, i.height, i.bytes.len()); for pixel in i.bytes.chunks_exact_mut(4) {
return icon::from_name("dialog-question").symbolic(true).handle(); pixel.rotate_left(1);
} }
// Convert ARGB to RGBA icon::from_raster_pixels(i.width as u32, i.height as u32, i.bytes)
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() iced::Task::none()
} }

View file

@ -21,9 +21,9 @@ pub struct Icon {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum IconUpdate { pub struct IconUpdate {
Name(String), pub name: Option<String>,
Pixmap(Vec<Icon>), pub pixmap: Option<Vec<Icon>>,
} }
impl StatusNotifierItem { impl StatusNotifierItem {
@ -93,22 +93,13 @@ impl StatusNotifierItem {
} }
pub fn icon_subscription(&self) -> iced::Subscription<IconUpdate> { pub fn icon_subscription(&self) -> iced::Subscription<IconUpdate> {
fn icon_events( async fn icon_events(item_proxy: StatusNotifierItemProxy<'static>) -> IconUpdate {
item_proxy: StatusNotifierItemProxy<'static>, let icon_name = item_proxy.icon_name().await;
) -> impl futures::Stream<Item = IconUpdate> + 'static { let icon_pixmap = item_proxy.icon_pixmap().await;
async move { IconUpdate {
let icon_name = item_proxy.icon_name().await; name: icon_name.ok(),
let icon_pixmap = item_proxy.icon_pixmap().await; pixmap: icon_pixmap.ok(),
futures::stream::iter(
[
icon_name.map(IconUpdate::Name),
icon_pixmap.map(IconUpdate::Pixmap),
]
.into_iter()
.filter_map(Result::ok),
)
} }
.flatten_stream()
} }
let item_proxy = self.item_proxy.clone(); let item_proxy = self.item_proxy.clone();
@ -118,7 +109,7 @@ impl StatusNotifierItem {
let new_icon_stream = item_proxy.receive_new_icon().await.unwrap(); let new_icon_stream = item_proxy.receive_new_icon().await.unwrap();
futures::stream::once(async {}) futures::stream::once(async {})
.chain(new_icon_stream.map(|_| ())) .chain(new_icon_stream.map(|_| ()))
.flat_map(move |()| icon_events(item_proxy.clone())) .then(move |()| icon_events(item_proxy.clone()))
} }
.flatten_stream(), .flatten_stream(),
) )