mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-07-09 14:42:44 +02: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),
|
SendContainerToMonitorWorkspaceNumber(usize, usize),
|
||||||
SendContainerToNamedWorkspace(String),
|
SendContainerToNamedWorkspace(String),
|
||||||
MoveWorkspaceToMonitorNumber(usize),
|
MoveWorkspaceToMonitorNumber(usize),
|
||||||
|
SwapWorkspacesToMonitorNumber(usize),
|
||||||
ForceFocus,
|
ForceFocus,
|
||||||
Close,
|
Close,
|
||||||
Minimize,
|
Minimize,
|
||||||
|
|||||||
@@ -105,6 +105,10 @@ impl Monitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_workspaces(&mut self) -> VecDeque<Workspace> {
|
||||||
|
self.workspaces_mut().drain(..).collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn move_container_to_workspace(
|
pub fn move_container_to_workspace(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@@ -324,6 +324,9 @@ impl WindowManager {
|
|||||||
SocketMessage::MoveContainerToMonitorNumber(monitor_idx) => {
|
SocketMessage::MoveContainerToMonitorNumber(monitor_idx) => {
|
||||||
self.move_container_to_monitor(monitor_idx, None, true)?;
|
self.move_container_to_monitor(monitor_idx, None, true)?;
|
||||||
}
|
}
|
||||||
|
SocketMessage::SwapWorkspacesToMonitorNumber(monitor_idx) => {
|
||||||
|
self.swap_focused_monitor(monitor_idx)?;
|
||||||
|
}
|
||||||
SocketMessage::CycleMoveContainerToMonitor(direction) => {
|
SocketMessage::CycleMoveContainerToMonitor(direction) => {
|
||||||
let monitor_idx = direction.next_idx(
|
let monitor_idx = direction.next_idx(
|
||||||
self.focused_monitor_idx(),
|
self.focused_monitor_idx(),
|
||||||
|
|||||||
@@ -1000,6 +1000,92 @@ impl WindowManager {
|
|||||||
Ok(())
|
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))]
|
#[tracing::instrument(skip(self))]
|
||||||
pub fn move_container_to_monitor(
|
pub fn move_container_to_monitor(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@@ -154,6 +154,7 @@ gen_target_subcommand_args! {
|
|||||||
FocusWorkspace,
|
FocusWorkspace,
|
||||||
FocusWorkspaces,
|
FocusWorkspaces,
|
||||||
MoveWorkspaceToMonitor,
|
MoveWorkspaceToMonitor,
|
||||||
|
SwapWorkspacesToMonitor,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! gen_named_target_subcommand_args {
|
macro_rules! gen_named_target_subcommand_args {
|
||||||
@@ -807,6 +808,9 @@ enum SubCommand {
|
|||||||
/// Move the focused workspace to the specified monitor
|
/// Move the focused workspace to the specified monitor
|
||||||
#[clap(arg_required_else_help = true)]
|
#[clap(arg_required_else_help = true)]
|
||||||
MoveWorkspaceToMonitor(MoveWorkspaceToMonitor),
|
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
|
/// Create and append a new workspace on the focused monitor
|
||||||
NewWorkspace,
|
NewWorkspace,
|
||||||
/// Set the resize delta (used by resize-edge and resize-axis)
|
/// Set the resize delta (used by resize-edge and resize-axis)
|
||||||
@@ -1192,6 +1196,9 @@ fn main() -> Result<()> {
|
|||||||
SubCommand::MoveWorkspaceToMonitor(arg) => {
|
SubCommand::MoveWorkspaceToMonitor(arg) => {
|
||||||
send_message(&SocketMessage::MoveWorkspaceToMonitorNumber(arg.target).as_bytes()?)?;
|
send_message(&SocketMessage::MoveWorkspaceToMonitorNumber(arg.target).as_bytes()?)?;
|
||||||
}
|
}
|
||||||
|
SubCommand::SwapWorkspacesToMonitor(arg) => {
|
||||||
|
send_message(&SocketMessage::SwapWorkspacesToMonitorNumber(arg.target).as_bytes()?)?;
|
||||||
|
}
|
||||||
SubCommand::InvisibleBorders(arg) => {
|
SubCommand::InvisibleBorders(arg) => {
|
||||||
send_message(
|
send_message(
|
||||||
&SocketMessage::InvisibleBorders(Rect {
|
&SocketMessage::InvisibleBorders(Rect {
|
||||||
|
|||||||
Reference in New Issue
Block a user