gardesk/tarmac / 661f759

Browse files

apply_layout: stage non-active stack members off-screen

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
661f759a13b1b1f215f665cc00f47f6851d22ff8
Parents
7a10607
Tree
e9de5eb

1 changed file

StatusFile+-
M tarmac/src/core/state.rs 22 1
tarmac/src/core/state.rsmodified
@@ -454,11 +454,26 @@ impl WmState {
454
             let ws = self.workspaces.get(ws_idx);
454
             let ws = self.workspaces.get(ws_idx);
455
             let screen_rect = self.monitor_rect(mi);
455
             let screen_rect = self.monitor_rect(mi);
456
             let geometries = self.workspace_render_geometries(ws_idx, screen_rect);
456
             let geometries = self.workspace_render_geometries(ws_idx, screen_rect);
457
+            // Only the active member of each stack lives at the tile rect.
458
+            // Non-active members get staged off-screen via hide_window so
459
+            // macOS's per-app global z-order cannot surface a non-active
460
+            // member above the active one (which happened when stacks
461
+            // contained windows from different apps and the user focused
462
+            // a sibling of one of those apps elsewhere — e.g. a Ghostty
463
+            // member of a Messages-active stack rising to the top of the
464
+            // tile when the user focused a different Ghostty on another
465
+            // monitor). focus_geometries returns one entry per visible
466
+            // tile (active for stacks, the leaf window for BSP leaves), so
467
+            // the difference vs render geometries is exactly the set of
468
+            // non-active stack members.
469
+            let actives = self.workspace_focus_geometries(ws_idx, screen_rect);
470
+            let active_ids: std::collections::HashSet<super::window::WindowId> =
471
+                actives.iter().map(|(w, _)| *w).collect();
457
             tracing::debug!(monitor = mi, workspace = %ws.id, windows = geometries.len(),
472
             tracing::debug!(monitor = mi, workspace = %ws.id, windows = geometries.len(),
458
                 sr_x = screen_rect.x, sr_y = screen_rect.y, sr_w = screen_rect.width,
473
                 sr_x = screen_rect.x, sr_y = screen_rect.y, sr_w = screen_rect.width,
459
                 sr_h = screen_rect.height, "apply_layout");
474
                 sr_h = screen_rect.height, "apply_layout");
460
 
475
 
461
-            for (wid, rect) in &geometries {
476
+            for (wid, rect) in &actives {
462
                 tracing::debug!(
477
                 tracing::debug!(
463
                     wid,
478
                     wid,
464
                     x = rect.x,
479
                     x = rect.x,
@@ -469,6 +484,12 @@ impl WmState {
469
                 );
484
                 );
470
                 self.show_window(*wid, *rect);
485
                 self.show_window(*wid, *rect);
471
             }
486
             }
487
+            for (wid, _) in &geometries {
488
+                if !active_ids.contains(wid) {
489
+                    tracing::debug!(wid, "stack non-active hidden off-screen");
490
+                    self.hide_window(*wid);
491
+                }
492
+            }
472
 
493
 
473
             for fw in &ws.floating {
494
             for fw in &ws.floating {
474
                 tracing::debug!(
495
                 tracing::debug!(