@@ -917,39 +917,29 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 917 | 917 | } |
| 918 | 918 | }; |
| 919 | 919 | |
| 920 | | - // Check if any window is further in the requested direction on same monitor |
| 921 | | - // For Up/Down: use monitor proximity instead of window detection (bars/panels cause false positives) |
| 922 | | - let mon_logical_h = (focused_monitor.height as f32 / focused_monitor.scale).round() as i32; |
| 923 | | - let has_window_in_direction = match direction { |
| 924 | | - Direction::Up => { |
| 925 | | - // Window is at top edge if its top is within 100px of monitor top |
| 926 | | - let near_top = win_y <= focused_monitor.y + 100; |
| 927 | | - !near_top |
| 920 | + // Check if any OTHER window on this monitor is further in that direction |
| 921 | + // Use window-based detection for all directions (consistent with IPC Move) |
| 922 | + let has_window_in_direction = clients.iter().any(|client| { |
| 923 | + let mon = client.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32; |
| 924 | + if mon != focused_monitor.id { return false; } |
| 925 | + |
| 926 | + let cx = client.get("at").and_then(|a| a.get(0)).and_then(|x| x.as_i64()).unwrap_or(0) as i32; |
| 927 | + let cy = client.get("at").and_then(|a| a.get(1)).and_then(|y| y.as_i64()).unwrap_or(0) as i32; |
| 928 | + let cw = client.get("size").and_then(|s| s.get(0)).and_then(|w| w.as_i64()).unwrap_or(0) as i32; |
| 929 | + let ch = client.get("size").and_then(|s| s.get(1)).and_then(|h| h.as_i64()).unwrap_or(0) as i32; |
| 930 | + |
| 931 | + // Skip the active window itself |
| 932 | + if cx == win_x && cy == win_y && cw == win_w && ch == win_h { |
| 933 | + return false; |
| 928 | 934 | } |
| 929 | | - Direction::Down => { |
| 930 | | - // Window is at bottom edge if its bottom is within 100px of monitor bottom |
| 931 | | - let win_bottom = win_y + win_h; |
| 932 | | - let mon_bottom = focused_monitor.y + mon_logical_h; |
| 933 | | - let near_bottom = win_bottom >= mon_bottom - 100; |
| 934 | | - !near_bottom |
| 935 | | - } |
| 936 | | - Direction::Left | Direction::Right => { |
| 937 | | - // Window-based detection for horizontal directions |
| 938 | | - clients.iter().any(|client| { |
| 939 | | - let mon = client.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32; |
| 940 | | - if mon != focused_monitor.id { return false; } |
| 941 | | - |
| 942 | | - let cx = client.get("at").and_then(|a| a.get(0)).and_then(|x| x.as_i64()).unwrap_or(0) as i32; |
| 943 | | - let cw = client.get("size").and_then(|s| s.get(0)).and_then(|w| w.as_i64()).unwrap_or(0) as i32; |
| 944 | | - |
| 945 | | - match direction { |
| 946 | | - Direction::Left => cx + cw < win_x + 10, |
| 947 | | - Direction::Right => cx > win_x + win_w - 10, |
| 948 | | - _ => false, |
| 949 | | - } |
| 950 | | - }) |
| 935 | + |
| 936 | + match direction { |
| 937 | + Direction::Left => cx + cw <= win_x + 10, |
| 938 | + Direction::Right => cx >= win_x + win_w - 10, |
| 939 | + Direction::Up => cy + ch <= win_y + 10, |
| 940 | + Direction::Down => cy >= win_y + win_h - 10, |
| 951 | 941 | } |
| 952 | | - }; |
| 942 | + }); |
| 953 | 943 | |
| 954 | 944 | info!(" RECOVERY edge_check: has_window_in_direction={} -> at_edge={}", has_window_in_direction, !has_window_in_direction); |
| 955 | 945 | !has_window_in_direction |