feat(bar): add app icon next to focused window title

This commit is contained in:
LGUG2Z
2024-09-07 15:00:29 -07:00
parent 025162769b
commit a1688691cf
4 changed files with 663 additions and 27 deletions

651
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -10,11 +10,13 @@ komorebi-client = { path = "../komorebi-client" }
anyhow = "1" anyhow = "1"
chrono = "0.4" chrono = "0.4"
crossbeam-channel = "0.5"
eframe = "0.28" eframe = "0.28"
font-loader = "0.11"
image = "0.25"
netdev = "0.30" netdev = "0.30"
serde_json = "1" serde_json = "1"
starship-battery = "0.9" starship-battery = "0.10"
sysinfo = "0.31" sysinfo = "0.31"
crossbeam-channel = "0.5"
windows = { workspace = true } windows = { workspace = true }
font-loader = "0.11" windows-icons = "0.1"

View File

@@ -26,15 +26,19 @@ use crate::widget::BarWidget;
use crossbeam_channel::Receiver; use crossbeam_channel::Receiver;
use eframe::egui; use eframe::egui;
use eframe::egui::Align; use eframe::egui::Align;
use eframe::egui::ColorImage;
use eframe::egui::Context;
use eframe::egui::Label; use eframe::egui::Label;
use eframe::egui::Layout; use eframe::egui::Layout;
use eframe::egui::Sense; use eframe::egui::Sense;
use eframe::egui::TextureHandle;
use eframe::egui::ViewportBuilder; use eframe::egui::ViewportBuilder;
use eframe::egui::Visuals; use eframe::egui::Visuals;
use eframe::emath::Pos2; use eframe::emath::Pos2;
use eframe::emath::Vec2; use eframe::emath::Vec2;
use font_loader::system_fonts; use font_loader::system_fonts;
use font_loader::system_fonts::FontPropertyBuilder; use font_loader::system_fonts::FontPropertyBuilder;
use image::RgbaImage;
use komorebi_client::CycleDirection; use komorebi_client::CycleDirection;
use komorebi_client::SocketMessage; use komorebi_client::SocketMessage;
use std::io::BufReader; use std::io::BufReader;
@@ -217,6 +221,8 @@ struct Komobar {
state_receiver: Receiver<komorebi_client::Notification>, state_receiver: Receiver<komorebi_client::Notification>,
selected_workspace: String, selected_workspace: String,
focused_window_title: String, focused_window_title: String,
focused_window_pid: Option<u32>,
focused_window_icon: Option<RgbaImage>,
layout: String, layout: String,
workspaces: Vec<String>, workspaces: Vec<String>,
right_widgets: Vec<Box<dyn BarWidget>>, right_widgets: Vec<Box<dyn BarWidget>>,
@@ -284,12 +290,20 @@ impl Komobar {
state_receiver: rx, state_receiver: rx,
selected_workspace: String::new(), selected_workspace: String::new(),
focused_window_title: String::new(), focused_window_title: String::new(),
focused_window_pid: None,
focused_window_icon: None,
layout: String::new(), layout: String::new(),
workspaces: vec![], workspaces: vec![],
right_widgets, right_widgets,
} }
} }
} }
fn img_to_texture(ctx: &Context, rgba_image: &RgbaImage) -> TextureHandle {
let size = [rgba_image.width() as usize, rgba_image.height() as usize];
let pixels = rgba_image.as_flat_samples();
let color_image = ColorImage::from_rgba_unmultiplied(size, pixels.as_slice());
ctx.load_texture("icon", color_image, egui::TextureOptions::default())
}
impl Komobar { impl Komobar {
fn handle_komorebi_notification(&mut self) { fn handle_komorebi_notification(&mut self) {
@@ -318,10 +332,14 @@ impl Komobar {
if let Some(window) = container.focused_window() { if let Some(window) = container.focused_window() {
if let Ok(title) = window.title() { if let Ok(title) = window.title() {
self.focused_window_title.clone_from(&title); self.focused_window_title.clone_from(&title);
self.focused_window_pid = Some(window.process_id());
let img = windows_icons::get_icon_by_process_id(window.process_id());
self.focused_window_icon = Some(img);
} }
} }
} else { } else {
self.focused_window_title.clear(); self.focused_window_title.clear();
self.focused_window_icon = None;
} }
if let Some(container) = monitor.workspaces()[focused_workspace_idx].monocle_container() if let Some(container) = monitor.workspaces()[focused_workspace_idx].monocle_container()
@@ -408,6 +426,14 @@ impl eframe::App for Komobar {
ui.add_space(10.0); ui.add_space(10.0);
if let Some(img) = &self.focused_window_icon {
ui.add(
egui::Image::from(&img_to_texture(ctx, img))
.maintain_aspect_ratio(true)
.max_height(15.0),
);
}
ui.add(Label::new(&self.focused_window_title).selectable(false)); ui.add(Label::new(&self.focused_window_title).selectable(false));
ui.add_space(10.0); ui.add_space(10.0);

View File

@@ -393,6 +393,11 @@ impl Window {
exe exe
} }
pub fn process_id(self) -> u32 {
let (process_id, _) = WindowsApi::window_thread_process_id(self.hwnd());
process_id
}
pub fn class(self) -> Result<String> { pub fn class(self) -> Result<String> {
WindowsApi::real_window_class_w(self.hwnd()) WindowsApi::real_window_class_w(self.hwnd())
} }