From 9fb6f8ebcd2671956234303e926467b5ce5dc39b Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Wed, 10 Jul 2024 10:19:14 -0700 Subject: [PATCH] feat(stackbar): allow custom font family and size config This commit introduces two new static configuration options under stackbar.tabs, font_size and font_family. re #909 #885 --- Cargo.toml | 3 +- komorebi-core/src/lib.rs | 2 ++ komorebi/src/process_command.rs | 9 ++++++ komorebi/src/stackbar_manager/mod.rs | 2 ++ komorebi/src/stackbar_manager/stackbar.rs | 36 +++++++++++++++++++++-- komorebi/src/static_config.rs | 11 +++++++ 6 files changed, 60 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c27f689d..1ab78714 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,5 +41,6 @@ features = [ "Win32_UI_Shell", "Win32_UI_Shell_Common", "Win32_UI_WindowsAndMessaging", - "Win32_System_SystemServices" + "Win32_System_SystemServices", + "Win32_System_WindowsProgramming" ] diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index 2384851d..ab3535a9 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -153,6 +153,8 @@ pub enum SocketMessage { StackbarBackgroundColour(u32, u32, u32), StackbarHeight(i32), StackbarTabWidth(i32), + StackbarFontSize(i32), + StackbarFontFamily(Option), WorkAreaOffset(Rect), MonitorWorkAreaOffset(usize, Rect), ResizeDelta(i32), diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index f18012fc..4336369e 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -46,6 +46,8 @@ use crate::colour::Rgb; use crate::current_virtual_desktop; use crate::notify_subscribers; use crate::stackbar_manager; +use crate::stackbar_manager::STACKBAR_FONT_FAMILY; +use crate::stackbar_manager::STACKBAR_FONT_SIZE; use crate::static_config::StaticConfig; use crate::transparency_manager; use crate::window::RuleDebug; @@ -1350,6 +1352,13 @@ impl WindowManager { SocketMessage::StackbarTabWidth(width) => { STACKBAR_TAB_WIDTH.store(width, Ordering::SeqCst); } + SocketMessage::StackbarFontSize(size) => { + STACKBAR_FONT_SIZE.store(size, Ordering::SeqCst); + } + #[allow(clippy::assigning_clones)] + SocketMessage::StackbarFontFamily(ref font_family) => { + *STACKBAR_FONT_FAMILY.lock() = font_family.clone(); + } SocketMessage::ApplicationSpecificConfigurationSchema => { let asc = schema_for!(Vec); let schema = serde_json::to_string_pretty(&asc)?; diff --git a/komorebi/src/stackbar_manager/mod.rs b/komorebi/src/stackbar_manager/mod.rs index bce3d14c..b824ae1f 100644 --- a/komorebi/src/stackbar_manager/mod.rs +++ b/komorebi/src/stackbar_manager/mod.rs @@ -21,6 +21,7 @@ use std::sync::Arc; use std::sync::OnceLock; use windows::Win32::Foundation::HWND; +pub static STACKBAR_FONT_SIZE: AtomicI32 = AtomicI32::new(0); // 0 will produce the system default pub static STACKBAR_FOCUSED_TEXT_COLOUR: AtomicU32 = AtomicU32::new(16777215); // white pub static STACKBAR_UNFOCUSED_TEXT_COLOUR: AtomicU32 = AtomicU32::new(11776947); // gray text pub static STACKBAR_TAB_BACKGROUND_COLOUR: AtomicU32 = AtomicU32::new(3355443); // gray @@ -31,6 +32,7 @@ pub static STACKBAR_MODE: AtomicCell = AtomicCell::new(StackbarMod lazy_static! { pub static ref STACKBAR_STATE: Mutex> = Mutex::new(HashMap::new()); + pub static ref STACKBAR_FONT_FAMILY: Mutex> = Mutex::new(None); static ref STACKBARS_MONITORS: Mutex> = Mutex::new(HashMap::new()); static ref STACKBARS_CONTAINERS: Mutex> = Mutex::new(HashMap::new()); } diff --git a/komorebi/src/stackbar_manager/stackbar.rs b/komorebi/src/stackbar_manager/stackbar.rs index c8600d23..a688d3fb 100644 --- a/komorebi/src/stackbar_manager/stackbar.rs +++ b/komorebi/src/stackbar_manager/stackbar.rs @@ -4,6 +4,8 @@ use crate::border_manager::STYLE; use crate::container::Container; use crate::stackbar_manager::STACKBARS_CONTAINERS; use crate::stackbar_manager::STACKBAR_FOCUSED_TEXT_COLOUR; +use crate::stackbar_manager::STACKBAR_FONT_FAMILY; +use crate::stackbar_manager::STACKBAR_FONT_SIZE; use crate::stackbar_manager::STACKBAR_LABEL; use crate::stackbar_manager::STACKBAR_TAB_BACKGROUND_COLOUR; use crate::stackbar_manager::STACKBAR_TAB_HEIGHT; @@ -16,6 +18,8 @@ use crossbeam_utils::atomic::AtomicConsume; use komorebi_core::BorderStyle; use komorebi_core::Rect; use komorebi_core::StackbarLabel; +use std::os::windows::ffi::OsStrExt; +use std::sync::atomic::Ordering; use std::sync::mpsc; use std::time::Duration; use windows::core::PCWSTR; @@ -30,6 +34,7 @@ use windows::Win32::Graphics::Gdi::CreateSolidBrush; use windows::Win32::Graphics::Gdi::DeleteObject; use windows::Win32::Graphics::Gdi::DrawTextW; use windows::Win32::Graphics::Gdi::GetDC; +use windows::Win32::Graphics::Gdi::GetDeviceCaps; use windows::Win32::Graphics::Gdi::Rectangle; use windows::Win32::Graphics::Gdi::ReleaseDC; use windows::Win32::Graphics::Gdi::RoundRect; @@ -43,8 +48,10 @@ use windows::Win32::Graphics::Gdi::DT_VCENTER; use windows::Win32::Graphics::Gdi::FONT_QUALITY; use windows::Win32::Graphics::Gdi::FW_BOLD; use windows::Win32::Graphics::Gdi::LOGFONTW; +use windows::Win32::Graphics::Gdi::LOGPIXELSY; use windows::Win32::Graphics::Gdi::PROOF_QUALITY; use windows::Win32::Graphics::Gdi::PS_SOLID; +use windows::Win32::System::WindowsProgramming::MulDiv; use windows::Win32::UI::WindowsAndMessaging::CreateWindowExW; use windows::Win32::UI::WindowsAndMessaging::DefWindowProcW; use windows::Win32::UI::WindowsAndMessaging::DispatchMessageW; @@ -181,11 +188,29 @@ impl Stackbar { SelectObject(hdc, hbrush); SetBkColor(hdc, COLORREF(background)); - let hfont = CreateFontIndirectW(&LOGFONTW { + let mut logfont = LOGFONTW { lfWeight: FW_BOLD.0 as i32, lfQuality: FONT_QUALITY(PROOF_QUALITY.0), + lfFaceName: [0; 32], ..Default::default() - }); + }; + + if let Some(font_name) = &*STACKBAR_FONT_FAMILY.lock() { + let font = wide_string(font_name); + for (i, &c) in font.iter().enumerate() { + logfont.lfFaceName[i] = c; + } + } + + let logical_height = -MulDiv( + STACKBAR_FONT_SIZE.load(Ordering::SeqCst), + 72, + GetDeviceCaps(hdc, LOGPIXELSY), + ); + + logfont.lfHeight = logical_height; + + let hfont = CreateFontIndirectW(&logfont); SelectObject(hdc, hfont); @@ -336,3 +361,10 @@ impl Stackbar { } } } + +fn wide_string(s: &str) -> Vec { + std::ffi::OsStr::new(s) + .encode_wide() + .chain(std::iter::once(0)) + .collect() +} diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 6b51f43f..e7013ad1 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -9,6 +9,8 @@ use crate::monitor::Monitor; use crate::monitor_reconciliator; use crate::ring::Ring; use crate::stackbar_manager::STACKBAR_FOCUSED_TEXT_COLOUR; +use crate::stackbar_manager::STACKBAR_FONT_FAMILY; +use crate::stackbar_manager::STACKBAR_FONT_SIZE; use crate::stackbar_manager::STACKBAR_LABEL; use crate::stackbar_manager::STACKBAR_MODE; use crate::stackbar_manager::STACKBAR_TAB_BACKGROUND_COLOUR; @@ -410,7 +412,12 @@ pub struct TabsConfig { unfocused_text: Option, /// Tab background colour background: Option, + /// Font family + font_family: Option, + /// Font size + font_size: Option, } + #[derive(Debug, Serialize, Deserialize, JsonSchema)] pub struct StackbarConfig { /// Stackbar height @@ -674,6 +681,7 @@ impl StaticConfig { STACKBAR_MODE.store(*mode); } + #[allow(clippy::assigning_clones)] if let Some(tabs) = &stackbar.tabs { if let Some(background) = &tabs.background { STACKBAR_TAB_BACKGROUND_COLOUR.store((*background).into(), Ordering::SeqCst); @@ -690,6 +698,9 @@ impl StaticConfig { if let Some(width) = &tabs.width { STACKBAR_TAB_WIDTH.store(*width, Ordering::SeqCst); } + + STACKBAR_FONT_SIZE.store(tabs.font_size.unwrap_or(0), Ordering::SeqCst); + *STACKBAR_FONT_FAMILY.lock() = tabs.font_family.clone(); } }