mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-20 16:43:57 +01:00
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:
@@ -57,6 +57,7 @@ pub enum SocketMessage {
|
||||
SendContainerToMonitorWorkspaceNumber(usize, usize),
|
||||
SendContainerToNamedWorkspace(String),
|
||||
MoveWorkspaceToMonitorNumber(usize),
|
||||
SwapWorkspacesToMonitorNumber(usize),
|
||||
ForceFocus,
|
||||
Close,
|
||||
Minimize,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user