@@ -308,7 +308,9 @@ impl Node { |
| 308 | match self { | 308 | match self { |
| 309 | Node::Leaf { window: Some(w) } => vec![(*w, padded)], | 309 | Node::Leaf { window: Some(w) } => vec![(*w, padded)], |
| 310 | Node::Leaf { window: None } => vec![], | 310 | Node::Leaf { window: None } => vec![], |
| 311 | - Node::Stack { windows, .. } => { | 311 | + Node::Stack { |
| | 312 | + windows, active, .. |
| | 313 | + } => { |
| 312 | // All stack members share the tile's full rect. Non-active | 314 | // All stack members share the tile's full rect. Non-active |
| 313 | // windows sit fully behind the active in z-order. The | 315 | // windows sit fully behind the active in z-order. The |
| 314 | // previous "Slack-style reveal" offset (origin += depth * | 316 | // previous "Slack-style reveal" offset (origin += depth * |
@@ -318,7 +320,27 @@ impl Node { |
| 318 | // larger offsets and visibly drifted away from the tile | 320 | // larger offsets and visibly drifted away from the tile |
| 319 | // (user-reported as "the windows are not sized and | 321 | // (user-reported as "the windows are not sized and |
| 320 | // positioned as if they are members of the stack"). | 322 | // positioned as if they are members of the stack"). |
| 321 | - windows.iter().map(|wid| (*wid, padded)).collect() | 323 | + // |
| | 324 | + // Order matters here even though every member shares the |
| | 325 | + // same rect: apply_layout walks this vec and issues AX |
| | 326 | + // position writes per element, and macOS z-orders whichever |
| | 327 | + // window was positioned last to the top of its level. |
| | 328 | + // Iterating in insertion order would make the last-inserted |
| | 329 | + // member visible regardless of `active`. Putting the active |
| | 330 | + // member last keeps it on top — including when focus leaves |
| | 331 | + // the stack to another monitor and apply_layout re-runs on |
| | 332 | + // the source workspace (visible artifact: the "wrong" stack |
| | 333 | + // member jumps to the top after mod+arrow off the stack). |
| | 334 | + let mut ordered: Vec<(WindowId, Rect)> = Vec::with_capacity(windows.len()); |
| | 335 | + for (i, wid) in windows.iter().enumerate() { |
| | 336 | + if i != *active { |
| | 337 | + ordered.push((*wid, padded)); |
| | 338 | + } |
| | 339 | + } |
| | 340 | + if let Some(active_wid) = windows.get(*active) { |
| | 341 | + ordered.push((*active_wid, padded)); |
| | 342 | + } |
| | 343 | + ordered |
| 322 | } | 344 | } |
| 323 | Node::Internal { | 345 | Node::Internal { |
| 324 | split, | 346 | split, |