feat(swap-workspaces-monitor): command to swap focused monitor workspaces with another monitor

Basically this commit adds a command that allows you to swap two monitors, well it actually swaps
the workspaces between the monitors.
This commit is contained in:
Yusuf007R
2023-06-08 21:37:04 -05:00
committed by جاد
parent 647f5b7ded
commit 6fe2290d74
5 changed files with 101 additions and 0 deletions

View File

@@ -57,6 +57,7 @@ pub enum SocketMessage {
SendContainerToMonitorWorkspaceNumber(usize, usize),
SendContainerToNamedWorkspace(String),
MoveWorkspaceToMonitorNumber(usize),
SwapWorkspacesToMonitorNumber(usize),
ForceFocus,
Close,
Minimize,

View File

@@ -105,6 +105,10 @@ impl Monitor {
}
}
pub fn remove_workspaces(&mut self) -> VecDeque<Workspace> {
self.workspaces_mut().drain(..).collect()
}
#[tracing::instrument(skip(self))]
pub fn move_container_to_workspace(
&mut self,

View File

@@ -324,6 +324,9 @@ impl WindowManager {
SocketMessage::MoveContainerToMonitorNumber(monitor_idx) => {
self.move_container_to_monitor(monitor_idx, None, true)?;
}
SocketMessage::SwapWorkspacesToMonitorNumber(monitor_idx) => {
self.swap_focused_monitor(monitor_idx)?;
}
SocketMessage::CycleMoveContainerToMonitor(direction) => {
let monitor_idx = direction.next_idx(
self.focused_monitor_idx(),

View File

@@ -1000,6 +1000,92 @@ impl WindowManager {
Ok(())
}
pub fn update_focused_workspace_by_monitor_idx(&mut self, idx: usize) -> Result<()> {
let invisible_borders = self.invisible_borders;
let offset = self.work_area_offset;
self.monitors_mut()
.get_mut(idx)
.ok_or_else(|| anyhow!("there is no monitor"))?
.update_focused_workspace(offset, &invisible_borders)
}
#[tracing::instrument(skip(self))]
pub fn swap_monitor_workspaces(&mut self, first_idx: usize, second_idx: usize) -> Result<()> {
tracing::info!("swaping monitors");
if first_idx == second_idx {
return Ok(());
}
let mouse_follows_focus = self.mouse_follows_focus;
let first_focused_workspace = {
let first_monitor = self
.monitors()
.get(first_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?;
first_monitor.focused_workspace_idx()
};
let second_focused_workspace = {
let second_monitor = self
.monitors()
.get(second_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?;
second_monitor.focused_workspace_idx()
};
// Swap workspaces between the first and second monitors
let first_workspaces = self
.monitors_mut()
.get_mut(first_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?
.remove_workspaces();
let second_workspaces = self
.monitors_mut()
.get_mut(second_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?
.remove_workspaces();
self.monitors_mut()
.get_mut(first_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?
.workspaces_mut()
.extend(second_workspaces);
self.monitors_mut()
.get_mut(second_idx)
.ok_or_else(|| anyhow!("There is no monitor"))?
.workspaces_mut()
.extend(first_workspaces);
// Set the focused workspaces for the first and second monitors
if let Some(first_monitor) = self.monitors_mut().get_mut(first_idx) {
first_monitor.focus_workspace(second_focused_workspace)?;
first_monitor.load_focused_workspace(mouse_follows_focus)?;
}
if let Some(second_monitor) = self.monitors_mut().get_mut(second_idx) {
second_monitor.focus_workspace(first_focused_workspace)?;
second_monitor.load_focused_workspace(mouse_follows_focus)?;
}
self.update_focused_workspace_by_monitor_idx(second_idx)?;
self.update_focused_workspace_by_monitor_idx(first_idx)
}
#[tracing::instrument(skip(self))]
pub fn swap_focused_monitor(&mut self, idx: usize) -> Result<()> {
tracing::info!("swapping focused monitor");
let focused_monitor_idx = self.focused_monitor_idx();
let mouse_follows_focus = self.mouse_follows_focus;
self.swap_monitor_workspaces(focused_monitor_idx, idx)?;
self.update_focused_workspace(mouse_follows_focus)
}
#[tracing::instrument(skip(self))]
pub fn move_container_to_monitor(
&mut self,

View File

@@ -154,6 +154,7 @@ gen_target_subcommand_args! {
FocusWorkspace,
FocusWorkspaces,
MoveWorkspaceToMonitor,
SwapWorkspacesToMonitor,
}
macro_rules! gen_named_target_subcommand_args {
@@ -807,6 +808,9 @@ enum SubCommand {
/// Move the focused workspace to the specified monitor
#[clap(arg_required_else_help = true)]
MoveWorkspaceToMonitor(MoveWorkspaceToMonitor),
/// Swap focused monitior workspaces with specified monitor
#[clap(arg_required_else_help = true)]
SwapWorkspacesToMonitor(SwapWorkspacesToMonitor),
/// Create and append a new workspace on the focused monitor
NewWorkspace,
/// Set the resize delta (used by resize-edge and resize-axis)
@@ -1192,6 +1196,9 @@ fn main() -> Result<()> {
SubCommand::MoveWorkspaceToMonitor(arg) => {
send_message(&SocketMessage::MoveWorkspaceToMonitorNumber(arg.target).as_bytes()?)?;
}
SubCommand::SwapWorkspacesToMonitor(arg) => {
send_message(&SocketMessage::SwapWorkspacesToMonitorNumber(arg.target).as_bytes()?)?;
}
SubCommand::InvisibleBorders(arg) => {
send_message(
&SocketMessage::InvisibleBorders(Rect {