From 96f7eb1d31a5cfad6e4000baad48f4684c16a772 Mon Sep 17 00:00:00 2001 From: alex-ds13 <145657253+alex-ds13@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:39:50 +0000 Subject: [PATCH] fix(bar): apply position on start For some reason, when calling the `window.set_position` when creating the Komobar or even when applying the config on the first frame the actual EGUI's window size wasn't changing. This commit adds a new field to `Komobar` called `size_rect` so that we can store the expected size rect of the window according to the config, so that we don't have to be calculating it all the time. This field is updated on `apply_config`. Now on `update` of the bar we check if the current size using the EGUI Context is the expected `size_rect`, if it is we do nothing, if it is not we update the bar position. This makes sure that on start the bar will resize to the users config correctly! Now the resize of the bar only happens here. This commit also adds the `hwnd` field to `Komobar` so that we don't have to be calling `process_hwnd()` all the time. --- komorebi-bar/src/bar.rs | 114 +++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 43 deletions(-) diff --git a/komorebi-bar/src/bar.rs b/komorebi-bar/src/bar.rs index 0fba29fd..03c1662a 100644 --- a/komorebi-bar/src/bar.rs +++ b/komorebi-bar/src/bar.rs @@ -50,6 +50,7 @@ use std::sync::atomic::Ordering; use std::sync::Arc; pub struct Komobar { + pub hwnd: Option, pub config: Arc, pub render_config: Rc>, pub komorebi_notification_state: Option>>, @@ -61,6 +62,7 @@ pub struct Komobar { pub bg_color: Rc>, pub bg_color_with_alpha: Rc>, pub scale_factor: f32, + pub size_rect: komorebi_client::Rect, applied_theme_on_first_frame: bool, } @@ -194,49 +196,9 @@ impl Komobar { Self::add_custom_font(ctx, font_family); } - let position = config.position.clone().unwrap_or(PositionConfig { - start: Some(Position { - x: MONITOR_LEFT.load(Ordering::SeqCst) as f32, - y: MONITOR_TOP.load(Ordering::SeqCst) as f32, - }), - end: Some(Position { - x: MONITOR_RIGHT.load(Ordering::SeqCst) as f32, - y: BAR_HEIGHT, - }), - }); - - if let Some(hwnd) = process_hwnd() { - let start = position.start.unwrap_or(Position { - x: MONITOR_LEFT.load(Ordering::SeqCst) as f32, - y: MONITOR_TOP.load(Ordering::SeqCst) as f32, - }); - - let end = position.end.unwrap_or(Position { - x: MONITOR_RIGHT.load(Ordering::SeqCst) as f32, - y: BAR_HEIGHT, - }); - - if end.y == 0.0 { - tracing::warn!("position.end.y is set to 0.0 which will make your bar invisible on a config reload - this is usually set to 50.0 by default") - } - - let rect = komorebi_client::Rect { - left: start.x as i32, - top: start.y as i32, - right: end.x as i32, - bottom: end.y as i32, - }; - - let window = komorebi_client::Window::from(hwnd); - match window.set_position(&rect, false) { - Ok(_) => { - tracing::info!("updated bar position"); - } - Err(error) => { - tracing::error!("{}", error.to_string()) - } - } - } + // Update the `size_rect` so that the bar position can be changed on the EGUI update + // function + self.update_size_rect(config.position.clone()); self.try_apply_theme(config, ctx); @@ -361,6 +323,41 @@ impl Komobar { self.config = config.clone().into(); } + /// Updates the `size_rect` field. Returns a bool indicating if the field was changed or not + fn update_size_rect(&mut self, position: Option) { + let position = position.unwrap_or(PositionConfig { + start: Some(Position { + x: MONITOR_LEFT.load(Ordering::SeqCst) as f32, + y: MONITOR_TOP.load(Ordering::SeqCst) as f32, + }), + end: Some(Position { + x: MONITOR_RIGHT.load(Ordering::SeqCst) as f32, + y: BAR_HEIGHT, + }), + }); + + let start = position.start.unwrap_or(Position { + x: MONITOR_LEFT.load(Ordering::SeqCst) as f32, + y: MONITOR_TOP.load(Ordering::SeqCst) as f32, + }); + + let end = position.end.unwrap_or(Position { + x: MONITOR_RIGHT.load(Ordering::SeqCst) as f32, + y: BAR_HEIGHT, + }); + + if end.y == 0.0 { + tracing::warn!("position.end.y is set to 0.0 which will make your bar invisible on a config reload - this is usually set to 50.0 by default") + } + + self.size_rect = komorebi_client::Rect { + left: start.x as i32, + top: start.y as i32, + right: end.x as i32, + bottom: end.y as i32, + }; + } + fn try_apply_theme(&mut self, config: &KomobarConfig, ctx: &Context) { match config.theme { Some(theme) => { @@ -454,6 +451,7 @@ impl Komobar { config: Arc, ) -> Self { let mut komobar = Self { + hwnd: process_hwnd(), config: config.clone(), render_config: Rc::new(RefCell::new(RenderConfig::new())), komorebi_notification_state: None, @@ -465,6 +463,7 @@ impl Komobar { bg_color: Rc::new(RefCell::new(Style::default().visuals.panel_fill)), bg_color_with_alpha: Rc::new(RefCell::new(Style::default().visuals.panel_fill)), scale_factor: cc.egui_ctx.native_pixels_per_point().unwrap_or(1.0), + size_rect: komorebi_client::Rect::default(), applied_theme_on_first_frame: false, }; @@ -535,6 +534,10 @@ impl eframe::App for Komobar { } fn update(&mut self, ctx: &Context, _frame: &mut eframe::Frame) { + if self.hwnd.is_none() { + self.hwnd = process_hwnd(); + } + if self.scale_factor != ctx.native_pixels_per_point().unwrap_or(1.0) { self.scale_factor = ctx.native_pixels_per_point().unwrap_or(1.0); self.apply_config( @@ -573,6 +576,31 @@ impl eframe::App for Komobar { self.applied_theme_on_first_frame = true; } + // Check if egui's Window size is the expected one, if not, update it + if let Some(current_rect) = ctx.input(|i| i.viewport().outer_rect) { + // Get the correct size according to scale factor + let current_rect = komorebi_client::Rect { + left: (current_rect.min.x * self.scale_factor) as i32, + top: (current_rect.min.y * self.scale_factor) as i32, + right: ((current_rect.max.x - current_rect.min.x) * self.scale_factor) as i32, + bottom: ((current_rect.max.y - current_rect.min.y) * self.scale_factor) as i32, + }; + + if self.size_rect != current_rect { + if let Some(hwnd) = self.hwnd { + let window = komorebi_client::Window::from(hwnd); + match window.set_position(&self.size_rect, false) { + Ok(_) => { + tracing::info!("updated bar position"); + } + Err(error) => { + tracing::error!("{}", error.to_string()) + } + } + } + } + } + let frame = if let Some(frame) = &self.config.frame { Frame::none() .inner_margin(Margin::symmetric(