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.
This commit is contained in:
Samuel Onoja committed 2026-09-29 13:09:58 +01:00
1 parent 4bf8043137
commit 7d3a88bef7
1 file changed
+9 -12
+9 -12
View File
@@ -1442,19 +1442,16 @@ impl Ferese {
} }
} }
let hidden = self let mut space = std::mem::take(&mut self.space);
.window_ids let mut layout_changed = false;
.iter() for (window, id) in &self.window_ids {
.filter(|(_, id)| !visible.contains(id)) if visible.contains(id) {
.map(|(window, _)| window.clone()) continue;
.collect::<Vec<_>>(); }
layout_changed |= space.element_location(window).is_some();
let mut layout_changed = hidden space.unmap_elem(window);
.iter()
.any(|window| self.space.element_location(window).is_some());
for window in hidden {
self.space.unmap_elem(&window);
} }
self.space = space;
let now = self.start_time.elapsed(); let now = self.start_time.elapsed();