git.lucas.co / cce-window-manager
window management library
git clone https://git.lucas.co/cce-window-manager.git

commitecad2ac902f4a7d9f09199670ed3f114af93c03d
parentd517e66f2e
authorLucas Galante <[email protected]>
date2026-08-18 08:21
fix: plan the grid's you-choose size only before the first patch

Re-planning 0x0 every arrange made the compositor re-configure the grid
client per pass; cce-ui's configure fallback bounced the surface back to
its settings size, and the settings<->patch resize thrash recreated
multi-hundred-MB swapchains per bounce (6.3G peak in 10s). Once a patch
is latched the client owns its size and the compositor plans none.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/arrange.rs | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/arrange.rs b/src/arrange.rs
index ce73d11..3da0cca 100644
--- a/src/arrange.rs
+++ b/src/arrange.rs
@@ -1100,12 +1100,6 @@ pub fn arrange(
                     wp.blur = Some(p.status_blur);
                 }
                 WindowClass::Grid => {
-                    // Always the xdg "you choose" size: the compositor never
-                    // dictates a grid buffer size (patches do), but a window
-                    // with NO planned dimensions can never leave Ready —
-                    // the map state machine requires one. Same trick as
-                    // Utility windows.
-                    wp.size = Some((0, 0));
                     match w.grid_patch {
                         Some(patch) if patch.scale > 0.0 => {
                             wp.scene_enabled = Some(true);
@@ -1134,7 +1128,16 @@ pub fn arrange(
                         }
                         _ => {
                             // No rendered patch yet: keep it out of the
-                            // scene — no flash of an unanchored buffer.
+                            // scene — no flash of an unanchored buffer. The
+                            // xdg "you choose" size unblocks the map state
+                            // machine (a window with NO planned dimensions
+                            // can never leave Ready — same trick as Utility)
+                            // but is planned ONLY in this pre-patch phase:
+                            // once a patch is latched the client owns its
+                            // size, and re-sending 0x0 per arrange bounced
+                            // the surface between the settings size and the
+                            // patch size — a swapchain-thrash that ate GBs.
+                            wp.size = Some((0, 0));
                             wp.scene_enabled = Some(false);
                             wp.hidden = Some(true);
                         }