From c0902bcad475291b13befca6369816631d7093e0 Mon Sep 17 00:00:00 2001 From: Daniel <101683475+Koranir@users.noreply.github.com> Date: Thu, 6 Feb 2025 13:44:59 +1100 Subject: [PATCH] Make the snap threshold configurable --- cosmic-comp-config/src/lib.rs | 3 +++ src/config/mod.rs | 6 +++++ src/input/mod.rs | 1 + src/shell/element/stack.rs | 1 + src/shell/element/window.rs | 1 + src/shell/grabs/menu/default.rs | 30 ++++++++++++++++++----- src/shell/grabs/moving.rs | 19 ++++++++++---- src/shell/layout/floating/grabs/resize.rs | 15 +++++++++--- src/shell/layout/floating/mod.rs | 3 +++ src/shell/mod.rs | 5 ++++ src/wayland/handlers/xdg_shell/mod.rs | 11 ++++++--- src/xwayland.rs | 11 ++++++--- 12 files changed, 85 insertions(+), 21 deletions(-) diff --git a/cosmic-comp-config/src/lib.rs b/cosmic-comp-config/src/lib.rs index 5a656e525..f926124c1 100644 --- a/cosmic-comp-config/src/lib.rs +++ b/cosmic-comp-config/src/lib.rs @@ -31,6 +31,8 @@ pub struct CosmicCompConfig { pub focus_follows_cursor_delay: u64, /// Let X11 applications scale themselves pub descale_xwayland: bool, + /// The threshold before windows snap themselves to output edges + pub window_snap_threshold: u32, } impl Default for CosmicCompConfig { @@ -60,6 +62,7 @@ impl Default for CosmicCompConfig { cursor_follows_focus: false, focus_follows_cursor_delay: 250, descale_xwayland: false, + window_snap_threshold: 0, } } } diff --git a/src/config/mod.rs b/src/config/mod.rs index 2aa5ff75b..9a27ba0b7 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -756,6 +756,12 @@ fn config_changed(config: cosmic_config::Config, keys: Vec, state: &mut state.common.config.cosmic_conf.focus_follows_cursor_delay = new; } } + "window_snap_threshold" => { + let new = get_config::(&config, "window_snap_threshold"); + if new != state.common.config.cosmic_conf.window_snap_threshold { + state.common.config.cosmic_conf.window_snap_threshold = new; + } + } _ => {} } } diff --git a/src/input/mod.rs b/src/input/mod.rs index 2f225bed1..bf80fed41 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -740,6 +740,7 @@ impl State { } }; let res = shell.resize_request( + &state.common.config, &surface, &seat_clone, serial, diff --git a/src/shell/element/stack.rs b/src/shell/element/stack.rs index e14b8a583..340985f11 100644 --- a/src/shell/element/stack.rs +++ b/src/shell/element/stack.rs @@ -1355,6 +1355,7 @@ impl PointerTarget for CosmicStack { }; self.0.loop_handle().insert_idle(move |state| { let res = state.common.shell.write().unwrap().resize_request( + &state.common.config, &surface, &seat, serial, diff --git a/src/shell/element/window.rs b/src/shell/element/window.rs index 57b525789..d58790db5 100644 --- a/src/shell/element/window.rs +++ b/src/shell/element/window.rs @@ -745,6 +745,7 @@ impl PointerTarget for CosmicWindow { }; self.0.loop_handle().insert_idle(move |state| { let res = state.common.shell.write().unwrap().resize_request( + &state.common.config, &surface, &seat, serial, diff --git a/src/shell/grabs/menu/default.rs b/src/shell/grabs/menu/default.rs index 9a976de9b..774551d3f 100644 --- a/src/shell/grabs/menu/default.rs +++ b/src/shell/grabs/menu/default.rs @@ -288,7 +288,12 @@ pub fn window_items( let _ = handle.insert_idle(move |state| { let mut shell = state.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); - let res = shell.menu_resize_request(&resize_clone, &seat, ResizeEdge::TOP); + let res = shell.menu_resize_request( + &state.common.config, + &resize_clone, + &seat, + ResizeEdge::TOP, + ); std::mem::drop(shell); if let Some(((target, loc), (grab, focus))) = res { @@ -318,7 +323,12 @@ pub fn window_items( let _ = handle.insert_idle(move |state| { let mut shell = state.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); - let res = shell.menu_resize_request(&resize_clone, &seat, ResizeEdge::LEFT); + let res = shell.menu_resize_request( + &state.common.config, + &resize_clone, + &seat, + ResizeEdge::LEFT, + ); std::mem::drop(shell); if let Some(((target, loc), (grab, focus))) = res { @@ -348,8 +358,12 @@ pub fn window_items( let _ = handle.insert_idle(move |state| { let mut shell = state.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); - let res = - shell.menu_resize_request(&resize_clone, &seat, ResizeEdge::RIGHT); + let res = shell.menu_resize_request( + &state.common.config, + &resize_clone, + &seat, + ResizeEdge::RIGHT, + ); std::mem::drop(shell); if let Some(((target, loc), (grab, focus))) = res { @@ -379,8 +393,12 @@ pub fn window_items( let _ = handle.insert_idle(move |state| { let mut shell = state.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); - let res = - shell.menu_resize_request(&resize_clone, &seat, ResizeEdge::BOTTOM); + let res = shell.menu_resize_request( + &state.common.config, + &resize_clone, + &seat, + ResizeEdge::BOTTOM, + ); std::mem::drop(shell); if let Some(((target, loc), (grab, focus))) = res { diff --git a/src/shell/grabs/moving.rs b/src/shell/grabs/moving.rs index d1e60cd7f..e798ecefd 100644 --- a/src/shell/grabs/moving.rs +++ b/src/shell/grabs/moving.rs @@ -342,6 +342,7 @@ pub struct MoveGrab { window_outputs: HashSet, previous: ManagedLayer, release: ReleaseMode, + window_snap_threshold: f64, // SAFETY: This is only used on drop which will always be on the main thread evlh: NotSend>, } @@ -395,16 +396,22 @@ impl MoveGrab { let output_loc = output_geom.loc; let output_size = output_geom.size; - grab_state.location.x = if (loc.x - output_loc.x).abs() < 10.0 { + grab_state.location.x = if (loc.x - output_loc.x).abs() < self.window_snap_threshold + { output_loc.x - grab_state.window_offset.x as f64 - } else if ((loc.x + size.w) - (output_loc.x + output_size.w)).abs() < 10.0 { + } else if ((loc.x + size.w) - (output_loc.x + output_size.w)).abs() + < self.window_snap_threshold + { output_loc.x + output_size.w - grab_state.window_offset.x as f64 - size.w } else { grab_state.location.x }; - grab_state.location.y = if (loc.y - output_loc.y).abs() < 10.0 { + grab_state.location.y = if (loc.y - output_loc.y).abs() < self.window_snap_threshold + { output_loc.y - grab_state.window_offset.y as f64 - } else if ((loc.y + size.h) - (output_loc.y + output_size.h)).abs() < 10.0 { + } else if ((loc.y + size.h) - (output_loc.y + output_size.h)).abs() + < self.window_snap_threshold + { output_loc.y + output_size.h - grab_state.window_offset.y as f64 - size.h } else { grab_state.location.y @@ -709,6 +716,7 @@ impl MoveGrab { initial_window_location: Point, cursor_output: Output, indicator_thickness: u8, + window_snap_threshold: f64, previous_layer: ManagedLayer, release: ReleaseMode, evlh: LoopHandle<'static, State>, @@ -748,10 +756,11 @@ impl MoveGrab { window, start_data, seat: seat.clone(), - window_outputs: outputs, cursor_output, + window_outputs: outputs, previous: previous_layer, release, + window_snap_threshold, evlh: NotSend(evlh), } } diff --git a/src/shell/layout/floating/grabs/resize.rs b/src/shell/layout/floating/grabs/resize.rs index c7b9f70d5..eae6758ff 100644 --- a/src/shell/layout/floating/grabs/resize.rs +++ b/src/shell/layout/floating/grabs/resize.rs @@ -58,6 +58,7 @@ pub struct ResizeSurfaceGrab { window: CosmicMapped, edges: ResizeEdge, output: Output, + window_snap_threshold: i32, initial_window_location: Point, initial_window_size: Size, last_window_size: Size, @@ -96,7 +97,9 @@ impl ResizeSurfaceGrab { // If the resizing vertical edge is close to our output's edge in the same direction, snap to it. let output_geom = self.output.geometry().to_local(&self.output); if self.edges.intersects(ResizeEdge::LEFT) { - if (self.initial_window_location.x - dx as i32 - output_geom.loc.x).abs() < 10 { + if (self.initial_window_location.x - dx as i32 - output_geom.loc.x).abs() + < self.window_snap_threshold + { new_window_width = self.initial_window_size.w - output_geom.loc.x + self.initial_window_location.x; } @@ -105,7 +108,7 @@ impl ResizeSurfaceGrab { - output_geom.loc.x - output_geom.size.w) .abs() - < 10 + < self.window_snap_threshold { new_window_width = output_geom.loc.x - self.initial_window_location.x + output_geom.size.w; @@ -123,7 +126,9 @@ impl ResizeSurfaceGrab { // If the resizing horizontal edge is close to our output's edge in the same direction, snap to it. let output_geom = self.output.geometry().to_local(&self.output); if self.edges.intersects(ResizeEdge::TOP) { - if (self.initial_window_location.y - dy as i32 - output_geom.loc.y).abs() < 10 { + if (self.initial_window_location.y - dy as i32 - output_geom.loc.y).abs() + < self.window_snap_threshold + { new_window_height = self.initial_window_size.h - output_geom.loc.y + self.initial_window_location.y; } @@ -132,7 +137,7 @@ impl ResizeSurfaceGrab { - output_geom.loc.y - output_geom.size.h) .abs() - < 10 + < self.window_snap_threshold { new_window_height = output_geom.loc.y - self.initial_window_location.y + output_geom.size.h; @@ -414,6 +419,7 @@ impl ResizeSurfaceGrab { mapped: CosmicMapped, edges: ResizeEdge, output: Output, + window_snap_threshold: i32, initial_window_location: Point, initial_window_size: Size, seat: &Seat, @@ -457,6 +463,7 @@ impl ResizeSurfaceGrab { initial_window_size, last_window_size: initial_window_size, release, + window_snap_threshold, } } diff --git a/src/shell/layout/floating/mod.rs b/src/shell/layout/floating/mod.rs index 21175a1f8..f1293cb53 100644 --- a/src/shell/layout/floating/mod.rs +++ b/src/shell/layout/floating/mod.rs @@ -25,6 +25,7 @@ use smithay::{ use crate::{ backend::render::{element::AsGlowRenderer, IndicatorShader, Key, Usage}, + config::Config, shell::{ element::{ resize_indicator::ResizeIndicator, @@ -884,6 +885,7 @@ impl FloatingLayout { pub fn resize_request( &mut self, + config: &Config, mapped: &CosmicMapped, seat: &Seat, start_data: GrabStartData, @@ -900,6 +902,7 @@ impl FloatingLayout { mapped.clone(), edges, self.space.outputs().next().cloned().unwrap(), + config.cosmic_conf.window_snap_threshold as i32, location, size, seat, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index ef871567f..7b566db59 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -2866,6 +2866,7 @@ impl Shell { initial_window_location, cursor_output, active_hint, + config.cosmic_conf.window_snap_threshold as f64, layer, release, evlh.clone(), @@ -3117,6 +3118,7 @@ impl Shell { pub fn menu_resize_request( &mut self, + config: &Config, mapped: &CosmicMapped, seat: &Seat, edge: ResizeEdge, @@ -3183,6 +3185,7 @@ impl Shell { start_data.set_focus(focus.clone()); let grab: ResizeGrab = if let Some(grab) = floating_layer.resize_request( + config, mapped, seat, start_data.clone(), @@ -3358,6 +3361,7 @@ impl Shell { pub fn resize_request( &mut self, + config: &Config, surface: &WlSurface, seat: &Seat, serial: impl Into>, @@ -3385,6 +3389,7 @@ impl Shell { }; let grab: ResizeGrab = if let Some(grab) = floating_layer.resize_request( + config, &mapped, seat, start_data.clone(), diff --git a/src/wayland/handlers/xdg_shell/mod.rs b/src/wayland/handlers/xdg_shell/mod.rs index 7f19913c3..e37f1f9fc 100644 --- a/src/wayland/handlers/xdg_shell/mod.rs +++ b/src/wayland/handlers/xdg_shell/mod.rs @@ -189,9 +189,14 @@ impl XdgShellHandler for State { ) { let seat = Seat::from_resource(&seat).unwrap(); let mut shell = self.common.shell.write().unwrap(); - if let Some((grab, focus)) = - shell.resize_request(surface.wl_surface(), &seat, serial, edges.into(), true) - { + if let Some((grab, focus)) = shell.resize_request( + &self.common.config, + surface.wl_surface(), + &seat, + serial, + edges.into(), + true, + ) { std::mem::drop(shell); if grab.is_touch_grab() { seat.get_touch().unwrap().set_grab(self, grab, serial) diff --git a/src/xwayland.rs b/src/xwayland.rs index 3847f7b6b..44a6a275f 100644 --- a/src/xwayland.rs +++ b/src/xwayland.rs @@ -549,9 +549,14 @@ impl XwmHandler for State { if let Some(wl_surface) = window.wl_surface() { let mut shell = self.common.shell.write().unwrap(); let seat = shell.seats.last_active().clone(); - if let Some((grab, focus)) = - shell.resize_request(&wl_surface, &seat, None, resize_edge.into(), true) - { + if let Some((grab, focus)) = shell.resize_request( + &self.common.config, + &wl_surface, + &seat, + None, + resize_edge.into(), + true, + ) { std::mem::drop(shell); if grab.is_touch_grab() { seat.get_touch()