aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-09-12 16:48:29 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-09-12 16:48:29 +0300
commit55a798bd8b44465a354c1bd7723d4ece855c362c (patch)
treed84e0cbb8934bfbc243d70ff7ff39493b473484b
parentcdcd5a2835cd4d48d9b51cce4b94fbd1a6eb8b5c (diff)
downloadniri-55a798bd8b44465a354c1bd7723d4ece855c362c.tar.gz
niri-55a798bd8b44465a354c1bd7723d4ece855c362c.tar.bz2
niri-55a798bd8b44465a354c1bd7723d4ece855c362c.zip
Prevent unintended focus-follows-mouse during workspace switch
-rw-r--r--src/layout/mod.rs29
-rw-r--r--src/niri.rs4
2 files changed, 33 insertions, 0 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 5ab81f03..9d69e0ff 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1031,6 +1031,35 @@ impl<W: LayoutElement> Layout<W> {
0.
}
+ pub fn should_trigger_focus_follows_mouse_on(&self, window: &W::Id) -> bool {
+ // During an animation, it's easy to trigger focus-follows-mouse on the previous workspace,
+ // especially when clicking to switch workspace on a bar of some kind. This cancels the
+ // workspace switch, which is annoying and not intended.
+ //
+ // This function allows focus-follows-mouse to trigger only on the animation target
+ // workspace.
+ let MonitorSet::Normal { monitors, .. } = &self.monitor_set else {
+ return true;
+ };
+
+ let (mon, ws_idx) = monitors
+ .iter()
+ .find_map(|mon| {
+ mon.workspaces
+ .iter()
+ .position(|ws| ws.has_window(window))
+ .map(|ws_idx| (mon, ws_idx))
+ })
+ .unwrap();
+
+ // During a gesture, focus-follows-mouse does not cause any unintended workspace switches.
+ if let Some(WorkspaceSwitch::Gesture(_)) = mon.workspace_switch {
+ return true;
+ }
+
+ ws_idx == mon.active_workspace_idx
+ }
+
pub fn activate_window(&mut self, window: &W::Id) {
let MonitorSet::Normal {
monitors,
diff --git a/src/niri.rs b/src/niri.rs
index 7c87ecc5..9e432319 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -4570,6 +4570,10 @@ impl Niri {
if let Some(window) = &new_focus.window {
if current_focus.window.as_ref() != Some(window) {
+ if !self.layout.should_trigger_focus_follows_mouse_on(window) {
+ return;
+ }
+
if let Some(threshold) = ffm.max_scroll_amount {
if self.layout.scroll_amount_to_activate(window) > threshold.0 {
return;