Skip to content

Commit

Permalink
feat(wm): add cmd to move ws to other monitors
Browse files Browse the repository at this point in the history
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
  • Loading branch information
LGUG2Z committed Jan 7, 2022
1 parent 228ef78 commit 39685dd
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@ focus-workspace Focus the specified workspace on the focuse
focus-monitor-workspace Focus the specified workspace on the target monitor
cycle-monitor Focus the monitor 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
resize-delta Set the resize delta (used by resize-edge and resize-axis)
invisible-borders Set the invisible border dimensions around each window
Expand Down Expand Up @@ -376,6 +377,7 @@ used [is available here](komorebi.sample.with.lib.ahk).
- [x] Move focused window container to workspace follow
- [x] Send focused window container to monitor
- [x] Send focused window container to workspace
- [x] Move focused workspace to monitor
- [x] Mouse follows focused container
- [x] Resize window container in direction
- [x] Resize window container on axis
Expand Down
1 change: 1 addition & 0 deletions komorebi-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum SocketMessage {
MoveContainerToWorkspaceNumber(usize),
SendContainerToMonitorNumber(usize),
SendContainerToWorkspaceNumber(usize),
MoveWorkspaceToMonitorNumber(usize),
Promote,
ToggleFloat,
ToggleMonocle,
Expand Down
14 changes: 14 additions & 0 deletions komorebi/src/monitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,20 @@ impl Monitor {
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) {
if self.workspaces().len() < ensure_count {
self.workspaces_mut()
Expand Down
3 changes: 3 additions & 0 deletions komorebi/src/process_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ impl WindowManager {
SocketMessage::SendContainerToMonitorNumber(monitor_idx) => {
self.move_container_to_monitor(monitor_idx, false)?;
}
SocketMessage::MoveWorkspaceToMonitorNumber(monitor_idx) => {
self.move_workspace_to_monitor(monitor_idx)?;
}
SocketMessage::TogglePause => {
if self.is_paused {
tracing::info!("resuming");
Expand Down
28 changes: 28 additions & 0 deletions komorebi/src/window_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -828,6 +828,34 @@ impl WindowManager {

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))]
pub fn focus_container_in_direction(&mut self, direction: OperationDirection) -> Result<()> {
Expand Down
4 changes: 4 additions & 0 deletions komorebic.lib.sample.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ CycleWorkspace(cycle_direction) {
Run, komorebic.exe cycle-workspace %cycle_direction%, , Hide
}

MoveWorkspaceToMonitor(target) {
Run, komorebic.exe move-workspace-to-monitor %target%, , Hide
}

NewWorkspace() {
Run, komorebic.exe new-workspace, , Hide
}
Expand Down
7 changes: 7 additions & 0 deletions komorebic/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ gen_target_subcommand_args! {
SendToWorkspace,
FocusMonitor,
FocusWorkspace,
MoveWorkspaceToMonitor,
}

// Thanks to @danielhenrymantilla for showing me how to use cfg_attr with an optional argument like
Expand Down Expand Up @@ -445,6 +446,9 @@ enum SubCommand {
/// Focus the workspace in the given cycle direction
#[clap(setting = AppSettings::ArgRequiredElseHelp)]
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
NewWorkspace,
/// Set the resize delta (used by resize-edge and resize-axis)
Expand Down Expand Up @@ -633,6 +637,9 @@ fn main() -> Result<()> {
SubCommand::SendToWorkspace(arg) => {
send_message(&*SocketMessage::SendContainerToWorkspaceNumber(arg.target).as_bytes()?)?;
}
SubCommand::MoveWorkspaceToMonitor(arg) => {
send_message(&*SocketMessage::MoveWorkspaceToMonitorNumber(arg.target).as_bytes()?)?;
}
SubCommand::InvisibleBorders(arg) => {
send_message(
&*SocketMessage::InvisibleBorders(Rect {
Expand Down

0 comments on commit 39685dd

Please sign in to comment.