@@ -332,7 +332,7 @@ impl EdgeCaptureState { |
| 332 | | 332 | |
| 333 | /// Find the output(s) at the edge of the screen for a given direction | 333 | /// Find the output(s) at the edge of the screen for a given direction |
| 334 | /// For Left/Right: returns single monitor at the edge | 334 | /// For Left/Right: returns single monitor at the edge |
| 335 | - /// For Up/Down: returns ALL monitors at the top/bottom edge (for horizontal layouts) | 335 | + /// For Up/Down: returns ALL monitors (in horizontal layouts, all monitors have exposed top/bottom edges) |
| 336 | fn find_edge_outputs(&self, direction: Direction) -> Vec<OutputInfo> { | 336 | fn find_edge_outputs(&self, direction: Direction) -> Vec<OutputInfo> { |
| 337 | if self.outputs.is_empty() { | 337 | if self.outputs.is_empty() { |
| 338 | return vec![]; | 338 | return vec![]; |
@@ -348,14 +348,26 @@ impl EdgeCaptureState { |
| 348 | self.outputs.iter().max_by_key(|o| o.x + o.width as i32).cloned().into_iter().collect() | 348 | self.outputs.iter().max_by_key(|o| o.x + o.width as i32).cloned().into_iter().collect() |
| 349 | } | 349 | } |
| 350 | Direction::Up => { | 350 | Direction::Up => { |
| 351 | - // Find ALL outputs at minimum y (all topmost monitors) | 351 | + // For horizontal layouts: all monitors with nothing above them |
| 352 | - let min_y = self.outputs.iter().map(|o| o.y).min().unwrap_or(0); | 352 | + // A monitor has nothing above if no other monitor overlaps its x range at a lower y |
| 353 | - self.outputs.iter().filter(|o| o.y == min_y).cloned().collect() | 353 | + self.outputs.iter().filter(|o| { |
| | 354 | + !self.outputs.iter().any(|other| { |
| | 355 | + other.y + other.height as i32 <= o.y && // other is above |
| | 356 | + other.x < o.x + o.width as i32 && // overlaps in x |
| | 357 | + other.x + other.width as i32 > o.x |
| | 358 | + }) |
| | 359 | + }).cloned().collect() |
| 354 | } | 360 | } |
| 355 | Direction::Down => { | 361 | Direction::Down => { |
| 356 | - // Find ALL outputs at maximum y + height (all bottommost monitors) | 362 | + // For horizontal layouts: all monitors with nothing below them |
| 357 | - let max_bottom = self.outputs.iter().map(|o| o.y + o.height as i32).max().unwrap_or(0); | 363 | + // A monitor has nothing below if no other monitor overlaps its x range at a higher y |
| 358 | - self.outputs.iter().filter(|o| o.y + o.height as i32 == max_bottom).cloned().collect() | 364 | + self.outputs.iter().filter(|o| { |
| | 365 | + !self.outputs.iter().any(|other| { |
| | 366 | + other.y >= o.y + o.height as i32 && // other is below |
| | 367 | + other.x < o.x + o.width as i32 && // overlaps in x |
| | 368 | + other.x + other.width as i32 > o.x |
| | 369 | + }) |
| | 370 | + }).cloned().collect() |
| 359 | } | 371 | } |
| 360 | } | 372 | } |
| 361 | } | 373 | } |