aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-10-31 07:53:53 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-10-31 08:06:41 +0300
commit94eeecac8c67b2b3f03536bbe4f74b4030afcea8 (patch)
treeff411523adacb529f5b9cc096de12dd4bdb32823 /src
parent739834dfecf7379dc57c541879a1bf7525aaec5f (diff)
downloadniri-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.rs33
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;