From 7d3a88bef70636149f43b2d1a0993dc183edcb68 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 29 Sep 2026 13:09:58 +0100 Subject: [PATCH] Unmap hidden windows in place in relayout The hidden-window sweep built a Vec of cloned Window handles purely to work around the borrow checker: unmap_elem needs &mut self.space while the iteration borrows self.window_ids. Move the space out with mem::take instead and unmap in place, dropping the allocation and the per-window clone. Behaviour is unchanged. unmap_elem only removes the element passed to it, so it cannot affect element_location for any other window, which makes checking each window immediately before its own unmap equivalent to testing every hidden window up front; the unmap order is the same window_ids iteration order. The |= is deliberate so the check never short-circuits past an unmap. This is a cleanup, not a measured win. The sweep is dominated by the linear scans inside element_location and unmap_elem, and a Vec only allocated when windows were actually hidden, so the saving is small. Verified with twelve live foot windows across forty workspace switches. --- compositor/src/state.rs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/compositor/src/state.rs b/compositor/src/state.rs index 0a749b2..947ce56 100644 --- a/compositor/src/state.rs +++ b/compositor/src/state.rs @@ -1442,19 +1442,16 @@ impl Ferese { } } - let hidden = self - .window_ids - .iter() - .filter(|(_, id)| !visible.contains(id)) - .map(|(window, _)| window.clone()) - .collect::>(); - - let mut layout_changed = hidden - .iter() - .any(|window| self.space.element_location(window).is_some()); - for window in hidden { - self.space.unmap_elem(&window); + let mut space = std::mem::take(&mut self.space); + let mut layout_changed = false; + for (window, id) in &self.window_ids { + if visible.contains(id) { + continue; + } + layout_changed |= space.element_location(window).is_some(); + space.unmap_elem(window); } + self.space = space; let now = self.start_time.elapsed();