diff --git a/src/layout_engine/engine.rs b/src/layout_engine/engine.rs index 952625c9..9989cacf 100644 --- a/src/layout_engine/engine.rs +++ b/src/layout_engine/engine.rs @@ -702,6 +702,12 @@ impl LayoutEngine { if let Some(prev_wid) = previous_selection { let _ = self.workspace_tree_mut(ws_id).select_window(layout, prev_wid); } + // In scrolling layout, don't jump to adjacent displays at the + // boundary. Off-screen columns are intentionally hidden, so + // cross-display focus here would select a hidden window. + if matches!(self.workspace_tree(ws_id), LayoutSystemKind::Scrolling(_)) { + return EventResponse::default(); + } if let Some(new_space) = self.next_space_for_direction( space, direction, diff --git a/src/layout_engine/systems/scrolling.rs b/src/layout_engine/systems/scrolling.rs index f38458da..5b9928e9 100644 --- a/src/layout_engine/systems/scrolling.rs +++ b/src/layout_engine/systems/scrolling.rs @@ -765,7 +765,19 @@ impl LayoutSystem for ScrollingLayoutSystem { .copied() .unwrap_or((tiling.size.width * ratio).max(1.0)); let start = column_starts.get(col_idx).copied().unwrap_or(0.0); - let x = anchor_x + start - offset; + let mut x = anchor_x + start - offset; + // Hide off-screen columns by clamping them to 1px visible at the + // screen edge. This prevents cross-app Z-order issues since + // macOS can't reorder other apps' windows via SLSOrderWindow. + let visible_left = tiling.origin.x; + let visible_right = tiling.origin.x + tiling.size.width; + if x + column_width <= visible_left { + // Column is fully off-screen left: hide just past the edge + x = visible_left - column_width; + } else if x >= visible_right { + // Column is fully off-screen right: hide just past the edge + x = visible_right; + } if col.windows.is_empty() { continue; }