status-area: Show icons that have icon_pixmap but not icon_name (#302)

This is at least one of the issue behind
https://github.com/pop-os/cosmic-applets/issues/165. OBS now shows it's
icon instead of an empty space. But the Mattermost flatpak doesn't show
anything. (Is that Flatpak related, or does it not use
`StatusNotifierItem`?)

Requires https://github.com/pop-os/libcosmic/pull/368. Ideally, it
should have some way to choose from multiple icons in memory of
different sizes.
This commit is contained in:
Ian Douglas Scott 2024-03-27 13:33:37 -07:00 committed by GitHub
parent 8128b6cf89
commit 180e75cb9a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 61 additions and 24 deletions

34
Cargo.lock generated
View file

@ -1146,7 +1146,7 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"atomicwrites",
"cosmic-config-derive",
@ -1166,7 +1166,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"quote",
"syn 1.0.109",
@ -1219,7 +1219,7 @@ dependencies = [
[[package]]
name = "cosmic-panel-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-panel#39f5f519338734daab5c09174b7fcacbc17d5843"
source = "git+https://github.com/pop-os/cosmic-panel#c2d4b3d9a12894f22e184de93bb0c634a844577c"
dependencies = [
"anyhow",
"cosmic-config",
@ -1277,7 +1277,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"almost",
"cosmic-config",
@ -2713,7 +2713,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"iced_accessibility",
"iced_core",
@ -2729,7 +2729,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"accesskit",
"accesskit_unix",
@ -2738,7 +2738,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"bitflags 1.3.2",
"iced_accessibility",
@ -2758,7 +2758,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"futures",
"iced_core",
@ -2771,7 +2771,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2795,7 +2795,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -2807,7 +2807,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"iced_accessibility",
"iced_core",
@ -2820,7 +2820,7 @@ dependencies = [
[[package]]
name = "iced_sctk"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"enum-repr",
"float-cmp",
@ -2846,7 +2846,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"iced_core",
"once_cell",
@ -2856,7 +2856,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"bytemuck",
"cosmic-text",
@ -2873,7 +2873,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2892,7 +2892,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"iced_renderer",
"iced_runtime",
@ -3168,7 +3168,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libcosmic"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#8afd6490da67704abf9480692abfe33b0780c9c9"
source = "git+https://github.com/pop-os/libcosmic#61a14a953dcb052efa6cdaf5b37c74e964896f5f"
dependencies = [
"apply",
"ashpd 0.7.0",

View file

@ -174,11 +174,14 @@ impl cosmic::Application for App {
fn view(&self) -> cosmic::Element<'_, Msg> {
// XXX connect open event
iced::widget::row(self.menus.iter().map(|(id, menu)| {
self.core
.applet
.icon_button(menu.icon_name())
.on_press(Msg::TogglePopup(*id))
.into()
match menu.icon_pixmap() {
Some(icon) if menu.icon_name() == "" => {
self.core.applet.icon_button_from_handle(icon.clone())
}
_ => self.core.applet.icon_button(menu.icon_name()),
}
.on_press(Msg::TogglePopup(*id))
.into()
}))
.into()
}

View file

@ -1,5 +1,5 @@
use cosmic::applet::menu_button;
use cosmic::iced;
use cosmic::{iced, widget::icon};
use crate::subscriptions::status_notifier_item::{Layout, StatusNotifierItem};
@ -65,6 +65,10 @@ impl State {
self.item.icon_name()
}
pub fn icon_pixmap(&self) -> Option<&icon::Handle> {
self.item.icon_pixmap()
}
pub fn popup_view(&self) -> cosmic::Element<Msg> {
if let Some(layout) = self.layout.as_ref() {
layout_view(layout, self.expanded)

View file

@ -1,4 +1,4 @@
use cosmic::iced;
use cosmic::{iced, widget::icon};
use futures::{FutureExt, StreamExt};
use zbus::zvariant::{self, OwnedValue};
@ -6,10 +6,19 @@ use zbus::zvariant::{self, OwnedValue};
pub struct StatusNotifierItem {
name: String,
icon_name: String,
// TODO Handle icon with multiple sizes?
icon_pixmap: Option<icon::Handle>,
_item_proxy: StatusNotifierItemProxy<'static>,
menu_proxy: DBusMenuProxy<'static>,
}
#[derive(Clone, Debug, zvariant::Value)]
pub struct Icon {
width: i32,
height: i32,
bytes: Vec<u8>,
}
impl StatusNotifierItem {
pub async fn new(connection: &zbus::Connection, name: String) -> zbus::Result<Self> {
let (dest, path) = if let Some(idx) = name.find('/') {
@ -25,6 +34,18 @@ impl StatusNotifierItem {
.await?;
let icon_name = item_proxy.icon_name().await?;
let icon_pixmap = item_proxy
.icon_pixmap()
.await?
.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)
});
let menu_path = item_proxy.menu().await?;
let menu_proxy = DBusMenuProxy::builder(connection)
@ -36,6 +57,7 @@ impl StatusNotifierItem {
Ok(Self {
name,
icon_name,
icon_pixmap,
_item_proxy: item_proxy,
menu_proxy,
})
@ -49,6 +71,10 @@ impl StatusNotifierItem {
&self.icon_name
}
pub fn icon_pixmap(&self) -> Option<&icon::Handle> {
self.icon_pixmap.as_ref()
}
// TODO: Only fetch changed part of layout, if that's any faster
pub fn layout_subscription(&self) -> iced::Subscription<Result<Layout, String>> {
let menu_proxy = self.menu_proxy.clone();
@ -81,6 +107,10 @@ trait StatusNotifierItem {
#[dbus_proxy(property)]
fn icon_name(&self) -> zbus::Result<String>;
// https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/Icons
#[dbus_proxy(property)]
fn icon_pixmap(&self) -> zbus::Result<Vec<Icon>>;
#[dbus_proxy(property)]
fn menu(&self) -> zbus::Result<zvariant::OwnedObjectPath>;
}