mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-25 10:08:33 +02:00
perf(bar): add icon cache
This commit adds an icon cache which is indexed by executable name to avoid unnecessary calls to windows_icons::get_icon_by_process_id, which is known to start failing after the komorebi-bar process has been running for a certain (unknown) period of time.
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::render::RenderConfig;
|
|||||||
use crate::selected_frame::SelectableFrame;
|
use crate::selected_frame::SelectableFrame;
|
||||||
use crate::ui::CustomUi;
|
use crate::ui::CustomUi;
|
||||||
use crate::widget::BarWidget;
|
use crate::widget::BarWidget;
|
||||||
|
use crate::ICON_CACHE;
|
||||||
use crate::MAX_LABEL_WIDTH;
|
use crate::MAX_LABEL_WIDTH;
|
||||||
use crate::MONITOR_INDEX;
|
use crate::MONITOR_INDEX;
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
@@ -611,17 +612,38 @@ impl From<&Workspace> for KomorebiNotificationStateContainerInformation {
|
|||||||
|
|
||||||
impl From<&Container> for KomorebiNotificationStateContainerInformation {
|
impl From<&Container> for KomorebiNotificationStateContainerInformation {
|
||||||
fn from(value: &Container) -> Self {
|
fn from(value: &Container) -> Self {
|
||||||
|
let windows = value.windows().iter().collect::<Vec<_>>();
|
||||||
|
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 {
|
Self {
|
||||||
titles: value
|
titles: value
|
||||||
.windows()
|
.windows()
|
||||||
.iter()
|
.iter()
|
||||||
.map(|w| w.title().unwrap_or_default())
|
.map(|w| w.title().unwrap_or_default())
|
||||||
.collect::<Vec<_>>(),
|
.collect::<Vec<_>>(),
|
||||||
icons: value
|
icons,
|
||||||
.windows()
|
|
||||||
.iter()
|
|
||||||
.map(|w| windows_icons::get_icon_by_process_id(w.process_id()))
|
|
||||||
.collect::<Vec<_>>(),
|
|
||||||
focused_window_idx: value.focused_window_idx(),
|
focused_window_idx: value.focused_window_idx(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -629,9 +651,30 @@ impl From<&Container> for KomorebiNotificationStateContainerInformation {
|
|||||||
|
|
||||||
impl From<&Window> for KomorebiNotificationStateContainerInformation {
|
impl From<&Window> for KomorebiNotificationStateContainerInformation {
|
||||||
fn from(value: &Window) -> Self {
|
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 {
|
Self {
|
||||||
titles: vec![value.title().unwrap_or_default()],
|
titles: vec![value.title().unwrap_or_default()],
|
||||||
icons: vec![windows_icons::get_icon_by_process_id(value.process_id())],
|
icons,
|
||||||
focused_window_idx: 0,
|
focused_window_idx: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ use eframe::egui::ViewportBuilder;
|
|||||||
use font_loader::system_fonts;
|
use font_loader::system_fonts;
|
||||||
use hotwatch::EventKind;
|
use hotwatch::EventKind;
|
||||||
use hotwatch::Hotwatch;
|
use hotwatch::Hotwatch;
|
||||||
|
use image::RgbaImage;
|
||||||
use komorebi_client::SocketMessage;
|
use komorebi_client::SocketMessage;
|
||||||
use komorebi_client::SubscribeOptions;
|
use komorebi_client::SubscribeOptions;
|
||||||
use schemars::gen::SchemaSettings;
|
use schemars::gen::SchemaSettings;
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -34,6 +36,8 @@ use std::sync::atomic::AtomicI32;
|
|||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::LazyLock;
|
||||||
|
use std::sync::Mutex;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
use windows::Win32::Foundation::BOOL;
|
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 MONITOR_INDEX: AtomicUsize = AtomicUsize::new(0);
|
||||||
pub static BAR_HEIGHT: f32 = 50.0;
|
pub static BAR_HEIGHT: f32 = 50.0;
|
||||||
|
|
||||||
|
pub static ICON_CACHE: LazyLock<Mutex<HashMap<String, RgbaImage>>> =
|
||||||
|
LazyLock::new(|| Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[clap(author, about, version)]
|
#[clap(author, about, version)]
|
||||||
struct Opts {
|
struct Opts {
|
||||||
|
|||||||
Reference in New Issue
Block a user