srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/crates/core/src/manager
diff options
context:
space:
mode:
authorsrdusr <[email protected]>2024-08-22 16:06:00 +0200
committersrdusr <[email protected]>2024-08-22 16:06:00 +0200
commit78da614d67c09e197dffc1cebb1c5ce2357c7128 (patch)
treea39694108f7d1192276a0ea8956e458dc2595d79 /crates/core/src/manager
parent8d94ca5d77d6e2a189d299b8b88a461ba2e621c6 (diff)
downloadsrdwm-78da614d67c09e197dffc1cebb1c5ce2357c7128.tar.gz
srdwm-78da614d67c09e197dffc1cebb1c5ce2357c7128.zip
Add per-window resize-margin override (Hyprland's extend_border_grab_area)
MISSING.md had listed this as needing to touch srdwm_core::window:: hit_test's signature at every call site, including the honest-stub Windows/macOS backends - overstated on closer inspection: that shared function already takes a plain resize_margin: i32 parameter, agnostic to where the value comes from. The only real change needed was reading Window.resize_margin.unwrap_or(wm-wide default) instead of always the WM-wide value, at the single call site inside WindowManager::hit_test in core - no backend touched at all. Window.resize_margin: Option<i32>, WindowRuleActions.resize_margin to match, applied in add_window/reapply_rules_if_pending the same way opacity already is. Settable via a rule action or srd.window.set_resize_margin(n) on the focused window.
Diffstat (limited to 'crates/core/src/manager')
-rw-r--r--crates/core/src/manager/hittest.rs3
-rw-r--r--crates/core/src/manager/tests.rs17
-rw-r--r--crates/core/src/manager/windows.rs6
3 files changed, 25 insertions, 1 deletions
diff --git a/crates/core/src/manager/hittest.rs b/crates/core/src/manager/hittest.rs
index 2d52b57..06ac659 100644
--- a/crates/core/src/manager/hittest.rs
+++ b/crates/core/src/manager/hittest.rs
@@ -24,7 +24,8 @@ impl WindowManager {
if w.minimized || w.workspace != self.current_workspace {
continue;
}
- if let Some(hit) = ResizeEdge::hit_test(w.geometry, x, y, w.decorated, w.border_width, self.resize_margin) {
+ let margin = w.resize_margin.unwrap_or(self.resize_margin);
+ if let Some(hit) = ResizeEdge::hit_test(w.geometry, x, y, w.decorated, w.border_width, margin) {
return Some((w.id, hit));
}
}
diff --git a/crates/core/src/manager/tests.rs b/crates/core/src/manager/tests.rs
index 24e8932..e1518f1 100644
--- a/crates/core/src/manager/tests.rs
+++ b/crates/core/src/manager/tests.rs
@@ -246,6 +246,23 @@
}
#[test]
+ fn per_window_resize_margin_overrides_the_wm_wide_default() {
+ // Hyprland's per-window `extend_border_grab_area` equivalent.
+ let mut wm = wm_with_monitor();
+ wm.set_layout(wm.current_workspace(), "tiling"); // keeps add_window from overriding geometry via SmartPlacement
+ let id = wm.alloc_window_id();
+ let mut w = Window::new(id, "a");
+ w.geometry = Rect::new(100, 100, 400, 300);
+ w.resize_margin = Some(30);
+ wm.add_window(w);
+
+ // 15px in from the left edge: well past the WM-wide default (6px),
+ // but still inside this window's own wider 30px override.
+ let hit = wm.hit_test(115, 250);
+ assert_eq!(hit.map(|(_, h)| h), Some(TitlebarHit::Resize(ResizeEdge::Left)));
+ }
+
+ #[test]
fn moving_window_to_another_workspace_removes_it_from_current() {
let mut wm = wm_with_monitor();
let a = wm.alloc_window_id();
diff --git a/crates/core/src/manager/windows.rs b/crates/core/src/manager/windows.rs
index 6171c15..4b4c0c8 100644
--- a/crates/core/src/manager/windows.rs
+++ b/crates/core/src/manager/windows.rs
@@ -52,6 +52,9 @@ impl WindowManager {
if let Some(opacity) = a.opacity {
window.opacity = opacity.clamp(0.0, 1.0);
}
+ if let Some(margin) = a.resize_margin {
+ window.resize_margin = Some(margin);
+ }
}
if let Some(monitor) = self.primary_monitor() {
@@ -127,6 +130,9 @@ impl WindowManager {
if let Some(opacity) = actions.opacity {
window.opacity = opacity.clamp(0.0, 1.0);
}
+ if let Some(margin) = actions.resize_margin {
+ window.resize_margin = Some(margin);
+ }
if let Some(geometry) = actions.geometry {
window.geometry = geometry;
}