tenseleyflow/hyprkvm / 92a72cc

Browse files

fix: use window-based edge detection for Up/Down directions

The previous code only checked if the current window was near the
monitor edge, not if there were other windows in that direction.
This caused Super+Up to always transfer when on the edge monitor,
even if there were windows above the current one.

Now all four directions use the same logic: check if any other window
on the same monitor is further in the requested direction.
Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
92a72ccd1c0cc2e3a6755de8decf786b2df6b63c
Parents
a27c4a6
Tree
455a5dd

1 changed file

StatusFile+-
M hyprkvm-daemon/src/main.rs 20 30
hyprkvm-daemon/src/main.rsmodified
@@ -1794,38 +1794,28 @@ async fn run_daemon(config_path: &std::path::Path) -> anyhow::Result<()> {
17941794
                                   clients.iter().filter(|c| c.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32 == focused_monitor.id).count(),
17951795
                                   focused_monitor.y, mon_logical_h);
17961796
 
1797
-                            // For Up/Down: check if window is near monitor edge (accounts for bars/panels)
1798
-                            // For Left/Right: check if any window is further in that direction
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
1797
+                            // Check if any OTHER window on this monitor is further in that direction
1798
+                            let has_window_in_direction = clients.iter().any(|client| {
1799
+                                let mon = client.get("monitor").and_then(|m| m.as_i64()).unwrap_or(-1) as i32;
1800
+                                if mon != focused_monitor.id { return false; }
1801
+
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;
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;
1806
+
1807
+                                // Skip the active window itself
1808
+                                if cx == win_x && cy == win_y && cw == win_w && ch == win_h {
1809
+                                    return false;
18041810
                                 }
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;
1816
-                                        if mon != focused_monitor.id { return false; }
1817
-
1818
-                                        let cx = client.get("at").and_then(|a| a.get(0)).and_then(|x| x.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;
1820
-
1821
-                                        match direction {
1822
-                                            Direction::Left => cx + cw < win_x + 10,
1823
-                                            Direction::Right => cx > win_x + win_w - 10,
1824
-                                            _ => false,
1825
-                                        }
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,
18271817
                                 }
1828
-                            };
1818
+                            });
18291819
 
18301820
                             info!("  edge_check: has_window_in_direction={} -> at_edge={}", has_window_in_direction, !has_window_in_direction);
18311821
                             !has_window_in_direction