feat(wm): add cmd to move ws to other monitors

This commit adds a new komorebic command to move the entire focused
workspace and all managed windows and containers to a target monitor
index. Windows that have been excluded from management using various
rules will not be moved as they are not tracked in the window manager
state.

resolve #88
This commit is contained in:
LGUG2Z
2021-12-31 09:21:47 -08:00
parent 228ef78d7f
commit 39685dd615
7 changed files with 59 additions and 0 deletions
+2
View File
@@ -311,6 +311,7 @@ focus-workspace Focus the specified workspace on the focuse
focus-monitor-workspace Focus the specified workspace on the target monitor focus-monitor-workspace Focus the specified workspace on the target monitor
cycle-monitor Focus the monitor in the given cycle direction cycle-monitor Focus the monitor in the given cycle direction
cycle-workspace Focus the workspace in the given cycle direction cycle-workspace Focus the workspace in the given cycle direction
move-workspace-to-monitor Move the focused workspace to the specified monitor
new-workspace Create and append a new workspace on the focused monitor new-workspace Create and append a new workspace on the focused monitor
resize-delta Set the resize delta (used by resize-edge and resize-axis) resize-delta Set the resize delta (used by resize-edge and resize-axis)
invisible-borders Set the invisible border dimensions around each window invisible-borders Set the invisible border dimensions around each window
@@ -376,6 +377,7 @@ used [is available here](komorebi.sample.with.lib.ahk).
- [x] Move focused window container to workspace follow - [x] Move focused window container to workspace follow
- [x] Send focused window container to monitor - [x] Send focused window container to monitor
- [x] Send focused window container to workspace - [x] Send focused window container to workspace
- [x] Move focused workspace to monitor
- [x] Mouse follows focused container - [x] Mouse follows focused container
- [x] Resize window container in direction - [x] Resize window container in direction
- [x] Resize window container on axis - [x] Resize window container on axis
+1
View File
@@ -47,6 +47,7 @@ pub enum SocketMessage {
MoveContainerToWorkspaceNumber(usize), MoveContainerToWorkspaceNumber(usize),
SendContainerToMonitorNumber(usize), SendContainerToMonitorNumber(usize),
SendContainerToWorkspaceNumber(usize), SendContainerToWorkspaceNumber(usize),
MoveWorkspaceToMonitorNumber(usize),
Promote, Promote,
ToggleFloat, ToggleFloat,
ToggleMonocle, ToggleMonocle,
+14
View File
@@ -68,6 +68,20 @@ impl Monitor {
Ok(()) Ok(())
} }
pub fn remove_workspace_by_idx(&mut self, idx: usize) -> Option<Workspace> {
if idx < self.workspaces().len() {
return self.workspaces_mut().remove(idx);
}
if idx == 0 {
self.workspaces_mut().push_back(Workspace::default());
} else {
self.focus_workspace(idx - 1).ok()?;
};
None
}
pub fn ensure_workspace_count(&mut self, ensure_count: usize) { pub fn ensure_workspace_count(&mut self, ensure_count: usize) {
if self.workspaces().len() < ensure_count { if self.workspaces().len() < ensure_count {
self.workspaces_mut() self.workspaces_mut()
+3
View File
@@ -147,6 +147,9 @@ impl WindowManager {
SocketMessage::SendContainerToMonitorNumber(monitor_idx) => { SocketMessage::SendContainerToMonitorNumber(monitor_idx) => {
self.move_container_to_monitor(monitor_idx, false)?; self.move_container_to_monitor(monitor_idx, false)?;
} }
SocketMessage::MoveWorkspaceToMonitorNumber(monitor_idx) => {
self.move_workspace_to_monitor(monitor_idx)?;
}
SocketMessage::TogglePause => { SocketMessage::TogglePause => {
if self.is_paused { if self.is_paused {
tracing::info!("resuming"); tracing::info!("resuming");
+28
View File
@@ -828,6 +828,34 @@ impl WindowManager {
self.update_focused_workspace(mouse_follows_focus) self.update_focused_workspace(mouse_follows_focus)
} }
pub fn remove_focused_workspace(&mut self) -> Option<Workspace> {
let focused_monitor: &mut Monitor = self.focused_monitor_mut()?;
let focused_workspace_idx = focused_monitor.focused_workspace_idx();
focused_monitor.remove_workspace_by_idx(focused_workspace_idx)
}
#[tracing::instrument(skip(self))]
pub fn move_workspace_to_monitor(&mut self, idx: usize) -> Result<()> {
tracing::info!("moving workspace");
let mouse_follows_focus = self.mouse_follows_focus;
let workspace = self
.remove_focused_workspace()
.ok_or_else(|| anyhow!("there is no workspace"))?;
{
let target_monitor: &mut Monitor = self
.monitors_mut()
.get_mut(idx)
.ok_or_else(|| anyhow!("there is no monitor"))?;
target_monitor.workspaces_mut().push_back(workspace);
target_monitor.focus_workspace(target_monitor.workspaces().len() - 1)?;
target_monitor.load_focused_workspace(mouse_follows_focus)?;
}
self.focus_monitor(idx)?;
self.update_focused_workspace(mouse_follows_focus)
}
#[tracing::instrument(skip(self))] #[tracing::instrument(skip(self))]
pub fn focus_container_in_direction(&mut self, direction: OperationDirection) -> Result<()> { pub fn focus_container_in_direction(&mut self, direction: OperationDirection) -> Result<()> {
+4
View File
@@ -116,6 +116,10 @@ CycleWorkspace(cycle_direction) {
Run, komorebic.exe cycle-workspace %cycle_direction%, , Hide Run, komorebic.exe cycle-workspace %cycle_direction%, , Hide
} }
MoveWorkspaceToMonitor(target) {
Run, komorebic.exe move-workspace-to-monitor %target%, , Hide
}
NewWorkspace() { NewWorkspace() {
Run, komorebic.exe new-workspace, , Hide Run, komorebic.exe new-workspace, , Hide
} }
+7
View File
@@ -114,6 +114,7 @@ gen_target_subcommand_args! {
SendToWorkspace, SendToWorkspace,
FocusMonitor, FocusMonitor,
FocusWorkspace, FocusWorkspace,
MoveWorkspaceToMonitor,
} }
// Thanks to @danielhenrymantilla for showing me how to use cfg_attr with an optional argument like // Thanks to @danielhenrymantilla for showing me how to use cfg_attr with an optional argument like
@@ -445,6 +446,9 @@ enum SubCommand {
/// Focus the workspace in the given cycle direction /// Focus the workspace in the given cycle direction
#[clap(setting = AppSettings::ArgRequiredElseHelp)] #[clap(setting = AppSettings::ArgRequiredElseHelp)]
CycleWorkspace(CycleWorkspace), CycleWorkspace(CycleWorkspace),
/// Move the focused workspace to the specified monitor
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
MoveWorkspaceToMonitor(MoveWorkspaceToMonitor),
/// 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)
@@ -633,6 +637,9 @@ fn main() -> Result<()> {
SubCommand::SendToWorkspace(arg) => { SubCommand::SendToWorkspace(arg) => {
send_message(&*SocketMessage::SendContainerToWorkspaceNumber(arg.target).as_bytes()?)?; send_message(&*SocketMessage::SendContainerToWorkspaceNumber(arg.target).as_bytes()?)?;
} }
SubCommand::MoveWorkspaceToMonitor(arg) => {
send_message(&*SocketMessage::MoveWorkspaceToMonitorNumber(arg.target).as_bytes()?)?;
}
SubCommand::InvisibleBorders(arg) => { SubCommand::InvisibleBorders(arg) => {
send_message( send_message(
&*SocketMessage::InvisibleBorders(Rect { &*SocketMessage::InvisibleBorders(Rect {