aboutsummaryrefslogtreecommitdiff
path: root/src/app/actions.rs
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-04-04 01:50:43 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-04-04 01:50:43 +0300
commit951fb1d88be721461783a239c152cf143d741dc4 (patch)
tree32f2946a53f30fd50b9523bf9490f13f330a309d /src/app/actions.rs
parent831894facfc1339f819b42c3339668154121d24f (diff)
feat: add mouse drag reordering for workspaces
Diffstat (limited to 'src/app/actions.rs')
-rw-r--r--src/app/actions.rs62
1 files changed, 62 insertions, 0 deletions
diff --git a/src/app/actions.rs b/src/app/actions.rs
index 88366ce8..41db6f1f 100644
--- a/src/app/actions.rs
+++ b/src/app/actions.rs
@@ -138,6 +138,32 @@ impl AppState {
}
}
+ pub fn move_workspace(&mut self, source_idx: usize, insert_idx: usize) {
+ if source_idx >= self.workspaces.len() || insert_idx > self.workspaces.len() {
+ return;
+ }
+
+ let active_id = self.active.map(|idx| self.workspaces[idx].id.clone());
+ let selected_id = self
+ .workspaces
+ .get(self.selected)
+ .map(|workspace| workspace.id.clone());
+
+ let workspace = self.workspaces.remove(source_idx);
+ let target_idx = if source_idx < insert_idx {
+ insert_idx.saturating_sub(1)
+ } else {
+ insert_idx
+ }
+ .min(self.workspaces.len());
+ self.workspaces.insert(target_idx, workspace);
+
+ self.active = active_id.and_then(|id| self.workspaces.iter().position(|ws| ws.id == id));
+ self.selected = selected_id
+ .and_then(|id| self.workspaces.iter().position(|ws| ws.id == id))
+ .unwrap_or(0);
+ }
+
pub fn next_tab(&mut self) {
if let Some(ws) = self.active.and_then(|i| self.workspaces.get_mut(i)) {
if !ws.tabs.is_empty() {
@@ -536,6 +562,42 @@ mod tests {
}
#[test]
+ fn move_workspace_reorders_without_changing_logical_selection() {
+ let mut state = app_with_workspaces(&["a", "b", "c"]);
+ let active_id = state.workspaces[1].id.clone();
+ let selected_id = state.workspaces[2].id.clone();
+ state.active = Some(1);
+ state.selected = 2;
+
+ state.move_workspace(1, 0);
+
+ let names: Vec<_> = state
+ .workspaces
+ .iter()
+ .map(|ws| ws.display_name())
+ .collect();
+ assert_eq!(names, vec!["b", "a", "c"]);
+ assert_eq!(state.active, Some(0));
+ assert_eq!(state.selected, 2);
+ assert_eq!(state.workspaces[state.active.unwrap()].id, active_id);
+ assert_eq!(state.workspaces[state.selected].id, selected_id);
+ }
+
+ #[test]
+ fn move_workspace_accepts_insert_at_end() {
+ let mut state = app_with_workspaces(&["a", "b", "c"]);
+
+ state.move_workspace(0, state.workspaces.len());
+
+ let names: Vec<_> = state
+ .workspaces
+ .iter()
+ .map(|ws| ws.display_name())
+ .collect();
+ assert_eq!(names, vec!["b", "c", "a"]);
+ }
+
+ #[test]
fn close_workspace_adjusts_indices() {
let mut state = app_with_workspaces(&["a", "b", "c"]);
state.selected = 1;