1
0
Fork 0
mirror of https://github.com/Zedfrigg/ironbar.git synced 2025-07-01 02:31:04 +02:00

fix(tray): existing icons rendering as text

This commit is contained in:
Chris Maniewski 2023-11-15 01:14:32 +01:00
parent 4fe20865bf
commit 5f82b6e9e0
No known key found for this signature in database
GPG key ID: 5853B5E298E10A05

View file

@ -3,6 +3,9 @@ use crate::config::CommonConfig;
use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext}; use crate::modules::{Module, ModuleInfo, ModuleParts, ModuleUpdateEvent, WidgetContext};
use crate::{await_sync, try_send}; use crate::{await_sync, try_send};
use color_eyre::Result; use color_eyre::Result;
use glib::ffi::g_strfreev;
use glib::translate::ToGlibPtr;
use gtk::ffi::gtk_icon_theme_get_search_path;
use gtk::gdk_pixbuf::{Colorspace, InterpType}; use gtk::gdk_pixbuf::{Colorspace, InterpType};
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{ use gtk::{
@ -10,7 +13,10 @@ use gtk::{
SeparatorMenuItem, SeparatorMenuItem,
}; };
use serde::Deserialize; use serde::Deserialize;
use std::collections::HashMap; use std::collections::{HashMap, HashSet};
use std::ffi::CStr;
use std::os::raw::{c_char, c_int};
use std::ptr;
use system_tray::message::menu::{MenuItem as MenuItemInfo, MenuType}; use system_tray::message::menu::{MenuItem as MenuItemInfo, MenuType};
use system_tray::message::tray::StatusNotifierItem; use system_tray::message::tray::StatusNotifierItem;
use system_tray::message::{NotifierItemCommand, NotifierItemMessage}; use system_tray::message::{NotifierItemCommand, NotifierItemMessage};
@ -24,21 +30,43 @@ pub struct TrayModule {
pub common: Option<CommonConfig>, pub common: Option<CommonConfig>,
} }
/// Gets the GTK icon theme search paths by calling the FFI function.
/// Conveniently returns the result as a `HashSet`.
fn get_icon_theme_search_paths(icon_theme: &IconTheme) -> HashSet<String> {
let mut gtk_paths: *mut *mut c_char = ptr::null_mut();
let mut n_elements: c_int = 0;
let mut paths = HashSet::new();
unsafe {
gtk_icon_theme_get_search_path(
icon_theme.to_glib_none().0,
&mut gtk_paths,
&mut n_elements,
);
// n_elements is never negative (that would be weird)
for i in 0..n_elements as usize {
let c_str = CStr::from_ptr(*gtk_paths.add(i));
if let Ok(str) = c_str.to_str() {
paths.insert(str.to_owned());
}
}
g_strfreev(gtk_paths);
}
paths
}
/// Attempts to get a GTK `Image` component /// Attempts to get a GTK `Image` component
/// for the status notifier item's icon. /// for the status notifier item's icon.
fn get_image_from_icon_name(item: &StatusNotifierItem) -> Option<Image> { fn get_image_from_icon_name(item: &StatusNotifierItem, icon_theme: IconTheme) -> Option<Image> {
let theme = item if let Some(path) = item.icon_theme_path.as_ref() {
.icon_theme_path if !path.is_empty() && !get_icon_theme_search_paths(&icon_theme).contains(path) {
.as_ref() icon_theme.append_search_path(path);
.map(|path| { }
let theme = IconTheme::new(); }
theme.append_search_path(path);
theme
})
.unwrap_or_default();
item.icon_name.as_ref().and_then(|icon_name| { item.icon_name.as_ref().and_then(|icon_name| {
let icon_info = theme.lookup_icon(icon_name, 16, IconLookupFlags::empty()); let icon_info = icon_theme.lookup_icon(icon_name, 16, IconLookupFlags::empty());
icon_info.map(|icon_info| Image::from_pixbuf(icon_info.load_icon().ok().as_ref())) icon_info.map(|icon_info| Image::from_pixbuf(icon_info.load_icon().ok().as_ref()))
}) })
} }
@ -171,13 +199,14 @@ impl Module<MenuBar> for TrayModule {
fn into_widget( fn into_widget(
self, self,
context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>, context: WidgetContext<Self::SendMessage, Self::ReceiveMessage>,
_info: &ModuleInfo, info: &ModuleInfo,
) -> Result<ModuleParts<MenuBar>> { ) -> Result<ModuleParts<MenuBar>> {
let container = MenuBar::new(); let container = MenuBar::new();
{ {
let container = container.clone(); let container = container.clone();
let mut widgets = HashMap::new(); let mut widgets = HashMap::new();
let icon_theme = info.icon_theme.clone();
// listen for UI updates // listen for UI updates
context.widget_rx.attach(None, move |update| { context.widget_rx.attach(None, move |update| {
@ -192,7 +221,7 @@ impl Module<MenuBar> for TrayModule {
let menu_item = MenuItem::new(); let menu_item = MenuItem::new();
menu_item.style_context().add_class("item"); menu_item.style_context().add_class("item");
get_image_from_icon_name(&item) get_image_from_icon_name(&item, icon_theme.clone())
.or_else(|| get_image_from_pixmap(&item)) .or_else(|| get_image_from_pixmap(&item))
.map_or_else( .map_or_else(
|| { || {