@@ -1794,38 +1794,28 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> { |
| 1794 | clients.iter().filter(|c| c.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32 == focused_monitor.id).count(), | 1794 | clients.iter().filter(|c| c.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32 == focused_monitor.id).count(), |
| 1795 | focused_monitor.y, mon_logical_h); | 1795 | focused_monitor.y, mon_logical_h); |
| 1796 | | 1796 | |
| 1797 | - // For Up/Down: check if window is near monitor edge (accounts for bars/panels) | 1797 | + // Check if any OTHER window on this monitor is further in that direction |
| 1798 | - // For Left/Right: check if any window is further in that direction | 1798 | + let has_window_in_direction = clients.iter().any(|client| { |
| 1799 | - let has_window_in_direction = match direction { | | |
| 1800 | - Direction::Up => { | | |
| 1801 | - // Window is at top edge if its top is within 100px of monitor top (allows for bars) | | |
| 1802 | - let near_top = win_y <= focused_monitor.y + 100; | | |
| 1803 | - !near_top // has_window_in_direction = !near_top, so at_edge = near_top | | |
| 1804 | - } | | |
| 1805 | - Direction::Down => { | | |
| 1806 | - // Window is at bottom edge if its bottom is within 100px of monitor bottom | | |
| 1807 | - let win_bottom = win_y + win_h; | | |
| 1808 | - let mon_bottom = focused_monitor.y + mon_logical_h; | | |
| 1809 | - let near_bottom = win_bottom >= mon_bottom - 100; | | |
| 1810 | - !near_bottom // has_window_in_direction = !near_bottom, so at_edge = near_bottom | | |
| 1811 | - } | | |
| 1812 | - Direction::Left | Direction::Right => { | | |
| 1813 | - // For Left/Right, use window-based detection | | |
| 1814 | - clients.iter().any(|client| { | | |
| 1815 | let mon = client.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32; | 1799 | let mon = client.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32; |
| 1816 | if mon != focused_monitor.id { return false; } | 1800 | if mon != focused_monitor.id { return false; } |
| 1817 | | 1801 | |
| 1818 | let cx = client.get("at").and_then(|a| a.get(0)).and_then(|x| x.as_i64()).unwrap_or(0) as i32; | 1802 | let cx = client.get("at").and_then(|a| a.get(0)).and_then(|x| x.as_i64()).unwrap_or(0) as i32; |
| | 1803 | + let cy = client.get("at").and_then(|a| a.get(1)).and_then(|y| y.as_i64()).unwrap_or(0) as i32; |
| 1819 | let cw = client.get("size").and_then(|s| s.get(0)).and_then(|w| w.as_i64()).unwrap_or(0) as i32; | 1804 | let cw = client.get("size").and_then(|s| s.get(0)).and_then(|w| w.as_i64()).unwrap_or(0) as i32; |
| | 1805 | + let ch = client.get("size").and_then(|s| s.get(1)).and_then(|h| h.as_i64()).unwrap_or(0) as i32; |
| 1820 | | 1806 | |
| 1821 | - match direction { | 1807 | + // Skip the active window itself |
| 1822 | - Direction::Left => cx + cw < win_x + 10, | 1808 | + if cx == win_x && cy == win_y && cw == win_w && ch == win_h { |
| 1823 | - Direction::Right => cx > win_x + win_w - 10, | 1809 | + return false; |
| 1824 | - _ => false, | | |
| 1825 | } | 1810 | } |
| 1826 | - }) | 1811 | + |
| | 1812 | + match direction { |
| | 1813 | + Direction::Left => cx + cw <= win_x + 10, |
| | 1814 | + Direction::Right => cx >= win_x + win_w - 10, |
| | 1815 | + Direction::Up => cy + ch <= win_y + 10, |
| | 1816 | + Direction::Down => cy >= win_y + win_h - 10, |
| 1827 | } | 1817 | } |
| 1828 | - }; | 1818 | + }); |
| 1829 | | 1819 | |
| 1830 | info!(" edge_check: has_window_in_direction={} -> at_edge={}", has_window_in_direction, !has_window_in_direction); | 1820 | info!(" edge_check: has_window_in_direction={} -> at_edge={}", has_window_in_direction, !has_window_in_direction); |
| 1831 | !has_window_in_direction | 1821 | !has_window_in_direction |