From 45d5bf5feb88d0854a41faa5890b56188b3e051c Mon Sep 17 00:00:00 2001 From: Jake Stanger Date: Fri, 9 Aug 2024 22:56:30 +0100 Subject: [PATCH] fix: popups not accounting for monitor scaling Fixes #657 --- src/bar.rs | 17 +++++++++++++---- src/main.rs | 5 +++++ src/popup.rs | 36 +++++++++++++++++------------------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/bar.rs b/src/bar.rs index 49147555..85f7ec03 100644 --- a/src/bar.rs +++ b/src/bar.rs @@ -22,6 +22,7 @@ enum Inner { pub struct Bar { name: String, monitor_name: String, + monitor_size: (i32, i32), position: BarPosition, ironbar: Rc, @@ -41,6 +42,7 @@ impl Bar { pub fn new( app: &Application, monitor_name: String, + monitor_size: (i32, i32), config: BarConfig, ironbar: Rc, ) -> Self { @@ -89,6 +91,7 @@ impl Bar { Self { name, monitor_name, + monitor_size, position, ironbar, window, @@ -146,7 +149,7 @@ impl Bar { } } - let load_result = self.load_modules(config, monitor)?; + let load_result = self.load_modules(config, monitor, self.monitor_size)?; self.show(!start_hidden); @@ -243,7 +246,12 @@ impl Bar { } /// Loads the configured modules onto a bar. - fn load_modules(&self, config: BarConfig, monitor: &Monitor) -> Result { + fn load_modules( + &self, + config: BarConfig, + monitor: &Monitor, + output_size: (i32, i32), + ) -> Result { let icon_theme = IconTheme::new(); if let Some(ref theme) = config.icon_theme { icon_theme.set_custom_theme(Some(theme)); @@ -265,7 +273,7 @@ impl Bar { } // popup ignores module location so can bodge this for now - let popup = Popup::new(&info!(ModuleLocation::Left), config.popup_gap); + let popup = Popup::new(&info!(ModuleLocation::Left), output_size, config.popup_gap); let popup = Rc::new(popup); if let Some(modules) = config.start { @@ -384,9 +392,10 @@ pub fn create_bar( app: &Application, monitor: &Monitor, monitor_name: String, + monitor_size: (i32, i32), config: BarConfig, ironbar: Rc, ) -> Result { - let bar = Bar::new(app, monitor_name, config, ironbar); + let bar = Bar::new(app, monitor_name, monitor_size, config, ironbar); bar.init(monitor) } diff --git a/src/main.rs b/src/main.rs index 4657574d..5deae779 100644 --- a/src/main.rs +++ b/src/main.rs @@ -363,6 +363,8 @@ fn load_output_bars( // We also need this static to ensure hot-reloading continues to work as best we can. static INDEX_MAP: OnceLock>> = OnceLock::new(); + let output_size = output.logical_size.unwrap_or_default(); + let Some(monitor_name) = &output.name else { return Err(Report::msg("Output missing monitor name")); }; @@ -401,6 +403,7 @@ fn load_output_bars( app, &monitor, monitor_name.to_string(), + output_size, config.clone(), ironbar.clone(), )?] @@ -412,6 +415,7 @@ fn load_output_bars( app, &monitor, monitor_name.to_string(), + output_size, config.clone(), ironbar.clone(), ) @@ -421,6 +425,7 @@ fn load_output_bars( app, &monitor, monitor_name.to_string(), + output_size, config.bar.clone(), ironbar.clone(), )?], diff --git a/src/popup.rs b/src/popup.rs index 5946e994..f04ef7b5 100644 --- a/src/popup.rs +++ b/src/popup.rs @@ -3,16 +3,14 @@ use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; -use gtk::gdk::Monitor; -use gtk::prelude::*; -use gtk::{ApplicationWindow, Button, Orientation}; -use gtk_layer_shell::LayerShell; -use tracing::{debug, trace}; - use crate::config::BarPosition; use crate::gtk_helpers::{IronbarGtkExt, WidgetGeometry}; use crate::modules::{ModuleInfo, ModulePopupParts, PopupButton}; use crate::rc_mut; +use gtk::prelude::*; +use gtk::{ApplicationWindow, Button, Orientation}; +use gtk_layer_shell::LayerShell; +use tracing::{debug, trace}; #[derive(Debug, Clone)] pub struct PopupCacheValue { @@ -25,16 +23,16 @@ pub struct Popup { pub window: ApplicationWindow, pub container_cache: Rc>>, pub button_cache: Rc>>, - monitor: Monitor, pos: BarPosition, current_widget: Rc>>, + output_size: (i32, i32), } impl Popup { /// Creates a new popup window. /// This includes setting up gtk-layer-shell /// and an empty `gtk::Box` container. - pub fn new(module_info: &ModuleInfo, gap: i32) -> Self { + pub fn new(module_info: &ModuleInfo, output_size: (i32, i32), gap: i32) -> Self { let pos = module_info.bar_position; let orientation = pos.orientation(); @@ -109,9 +107,9 @@ impl Popup { window: win, container_cache: rc_mut!(HashMap::new()), button_cache: rc_mut!(vec![]), - monitor: module_info.monitor.clone(), pos, current_widget: rc_mut!(None), + output_size, } } @@ -123,13 +121,14 @@ impl Popup { } let orientation = self.pos.orientation(); - let monitor = self.monitor.clone(); let window = self.window.clone(); let current_widget = self.current_widget.clone(); let cache = self.container_cache.clone(); let button_cache = self.button_cache.clone(); + let output_size = self.output_size; + content .container .connect_size_allocate(move |container, rect| { @@ -142,8 +141,8 @@ impl Popup { &button_cache.borrow(), button_id, orientation, - &monitor, &window, + output_size, ); } } @@ -175,8 +174,8 @@ impl Popup { &self.button_cache.borrow(), button_id, self.pos.orientation(), - &self.monitor, &self.window, + self.output_size, ); } } @@ -193,8 +192,8 @@ impl Popup { Self::set_pos( geometry, self.pos.orientation(), - &self.monitor, &self.window, + self.output_size, ); } } @@ -203,8 +202,8 @@ impl Popup { buttons: &[Button], button_id: usize, orientation: Orientation, - monitor: &Monitor, window: &ApplicationWindow, + output_size: (i32, i32), ) { let button = buttons .iter() @@ -212,7 +211,7 @@ impl Popup { .expect("to find valid button"); let geometry = button.geometry(orientation); - Self::set_pos(geometry, orientation, monitor, window); + Self::set_pos(geometry, orientation, window, output_size); } fn clear_window(&self) { @@ -242,14 +241,13 @@ impl Popup { fn set_pos( geometry: WidgetGeometry, orientation: Orientation, - monitor: &Monitor, window: &ApplicationWindow, + output_size: (i32, i32), ) { - let mon_workarea = monitor.workarea(); let screen_size = if orientation == Orientation::Horizontal { - mon_workarea.width() + output_size.0 } else { - mon_workarea.height() + output_size.1 }; let (popup_width, popup_height) = window.size();