diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-10-31 07:53:53 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-10-31 08:06:41 +0300 |
| commit | 94eeecac8c67b2b3f03536bbe4f74b4030afcea8 (patch) | |
| tree | ff411523adacb529f5b9cc096de12dd4bdb32823 /src | |
| parent | 739834dfecf7379dc57c541879a1bf7525aaec5f (diff) | |
| download | niri-94eeecac8c67b2b3f03536bbe4f74b4030afcea8.tar.gz niri-94eeecac8c67b2b3f03536bbe4f74b4030afcea8.tar.bz2 niri-94eeecac8c67b2b3f03536bbe4f74b4030afcea8.zip | |
Avoid triggering hot corner during some grabs
Diffstat (limited to 'src')
| -rw-r--r-- | src/input/mod.rs | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs index bfde9876..7b0078ab 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -22,7 +22,7 @@ use smithay::input::pointer::{ AxisFrame, ButtonEvent, CursorIcon, CursorImageStatus, Focus, GestureHoldBeginEvent, GestureHoldEndEvent, GesturePinchBeginEvent, GesturePinchEndEvent, GesturePinchUpdateEvent, GestureSwipeBeginEvent, GestureSwipeEndEvent, GestureSwipeUpdateEvent, - GrabStartData as PointerGrabStartData, MotionEvent, RelativeMotionEvent, + GrabStartData as PointerGrabStartData, MotionEvent, PointerGrab, RelativeMotionEvent, }; use smithay::input::touch::{ DownEvent, GrabStartData as TouchGrabStartData, MotionEvent as TouchMotionEvent, UpEvent, @@ -2366,7 +2366,11 @@ impl State { // contents_under() will return no surface when the hot corner should trigger, so // pointer.motion() will set the current focus to None. if under.hot_corner && pointer.current_focus().is_none() { - if !was_inside_hot_corner { + if !was_inside_hot_corner + && pointer + .with_grab(|_, grab| grab_allows_hot_corner(grab)) + .unwrap_or(true) + { self.niri.layout.toggle_overview(); } self.niri.pointer_inside_hot_corner = true; @@ -2448,7 +2452,11 @@ impl State { // contents_under() will return no surface when the hot corner should trigger, so // pointer.motion() will set the current focus to None. if under.hot_corner && pointer.current_focus().is_none() { - if !was_inside_hot_corner { + if !was_inside_hot_corner + && pointer + .with_grab(|_, grab| grab_allows_hot_corner(grab)) + .unwrap_or(true) + { self.niri.layout.toggle_overview(); } self.niri.pointer_inside_hot_corner = true; @@ -4669,6 +4677,25 @@ pub fn mods_with_finger_scroll_binds(mod_key: ModKey, binds: &Binds) -> HashSet< ) } +fn grab_allows_hot_corner(grab: &(dyn PointerGrab<State> + 'static)) -> bool { + let grab = grab.as_any(); + + // We lean on the blocklist approach here since it's not a terribly big deal if hot corner + // works where it shouldn't, but it could prevent some workflows if the hot corner doesn't work + // when it should. + // + // Some notable grabs not mentioned here: + // - DnDGrab allows hot corner to DnD across workspaces. + // - MoveGrab allows hot corner to DnD across workspaces. + // - ClickGrab keeps pointer focus on the window, so the hot corner doesn't trigger. + // - Touch grabs: touch doesn't trigger the hot corner. + if grab.is::<ResizeGrab>() || grab.is::<SpatialMovementGrab>() { + return false; + } + + true +} + #[cfg(test)] mod tests { use std::cell::Cell; |
