gardesk/tarmac / cec9623

Browse files

Cold-start overflow: collapse workspace into root stack

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
cec9623e660ae070394141b7b8f932ec0fde257f
Parents
75838d6
Tree
ac251df

1 changed file

StatusFile+-
M tarmac/src/core/state.rs 41 1
tarmac/src/core/state.rsmodified
@@ -367,7 +367,7 @@ impl WmState {
367367
         self.apply_layout();
368368
         std::thread::sleep(std::time::Duration::from_millis(50));
369369
         self.apply_layout();
370
-        self.fix_oversized_windows();
370
+        self.fix_oversized_windows_aggressive();
371371
         self.update_borders();
372372
         self.install_observers_for_all();
373373
 
@@ -562,7 +562,23 @@ impl WmState {
562562
     /// After layout, check for windows that overflow their tiles.
563563
     /// Try swapping the oversized window into the largest available tile.
564564
     /// If it still doesn't fit, auto-float it.
565
+    ///
566
+    /// `aggressive` is set during initial discovery: if the BSP layout would
567
+    /// leave any window unable to fit its tile, collapse the entire workspace
568
+    /// into a single root-level stack instead of producing the hybrid
569
+    /// "few-tiles-plus-corner-stack" shape that arises from the staircase BSP
570
+    /// shape on cold start with many windows. Normal runtime overflow keeps
571
+    /// the original Phase 2 behavior — small subtree stacks are fine when the
572
+    /// user has already arranged the layout.
565573
     pub fn fix_oversized_windows(&mut self) {
574
+        self.fix_oversized_windows_with(false);
575
+    }
576
+
577
+    pub fn fix_oversized_windows_aggressive(&mut self) {
578
+        self.fix_oversized_windows_with(true);
579
+    }
580
+
581
+    fn fix_oversized_windows_with(&mut self, aggressive: bool) {
566582
         // Give apps time to settle to their actual minimum size after apply_layout.
567583
         // Some apps (e.g. Messages) handle AX resize asynchronously — they ack the
568584
         // request but snap to their minimum size later.
@@ -663,6 +679,10 @@ impl WmState {
663679
             }
664680
 
665681
             // Phase 2: Replace the smallest conflicting subtree with a stack.
682
+            // In aggressive mode (cold start), collapse the entire workspace
683
+            // tree into one root-level stack on the first oversized window,
684
+            // instead of leaving a hybrid layout where some windows got their
685
+            // own tile and the rest piled into a corner subtree.
666686
             loop {
667687
                 let geometries = self.workspace_focus_geometries(ws_idx, screen_rect);
668688
                 if geometries.is_empty() {
@@ -692,6 +712,26 @@ impl WmState {
692712
                     None => break,
693713
                 };
694714
 
715
+                if aggressive {
716
+                    if self
717
+                        .workspaces
718
+                        .get_mut(ws_idx)
719
+                        .tree
720
+                        .collapse_to_root_stack(oversized_wid)
721
+                    {
722
+                        tracing::info!(
723
+                            id = oversized_wid,
724
+                            min_w,
725
+                            min_h,
726
+                            ws = ws_idx + 1,
727
+                            "cold-start overflow: collapsing workspace into root stack"
728
+                        );
729
+                        self.apply_layout();
730
+                        std::thread::sleep(std::time::Duration::from_millis(50));
731
+                    }
732
+                    break;
733
+                }
734
+
695735
                 if self
696736
                     .workspaces
697737
                     .get_mut(ws_idx)