From 3a486f181e35a1f48edc0cf91ef4eebaaefbc7bd Mon Sep 17 00:00:00 2001 From: Florian Proksch Date: Sat, 11 Sep 2021 17:34:53 +0200 Subject: [PATCH] I3 dock fix (#258) * fix: problem with docked widgets on i3 Show window only after settings x-props. According to the EWMH spec: > _NET_WM_WINDOW_TYPE > This SHOULD be set by the Client before mapping to a list of atoms > indicating the functional type of the window. So the _NET_WM_WINDOW_TYPE atom must be set before showing the window. The callback to the configure event handle now checks the windows current geometry to not move the window if it's already where it's supposed to be. This prevents the eww daemon from endlessly chatting with X11 in some instances. * chore: cargo fmt --- crates/eww/src/app.rs | 13 ++++++++++-- crates/eww/src/opts.rs | 2 +- crates/eww/src/widgets/widget_definitions.rs | 21 +++++++++++++++----- crates/eww/src/widgets/widget_node.rs | 2 +- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index aea4157..f55f56b 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -344,7 +344,7 @@ fn initialize_window( window.add(&root_widget); - window.show_all(); + window.realize(); #[cfg(feature = "x11")] { @@ -357,6 +357,9 @@ fn initialize_window( } display_backend::set_xprops(&window, monitor_geometry, &window_def)?; } + + window.show_all(); + Ok(EwwWindow { name: window_def.name.clone(), definition: window_def, gtk_window: window }) } @@ -370,7 +373,13 @@ fn apply_window_position( let gdk_window = window.get_window().context("Failed to get gdk window from gtk window")?; window_geometry.size = Coords::from_pixels(window.get_size()); let actual_window_rect = get_window_rectangle(window_geometry, monitor_geometry); - gdk_window.move_(actual_window_rect.x, actual_window_rect.y); + + let gdk_origin = gdk_window.get_origin(); + + if actual_window_rect.x != gdk_origin.1 || actual_window_rect.y != gdk_origin.2 { + gdk_window.move_(actual_window_rect.x, actual_window_rect.y); + } + Ok(()) } diff --git a/crates/eww/src/opts.rs b/crates/eww/src/opts.rs index c9bdbea..cc22f56 100644 --- a/crates/eww/src/opts.rs +++ b/crates/eww/src/opts.rs @@ -173,7 +173,7 @@ fn parse_var_update_arg(s: &str) -> Result<(VarName, DynVal)> { impl ActionWithServer { pub fn can_start_daemon(&self) -> bool { - matches!(self, ActionWithServer::OpenWindow {..} | ActionWithServer::OpenMany { .. }) + matches!(self, ActionWithServer::OpenWindow { .. } | ActionWithServer::OpenMany { .. }) } pub fn into_daemon_command(self) -> (app::DaemonCommand, Option) { diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index a12349c..c46a0fe 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -8,7 +8,7 @@ use gdk::WindowExt; use glib; use gtk::{self, prelude::*, ImageExt}; use itertools::Itertools; -use std::{cell::RefCell, collections::HashMap, rc::Rc, time::Duration, cmp::Ordering}; +use std::{cell::RefCell, cmp::Ordering, collections::HashMap, rc::Rc, time::Duration}; use yuck::{ config::validate::ValidationError, error::{AstError, AstResult, AstResultExt}, @@ -41,7 +41,11 @@ pub(super) fn widget_to_gtk_widget(bargs: &mut BuilderArgs) -> Result build_gtk_revealer(bargs)?.upcast(), "if-else" => build_if_else(bargs)?.upcast(), _ => { - return Err(AstError::ValidationError(ValidationError::UnknownWidget(bargs.widget.name_span, bargs.widget.name.to_string())).into()) + return Err(AstError::ValidationError(ValidationError::UnknownWidget( + bargs.widget.name_span, + bargs.widget.name.to_string(), + )) + .into()) } }; Ok(gtk_widget) @@ -517,11 +521,18 @@ fn build_center_box(bargs: &mut BuilderArgs) -> Result { // we know that there is more than three children, so unwrapping on first and left here is fine. let first_span = additional_children.first().unwrap().span(); let last_span = additional_children.last().unwrap().span(); - Err(DiagError::new(gen_diagnostic!("centerbox must contain exactly 3 elements, but got more", first_span.to(last_span))).into()) + Err(DiagError::new(gen_diagnostic!( + "centerbox must contain exactly 3 elements, but got more", + first_span.to(last_span) + )) + .into()) } Ordering::Equal => { - let mut children = - bargs.widget.children.iter().map(|child| child.render(bargs.eww_state, bargs.window_name, bargs.widget_definitions)); + let mut children = bargs + .widget + .children + .iter() + .map(|child| child.render(bargs.eww_state, bargs.window_name, bargs.widget_definitions)); // we know that we have exactly three children here, so we can unwrap here. let (first, center, end) = children.next_tuple().unwrap(); let (first, center, end) = (first?, center?, end?); diff --git a/crates/eww/src/widgets/widget_node.rs b/crates/eww/src/widgets/widget_node.rs index aa0c4b5..db6bdf5 100644 --- a/crates/eww/src/widgets/widget_node.rs +++ b/crates/eww/src/widgets/widget_node.rs @@ -113,7 +113,7 @@ pub fn generate_generic_widget_node( ) -> AstResult> { if let Some(def) = defs.get(&w.name) { if !w.children.is_empty() { - return Err(AstError::TooManyNodes(w.children_span(), 0).note("User-defined widgets cannot be given children.")) + return Err(AstError::TooManyNodes(w.children_span(), 0).note("User-defined widgets cannot be given children.")); } let mut new_local_env = w