Skip to content

Commit

Permalink
shell: Add keybindings to migrate workspaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Nov 21, 2023
1 parent 1a2d915 commit 3dee249
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 5 deletions.
4 changes: 4 additions & 0 deletions src/config/key_bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ pub enum Action {
MoveToOutput(Direction),
SendToOutput(Direction),

MigrateWorkspaceToNextOutput,
MigrateWorkspaceToPreviousOutput,
MigrateWorkspaceToOutput(Direction),

Focus(FocusDirection),
Move(Direction),

Expand Down
50 changes: 50 additions & 0 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1633,6 +1633,56 @@ impl State {
}
}
}
Action::MigrateWorkspaceToNextOutput => {
let current_output = seat.active_output();
let active = self.common.shell.active_space(&current_output).handle;
let next_output = self
.common
.shell
.outputs()
.skip_while(|o| *o != &current_output)
.skip(1)
.next()
.cloned();
if let Some(next_output) = next_output {
self.common
.shell
.migrate_workspace(&current_output, &next_output, &active);
}
}
Action::MigrateWorkspaceToPreviousOutput => {
let current_output = seat.active_output();
let active = self.common.shell.active_space(&current_output).handle;
let prev_output = self
.common
.shell
.outputs()
.rev()
.skip_while(|o| *o != &current_output)
.skip(1)
.next()
.cloned();
if let Some(prev_output) = prev_output {
self.common
.shell
.migrate_workspace(&current_output, &prev_output, &active);
}
}
Action::MigrateWorkspaceToOutput(direction) => {
let current_output = seat.active_output();
let active = self.common.shell.active_space(&current_output).handle;
let next_output = self
.common
.shell
.next_output(&current_output, direction)
.cloned();

if let Some(next_output) = next_output {
self.common
.shell
.migrate_workspace(&current_output, &next_output, &active);
}
}
Action::Focus(focus) => {
let current_output = seat.active_output();
let overview = self.common.shell.overview_mode().0;
Expand Down
66 changes: 61 additions & 5 deletions src/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,18 +633,18 @@ impl Workspaces {
toplevel_info_state,
);
} else {
// update workspace protocol state
// update workspace protocol state
move_workspace_to_group(
&mut workspace,
&workspace_group,
workspace_state,
toplevel_info_state,
);

// update mapping
workspace.set_output(&new_output, toplevel_info_state);
workspace.refresh(xdg_activation_state);
new_set.workspaces.push(workspace);
// update mapping
workspace.set_output(&new_output, toplevel_info_state);
workspace.refresh(xdg_activation_state);
new_set.workspaces.push(workspace);
}
}
if self.mode == WorkspaceMode::OutputBound {
Expand All @@ -665,6 +665,46 @@ impl Workspaces {
}
}

fn migrate_workspace(
&mut self,
from: &Output,
to: &Output,
handle: &WorkspaceHandle,
workspace_state: &mut WorkspaceUpdateGuard<'_, State>,
toplevel_info_state: &mut ToplevelInfoState<State, CosmicSurface>,
xdg_activation_state: &XdgActivationState,
) {
if !self.sets.contains_key(to) {
return;
}

if let Some(mut workspace) = self.sets.get_mut(from).and_then(|set| {
let pos = set.workspaces.iter().position(|w| &w.handle == handle)?;
Some(set.workspaces.remove(pos))
}) {
let new_set = self.sets.get_mut(to).unwrap();
match self.amount {
WorkspaceAmount::Dynamic => {
move_workspace_to_group(
&mut workspace,
&new_set.group,
workspace_state,
toplevel_info_state,
);
workspace.set_output(to, toplevel_info_state);
workspace.refresh(xdg_activation_state);
new_set.workspaces.insert(new_set.active + 1, workspace)
}
WorkspaceAmount::Static(_) => merge_workspaces(
workspace,
&mut new_set.workspaces[new_set.active],
workspace_state,
toplevel_info_state,
),
};
}
}

pub fn update_config(
&mut self,
config: &Config,
Expand Down Expand Up @@ -1013,6 +1053,22 @@ impl Shell {
self.refresh(); // cleans up excess of workspaces and empty workspaces
}

pub fn migrate_workspace(&mut self, from: &Output, to: &Output, handle: &WorkspaceHandle) {
if from == to {
return;
}

self.workspaces.migrate_workspace(
from,
to,
handle,
&mut self.workspace_state.update(),
&mut self.toplevel_info_state,
&self.xdg_activation_state,
);
self.refresh(); // fixes index of moved workspace
}

pub fn update_config(&mut self, config: &Config) {
let mut workspace_state = self.workspace_state.update();
let toplevel_info_state = &mut self.toplevel_info_state;
Expand Down

0 comments on commit 3dee249

Please sign in to comment.