From d1212e265f93023f666164c7bf0b589819650396 Mon Sep 17 00:00:00 2001 From: Wilf Silver Date: Sun, 2 Jul 2023 15:37:10 +0100 Subject: [PATCH] Take gtk scaling into account when setting struts --- crates/eww/src/app.rs | 14 ++++++++------ crates/eww/src/display_backend.rs | 21 +++++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index 0a9808bc..e736613f 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -14,6 +14,7 @@ use crate::{ use anyhow::anyhow; use codespan_reporting::files::Files; use eww_shared_util::{Span, VarName}; +use gdk::Monitor; use glib::ObjectExt; use itertools::Itertools; use once_cell::sync::Lazy; @@ -398,8 +399,8 @@ impl App { root_widget.style_context().add_class(window_name); - let monitor_geometry = get_monitor_geometry(initiator.monitor.clone())?; - let mut eww_window = initialize_window::(&initiator, monitor_geometry, root_widget, window_scope)?; + let monitor = get_monitor(initiator.monitor.clone())?; + let mut eww_window = initialize_window::(&initiator, monitor, root_widget, window_scope)?; eww_window.gtk_window.style_context().add_class(window_name); // initialize script var handlers for variables. As starting a scriptvar with the script_var_handler is idempodent, @@ -492,10 +493,11 @@ impl App { fn initialize_window( window_init: &WindowInitiator, - monitor_geometry: gdk::Rectangle, + monitor: Monitor, root_widget: gtk::Widget, window_scope: ScopeIndex, ) -> Result { + let monitor_geometry = monitor.geometry(); let window = B::initialize_window(window_init, monitor_geometry) .with_context(|| format!("monitor {} is unavailable", window_init.monitor.clone().unwrap()))?; @@ -531,7 +533,7 @@ fn initialize_window( }); } } - display_backend::set_xprops(&window, monitor_geometry, window_init)?; + display_backend::set_xprops(&window, monitor, window_init)?; } window.show_all(); @@ -573,7 +575,7 @@ fn on_screen_changed(window: >k::Window, _old_screen: Option<&gdk::Screen>) { } /// Get the monitor geometry of a given monitor, or the default if none is given -fn get_monitor_geometry(identifier: Option) -> Result { +fn get_monitor(identifier: Option) -> Result { let display = gdk::Display::default().expect("could not get default display"); let monitor = match identifier { Some(ident) => { @@ -608,7 +610,7 @@ fn get_monitor_geometry(identifier: Option) -> Result Result<()> { + pub fn set_xprops(window: >k::Window, monitor: Monitor, window_init: &WindowInitiator) -> Result<()> { let backend = X11BackendConnection::new()?; backend.set_xprops_for(window, monitor, window_init)?; Ok(()) @@ -168,17 +169,21 @@ mod platform_x11 { fn set_xprops_for( &self, window: >k::Window, - monitor_rect: gdk::Rectangle, + monitor: Monitor, window_init: &WindowInitiator, ) -> Result<()> { + let monitor_rect = monitor.geometry(); + let scale_factor = monitor.scale_factor() as u32; let gdk_window = window.window().context("Couldn't get gdk window from gtk window")?; let win_id = gdk_window.downcast_ref::().context("Failed to get x11 window for gtk window")?.xid() as u32; let strut_def = window_init.backend_options.x11.struts; let root_window_geometry = self.conn.get_geometry(self.root_window)?.reply()?; - let mon_end_x = (monitor_rect.x() + monitor_rect.width()) as u32 - 1u32; - let mon_end_y = (monitor_rect.y() + monitor_rect.height()) as u32 - 1u32; + let mon_x = scale_factor * monitor_rect.x() as u32; + let mon_y = scale_factor * monitor_rect.y() as u32; + let mon_end_x = scale_factor * (monitor_rect.x() + monitor_rect.width()) as u32 - 1u32; + let mon_end_y = scale_factor * (monitor_rect.y() + monitor_rect.height()) as u32 - 1u32; let dist = match strut_def.side { Side::Left | Side::Right => strut_def.dist.pixels_relative_to(monitor_rect.width()) as u32, @@ -190,10 +195,10 @@ mod platform_x11 { // left, right, top, bottom, left_start_y, left_end_y, right_start_y, right_end_y, top_start_x, top_end_x, bottom_start_x, bottom_end_x #[rustfmt::skip] let strut_list: Vec = match strut_def.side { - Side::Left => vec![dist + monitor_rect.x() as u32, 0, 0, 0, monitor_rect.y() as u32, mon_end_y, 0, 0, 0, 0, 0, 0], - Side::Right => vec![0, root_window_geometry.width as u32 - mon_end_x + dist, 0, 0, 0, 0, monitor_rect.y() as u32, mon_end_y, 0, 0, 0, 0], - Side::Top => vec![0, 0, dist + monitor_rect.y() as u32, 0, 0, 0, 0, 0, monitor_rect.x() as u32, mon_end_x, 0, 0], - Side::Bottom => vec![0, 0, 0, root_window_geometry.height as u32 - mon_end_y + dist, 0, 0, 0, 0, 0, 0, monitor_rect.x() as u32, mon_end_x], + Side::Left => vec![dist + mon_x, 0, 0, 0, mon_x, mon_end_y, 0, 0, 0, 0, 0, 0], + Side::Right => vec![0, root_window_geometry.width as u32 - mon_end_x + dist, 0, 0, 0, 0, mon_x, mon_end_y, 0, 0, 0, 0], + Side::Top => vec![0, 0, dist + mon_y as u32, 0, 0, 0, 0, 0, mon_x, mon_end_x, 0, 0], + Side::Bottom => vec![0, 0, 0, root_window_geometry.height as u32 - mon_end_y + dist, 0, 0, 0, 0, 0, 0, mon_x as u32, mon_end_x], // This should never happen but if it does the window will be anchored on the // right of the screen }.iter().flat_map(|x| x.to_le_bytes().to_vec()).collect();