diff --git a/src/layout.rs b/src/layout.rs index 2bbfb128..665f1e93 100644 --- a/src/layout.rs +++ b/src/layout.rs @@ -158,6 +158,11 @@ pub struct GroupNode { #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub struct WindowNode { window: Window, + /// Whether the `window` was changed in the latest [`add_window`] or [`remove_window`] call. + /// + /// [`add_window`]: TilingLayoutManager::add_window + /// [`remove_window`]: TilingLayoutManager::remove_window + window_changed: bool, width: u32, height: u32, diff --git a/src/layout/implementations.rs b/src/layout/implementations.rs index 36c17904..7399bfb5 100644 --- a/src/layout/implementations.rs +++ b/src/layout/implementations.rs @@ -4,6 +4,7 @@ use std::{ borrow::{Borrow, BorrowMut}, + mem, ops::{Deref, DerefMut, Index, IndexMut}, }; @@ -184,7 +185,12 @@ impl WindowNode { /// Creates a window node of the given `window` and dimensions. #[inline] pub(crate) const fn with_dimensions(window: Window, width: u32, height: u32) -> Self { - Self { window, width, height } + Self { + window, + window_changed: false, + width, + height, + } } /// Returns a reference to the window node's window. @@ -193,18 +199,22 @@ impl WindowNode { &self.window } - /// Returns a mutable reference to the window node's window. - #[inline(always)] - pub fn window_mut(&mut self) -> &mut Window { - &mut self.window - } - /// Sets the window node's window to the given `window`. - #[inline(always)] + #[inline] pub fn set_window(&mut self, window: Window) { + self.window_changed = true; + self.window = window; } + /// Replaces the window node's window with the given `window`, returning the previous one. + #[inline] + pub fn replace_window(&mut self, window: Window) -> Window { + self.window_changed = true; + + mem::replace(&mut self.window, window) + } + /// Returns the window node's window. #[inline(always)] pub fn unwrap(self) -> Window { diff --git a/src/layout/implementations/node_changes.rs b/src/layout/implementations/node_changes.rs index dfaff680..ff841d54 100644 --- a/src/layout/implementations/node_changes.rs +++ b/src/layout/implementations/node_changes.rs @@ -467,14 +467,21 @@ impl GroupNode { { // If no changes have been made to this group, apply all the child groups' changes and return. if !self.changes_made() { - let groups = self.children.iter_mut().filter_map(|node| match node { - Node::Group(group) => Some(group), + for node in self { + match node { + Node::Group(group) => group.apply_resizes(resize_window.clone())?, - Node::Window(_) => None, - }); - - for group in groups { - group.apply_resizes(resize_window.clone())?; + Node::Window(WindowNode { + window, + window_changed, + width, + height, + }) => { + if mem::take(window_changed) { + resize_window(window, *width, *height)? + } + }, + } } return Ok(()); @@ -539,7 +546,16 @@ impl GroupNode { match node { Node::Group(group) => group.apply_resizes(resize_window.clone()), - Node::Window(WindowNode { window, .. }) => resize_window(window, primary, secondary), + + Node::Window(WindowNode { + window, + window_changed, + width, + height, + }) => { + *window_changed = false; + resize_window(window, *width, *height) + }, } }; diff --git a/src/layout/managers.rs b/src/layout/managers.rs index 9793f839..6e17ca11 100644 --- a/src/layout/managers.rs +++ b/src/layout/managers.rs @@ -143,12 +143,12 @@ where for (i, node) in window_nodes { // If the window matches, remove it and return. if node.window() == window { - if stack.len() == 1 { - // If it is the last window in the stack, remove the whole stack. - self.layout.remove(1); - } else { - // Otherwise, if it is not the last window in the stack, simply remove that window node. + if stack.len() > 1 { + // If it is not the last window in the stack, remove the node. stack.remove(i); + } else { + // Otherwise, if it is the last window in the stack, remove the stack. + self.layout.remove(1); } return;