diff --git a/src/app.rs b/src/app.rs index 42a5ab7..4a6b448 100644 --- a/src/app.rs +++ b/src/app.rs @@ -296,11 +296,11 @@ impl App { fn initialize_window( monitor_geometry: gdk::Rectangle, root_widget: gtk::Widget, - mut window_def: config::EwwWindowDefinition, + window_def: config::EwwWindowDefinition, ) -> Result { let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry); - let window = display_backend::initialize_window(&mut window_def, monitor_geometry); + let window = display_backend::initialize_window(&window_def, monitor_geometry); window.set_title(&format!("Eww - {}", window_def.name)); let wm_class_name = format!("eww-{}", window_def.name); @@ -309,32 +309,48 @@ fn initialize_window( window.set_size_request(actual_window_rect.width, actual_window_rect.height); window.set_default_size(actual_window_rect.width, actual_window_rect.height); window.set_decorated(false); - // run on_screen_changed to set the visual correctly initially. on_screen_changed(&window, None); window.connect_screen_changed(on_screen_changed); window.add(&root_widget); - // Handle the fact that the gtk window will have a different size than specified, - // as it is sized according to how much space it's contents require. - // This is necessary to handle different anchors correctly in case the size was wrong. - let (gtk_window_width, gtk_window_height) = window.get_size(); - window_def.geometry.size = Coords { x: NumWithUnit::Pixels(gtk_window_width), y: NumWithUnit::Pixels(gtk_window_height) }; - let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry); - window.show_all(); + apply_window_position(window_def.clone(), monitor_geometry, &window)?; let gdk_window = window.get_window().context("couldn't get gdk window from gtk window")?; gdk_window.set_override_redirect(!window_def.focusable); - gdk_window.move_(actual_window_rect.x, actual_window_rect.y); #[cfg(feature = "x11")] display_backend::reserve_space_for(&window, monitor_geometry, window_def.struts)?; + // this should only be required on x11, as waylands layershell should manage the margins properly anways. + #[cfg(feature = "x11")] + window.connect_configure_event({ + let window_def = window_def.clone(); + move |window, _evt| { + let _ = apply_window_position(window_def.clone(), monitor_geometry, &window); + false + } + }); + Ok(EwwWindow { name: window_def.name.clone(), definition: window_def, gtk_window: window }) } +/// Apply the provided window-positioning rules to the window. +fn apply_window_position( + mut window_def: config::EwwWindowDefinition, + monitor_geometry: gdk::Rectangle, + window: >k::Window, +) -> Result<()> { + let (gtk_window_width, gtk_window_height) = window.get_size(); + window_def.geometry.size = Coords { x: NumWithUnit::Pixels(gtk_window_width), y: NumWithUnit::Pixels(gtk_window_height) }; + let gdk_window = window.get_window().context("Failed to get gdk window from gtk window")?; + let actual_window_rect = window_def.geometry.get_window_rectangle(monitor_geometry); + gdk_window.move_(actual_window_rect.x, actual_window_rect.y); + Ok(()) +} + fn on_screen_changed(window: >k::Window, _old_screen: Option<&gdk::Screen>) { let visual = window .get_screen() diff --git a/src/display_backend.rs b/src/display_backend.rs index ba1ee7b..d8d431d 100644 --- a/src/display_backend.rs +++ b/src/display_backend.rs @@ -6,7 +6,7 @@ mod platform { use anyhow::*; use gtk::{self, prelude::*}; - pub fn initialize_window(window_def: &mut EwwWindowDefinition, _monitor: gdk::Rectangle) -> gtk::Window { + pub fn initialize_window(window_def: &EwwWindowDefinition, _monitor: gdk::Rectangle) -> gtk::Window { let window = if window_def.focusable { gtk::Window::new(gtk::WindowType::Toplevel) } else { @@ -36,7 +36,7 @@ mod platform { use gdk; use gtk::prelude::*; - pub fn initialize_window(window_def: &mut EwwWindowDefinition, monitor: gdk::Rectangle) -> gtk::Window { + pub fn initialize_window(window_def: &EwwWindowDefinition, monitor: gdk::Rectangle) -> gtk::Window { let window = gtk::Window::new(gtk::WindowType::Toplevel); // Initialising a layer shell surface gtk_layer_shell::init_for_window(&window); @@ -119,7 +119,7 @@ mod platform { rust_connection::{DefaultStream, RustConnection}, }; - pub fn initialize_window(window_def: &mut EwwWindowDefinition, _monitor: gdk::Rectangle) -> gtk::Window { + pub fn initialize_window(window_def: &EwwWindowDefinition, _monitor: gdk::Rectangle) -> gtk::Window { let window = if window_def.focusable { gtk::Window::new(gtk::WindowType::Toplevel) } else {