From 1a019280f3b185332769dc49def96e68b74c9a3e Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Thu, 27 Feb 2025 18:14:35 +0100 Subject: [PATCH] actions: Remember previous workspace on extended action --- src/input/actions.rs | 116 +++++++++++++++++++++++++++++++++++-------- src/shell/mod.rs | 4 +- 2 files changed, 99 insertions(+), 21 deletions(-) diff --git a/src/input/actions.rs b/src/input/actions.rs index 0d326649..64c064d4 100644 --- a/src/input/actions.rs +++ b/src/input/actions.rs @@ -221,7 +221,7 @@ impl State { time, pattern, direction, - false, + true, ) }; } else { @@ -267,7 +267,7 @@ impl State { time, pattern, direction, - false, + true, ) }; } else { @@ -401,7 +401,7 @@ impl State { time, pattern, direction, - false, + true, ) } } @@ -484,7 +484,7 @@ impl State { time, pattern, direction, - false, + true, ) } } @@ -514,14 +514,35 @@ impl State { let next_output = shell.next_output(¤t_output, direction).cloned(); if let Some(next_output) = next_output { - let idx = shell.workspaces.active_num(&next_output).1; - let res = shell.activate( - &next_output, - idx, - WorkspaceDelta::new_shortcut(), - &mut self.common.workspace_state.update(), - ); - seat.set_active_output(&next_output); + let res = { + let mut workspace_guard = self.common.workspace_state.update(); + if propagate { + if let Some((serial, prev_output, prev_idx)) = + shell.previous_workspace_idx.take() + { + if seat.last_modifier_change().is_some_and(|s| s == serial) + && prev_output == current_output + { + let _ = shell.activate( + ¤t_output, + prev_idx, + WorkspaceDelta::new_shortcut(), + &mut workspace_guard, + ); + } + } + } + + let idx = shell.workspaces.active_num(&next_output).1; + let res = shell.activate( + &next_output, + idx, + WorkspaceDelta::new_shortcut(), + &mut workspace_guard, + ); + seat.set_active_output(&next_output); + res + }; if let Ok(Some(new_pos)) = res { let new_target = shell @@ -585,14 +606,34 @@ impl State { let next_output = shell.next_output(&focused_output, direction).cloned(); if let Some(next_output) = next_output { - let res = shell.move_current_window( - seat, - &focused_output, - (&next_output, None), - is_move_action, - Some(direction), - &mut self.common.workspace_state.update(), - ); + let res = { + let mut workspace_guard = self.common.workspace_state.update(); + let res = shell.move_current_window( + seat, + &focused_output, + (&next_output, None), + is_move_action, + Some(direction), + &mut workspace_guard, + ); + + if is_move_action && propagate { + if let Some((_, prev_output, prev_idx)) = + shell.previous_workspace_idx.take() + { + if prev_output == focused_output { + let _ = shell.activate( + &focused_output, + prev_idx, + WorkspaceDelta::new_shortcut(), + &mut workspace_guard, + ); + } + } + } + res + }; + if let Ok(Some((target, new_pos))) = res { std::mem::drop(shell); Shell::set_focus(self, Some(&target), seat, None, is_move_action); @@ -659,6 +700,24 @@ impl State { }; if let Some(direction) = dir { + if let Some(last_mod_serial) = seat.last_modifier_change() { + let mut shell = self.common.shell.write().unwrap(); + if !shell + .previous_workspace_idx + .as_ref() + .is_some_and(|(serial, _, _)| *serial == last_mod_serial) + { + let current_output = seat.active_output(); + let workspace_idx = + shell.workspaces.active_num(¤t_output).1; + shell.previous_workspace_idx = Some(( + last_mod_serial, + current_output.downgrade(), + workspace_idx, + )); + } + } + let action = match ( direction, self.common.config.cosmic_conf.workspaces.workspace_layout, @@ -701,6 +760,23 @@ impl State { .move_current_element(direction, seat); match res { MoveResult::MoveFurther(_move_further) => { + if let Some(last_mod_serial) = seat.last_modifier_change() { + let mut shell = self.common.shell.write().unwrap(); + if !shell + .previous_workspace_idx + .as_ref() + .is_some_and(|(serial, _, _)| *serial == last_mod_serial) + { + let current_output = seat.active_output(); + let workspace_idx = shell.workspaces.active_num(¤t_output).1; + shell.previous_workspace_idx = Some(( + last_mod_serial, + current_output.downgrade(), + workspace_idx, + )); + } + } + let action = match ( direction, self.common.config.cosmic_conf.workspaces.workspace_layout, diff --git a/src/shell/mod.rs b/src/shell/mod.rs index 98af0027..65838b10 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -36,7 +36,7 @@ use smithay::{ }, Seat, }, - output::Output, + output::{Output, WeakOutput}, reexports::{ wayland_protocols::ext::{ session_lock::v1::server::ext_session_lock_v1::ExtSessionLockV1, @@ -257,6 +257,7 @@ pub struct Shell { pub override_redirect_windows: Vec, pub session_lock: Option, pub seats: Seats, + pub previous_workspace_idx: Option<(Serial, WeakOutput, usize)>, theme: cosmic::Theme, pub active_hint: bool, @@ -1344,6 +1345,7 @@ impl Shell { pending_activations: HashMap::new(), override_redirect_windows: Vec::new(), session_lock: None, + previous_workspace_idx: None, theme, active_hint: config.cosmic_conf.active_hint,