agentmux_launcher\wrr/
rect.rs1use agentmux_common::ipc::Rect;
12
13pub fn intersects(r: &Rect, m: &Rect) -> bool {
15 if r.left >= r.right || r.top >= r.bottom {
16 return false;
17 }
18 if m.left >= m.right || m.top >= m.bottom {
19 return false;
20 }
21 r.left < m.right && r.right > m.left && r.top < m.bottom && r.bottom > m.top
22}
23
24pub fn intersects_any(r: &Rect, monitors: &[Rect]) -> bool {
28 monitors.iter().any(|m| intersects(r, m))
29}
30
31#[cfg(test)]
32mod tests {
33 use super::*;
34
35 fn rect(l: i32, t: i32, r: i32, b: i32) -> Rect {
36 Rect { left: l, top: t, right: r, bottom: b }
37 }
38
39 #[test]
40 fn fully_inside_intersects() {
41 let mon = rect(0, 0, 1920, 1080);
42 let win = rect(100, 100, 800, 600);
43 assert!(intersects(&win, &mon));
44 }
45
46 #[test]
47 fn touching_edge_does_not_intersect() {
48 let mon = rect(0, 0, 1920, 1080);
50 let win = rect(1920, 100, 2920, 600);
51 assert!(!intersects(&win, &mon));
52 }
53
54 #[test]
55 fn fully_off_screen_no_intersect() {
56 let mon = rect(0, 0, 1920, 1080);
57 let off = rect(-9999, -9999, -9000, -9000);
58 assert!(!intersects(&off, &mon));
59 }
60
61 #[test]
62 fn intersects_any_picks_correct_monitor() {
63 let monitors = vec![
64 rect(0, 0, 1920, 1080), rect(1920, 0, 3840, 1080), ];
67 let win = rect(2000, 100, 2500, 600);
68 assert!(intersects_any(&win, &monitors));
69 }
70
71 #[test]
72 fn empty_monitors_returns_false() {
73 let win = rect(100, 100, 200, 200);
74 assert!(!intersects_any(&win, &[]));
75 }
76
77 #[test]
78 fn empty_rect_never_intersects() {
79 let mon = rect(0, 0, 1920, 1080);
80 let zero = rect(100, 100, 100, 100);
81 assert!(!intersects(&zero, &mon));
82 }
83
84 #[test]
85 fn cross_monitor_window_intersects_one() {
86 let monitors = vec![
88 rect(0, 0, 1920, 1080),
89 rect(1920, 0, 3840, 1080),
90 ];
91 let straddle = rect(1800, 100, 2200, 600);
92 assert!(intersects_any(&straddle, &monitors));
93 }
94}