diff --git a/komorebi-bar/src/komorebi.rs b/komorebi-bar/src/komorebi.rs index ec2da578..99e82836 100644 --- a/komorebi-bar/src/komorebi.rs +++ b/komorebi-bar/src/komorebi.rs @@ -6,6 +6,7 @@ use crate::render::RenderConfig; use crate::selected_frame::SelectableFrame; use crate::ui::CustomUi; use crate::widget::BarWidget; +use crate::ICON_CACHE; use crate::MAX_LABEL_WIDTH; use crate::MONITOR_INDEX; use crossbeam_channel::Receiver; @@ -611,17 +612,38 @@ impl From<&Workspace> for KomorebiNotificationStateContainerInformation { impl From<&Container> for KomorebiNotificationStateContainerInformation { fn from(value: &Container) -> Self { + let windows = value.windows().iter().collect::>(); + let mut icons = vec![]; + + for window in windows { + let mut icon_cache = ICON_CACHE.lock().unwrap(); + let mut update_cache = false; + let exe = window.exe().unwrap_or_default(); + + match icon_cache.get(&exe) { + None => { + icons.push(windows_icons::get_icon_by_process_id(window.process_id())); + update_cache = true; + } + Some(icon) => { + icons.push(Some(icon.clone())); + } + } + + if update_cache { + if let Some(Some(icon)) = icons.last() { + icon_cache.insert(exe, icon.clone()); + } + } + } + Self { titles: value .windows() .iter() .map(|w| w.title().unwrap_or_default()) .collect::>(), - icons: value - .windows() - .iter() - .map(|w| windows_icons::get_icon_by_process_id(w.process_id())) - .collect::>(), + icons, focused_window_idx: value.focused_window_idx(), } } @@ -629,9 +651,30 @@ impl From<&Container> for KomorebiNotificationStateContainerInformation { impl From<&Window> for KomorebiNotificationStateContainerInformation { fn from(value: &Window) -> Self { + let mut icon_cache = ICON_CACHE.lock().unwrap(); + let mut update_cache = false; + let mut icons = vec![]; + let exe = value.exe().unwrap_or_default(); + + match icon_cache.get(&exe) { + None => { + icons.push(windows_icons::get_icon_by_process_id(value.process_id())); + update_cache = true; + } + Some(icon) => { + icons.push(Some(icon.clone())); + } + } + + if update_cache { + if let Some(Some(icon)) = icons.last() { + icon_cache.insert(exe, icon.clone()); + } + } + Self { titles: vec![value.title().unwrap_or_default()], - icons: vec![windows_icons::get_icon_by_process_id(value.process_id())], + icons, focused_window_idx: 0, } } diff --git a/komorebi-bar/src/main.rs b/komorebi-bar/src/main.rs index 5c4afd85..759d6e59 100644 --- a/komorebi-bar/src/main.rs +++ b/komorebi-bar/src/main.rs @@ -24,9 +24,11 @@ use eframe::egui::ViewportBuilder; use font_loader::system_fonts; use hotwatch::EventKind; use hotwatch::Hotwatch; +use image::RgbaImage; use komorebi_client::SocketMessage; use komorebi_client::SubscribeOptions; use schemars::gen::SchemaSettings; +use std::collections::HashMap; use std::io::BufReader; use std::io::Read; use std::path::PathBuf; @@ -34,6 +36,8 @@ use std::sync::atomic::AtomicI32; use std::sync::atomic::AtomicUsize; use std::sync::atomic::Ordering; use std::sync::Arc; +use std::sync::LazyLock; +use std::sync::Mutex; use std::time::Duration; use tracing_subscriber::EnvFilter; use windows::Win32::Foundation::BOOL; @@ -53,6 +57,9 @@ pub static MONITOR_RIGHT: AtomicI32 = AtomicI32::new(0); pub static MONITOR_INDEX: AtomicUsize = AtomicUsize::new(0); pub static BAR_HEIGHT: f32 = 50.0; +pub static ICON_CACHE: LazyLock>> = + LazyLock::new(|| Mutex::new(HashMap::new())); + #[derive(Parser)] #[clap(author, about, version)] struct Opts {