diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index ea0b0d755..08d7281bc 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -105,6 +105,7 @@ pub enum SocketMessage { ActiveWindowBorderColour(WindowKind, u32, u32, u32), InvisibleBorders(Rect), WorkAreaOffset(Rect), + MonitorWorkAreaOffset(usize, Rect), ResizeDelta(i32), WorkspaceRule(ApplicationIdentifier, String, usize, usize), FloatRule(ApplicationIdentifier, String), diff --git a/komorebi/src/monitor.rs b/komorebi/src/monitor.rs index 80aebcb11..2d5252158 100644 --- a/komorebi/src/monitor.rs +++ b/komorebi/src/monitor.rs @@ -26,6 +26,8 @@ pub struct Monitor { size: Rect, #[getset(get = "pub", set = "pub")] work_area_size: Rect, + #[getset(get_copy = "pub", set = "pub")] + work_area_offset: Option, workspaces: Ring, #[serde(skip_serializing)] #[getset(get_mut = "pub")] @@ -43,6 +45,7 @@ pub fn new(id: isize, size: Rect, work_area_size: Rect, name: String) -> Monitor name, size, work_area_size, + work_area_offset: None, workspaces, workspace_names: HashMap::default(), } @@ -179,6 +182,11 @@ impl Monitor { invisible_borders: &Rect, ) -> Result<()> { let work_area = *self.work_area_size(); + let offset = if self.work_area_offset().is_some() { + self.work_area_offset() + } else { + offset + }; self.focused_workspace_mut() .ok_or_else(|| anyhow!("there is no workspace"))? diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 0888ed40d..b2cef3455 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -709,6 +709,12 @@ impl WindowManager { self.work_area_offset = Option::from(rect); self.retile_all(false)?; } + SocketMessage::MonitorWorkAreaOffset(monitor_idx, rect) => { + if let Some(monitor) = self.monitors_mut().get_mut(monitor_idx) { + monitor.set_work_area_offset(Option::from(rect)); + self.retile_all(false)?; + } + } SocketMessage::QuickSave => { let workspace = self.focused_workspace()?; let resize = workspace.resize_dimensions(); diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index 60abc0dca..7ce0197d5 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -109,6 +109,12 @@ impl WindowManager { for (i, monitor) in self.monitors_mut().iter_mut().enumerate() { let work_area = *monitor.work_area_size(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; + for (j, workspace) in monitor.workspaces_mut().iter_mut().enumerate() { let reaped_orphans = workspace.reap_orphans()?; if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 { diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index e74c46974..64291473c 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -599,6 +599,12 @@ impl WindowManager { for monitor in self.monitors_mut() { let work_area = *monitor.work_area_size(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; + let workspace = monitor .focused_workspace_mut() .ok_or_else(|| anyhow!("there is no workspace"))?; @@ -1650,6 +1656,11 @@ impl WindowManager { let work_area = *monitor.work_area_size(); let focused_workspace_idx = monitor.focused_workspace_idx(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; let workspace = monitor .workspaces_mut() @@ -1691,6 +1702,11 @@ impl WindowManager { let work_area = *monitor.work_area_size(); let focused_workspace_idx = monitor.focused_workspace_idx(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; let workspace = monitor .workspaces_mut() @@ -1732,6 +1748,11 @@ impl WindowManager { let work_area = *monitor.work_area_size(); let focused_workspace_idx = monitor.focused_workspace_idx(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; let workspace = monitor .workspaces_mut() @@ -1770,6 +1791,11 @@ impl WindowManager { let work_area = *monitor.work_area_size(); let focused_workspace_idx = monitor.focused_workspace_idx(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; let workspace = monitor .workspaces_mut() @@ -1807,6 +1833,11 @@ impl WindowManager { let work_area = *monitor.work_area_size(); let focused_workspace_idx = monitor.focused_workspace_idx(); + let offset = if monitor.work_area_offset().is_some() { + monitor.work_area_offset() + } else { + offset + }; let workspace = monitor .workspaces_mut() diff --git a/komorebic.lib.ahk b/komorebic.lib.ahk index a3b21027e..d9e97adc2 100644 --- a/komorebic.lib.ahk +++ b/komorebic.lib.ahk @@ -144,8 +144,12 @@ InvisibleBorders(left, top, right, bottom) { RunWait, komorebic.exe invisible-borders %left% %top% %right% %bottom%, , Hide } -WorkAreaOffset(left, top, right, bottom) { - RunWait, komorebic.exe work-area-offset %left% %top% %right% %bottom%, , Hide +GlobalWorkAreaOffset(left, top, right, bottom) { + RunWait, komorebic.exe global-work-area-offset %left% %top% %right% %bottom%, , Hide +} + +MonitorWorkAreaOffset(monitor, left, top, right, bottom) { + RunWait, komorebic.exe monitor-work-area-offset %monitor% %left% %top% %right% %bottom%, , Hide } AdjustContainerPadding(sizing, adjustment) { diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 071554624..47735d2fc 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -268,7 +268,21 @@ struct InvisibleBorders { } #[derive(Parser, AhkFunction)] -struct WorkAreaOffset { +struct GlobalWorkAreaOffset { + /// Size of the left work area offset (set right to left * 2 to maintain right padding) + left: i32, + /// Size of the top work area offset (set bottom to the same value to maintain bottom padding) + top: i32, + /// Size of the right work area offset + right: i32, + /// Size of the bottom work area offset + bottom: i32, +} + +#[derive(Parser, AhkFunction)] +struct MonitorWorkAreaOffset { + /// Monitor index (zero-indexed) + monitor: usize, /// Size of the left work area offset (set right to left * 2 to maintain right padding) left: i32, /// Size of the top work area offset (set bottom to the same value to maintain bottom padding) @@ -598,7 +612,11 @@ enum SubCommand { InvisibleBorders(InvisibleBorders), /// Set offsets to exclude parts of the work area from tiling #[clap(arg_required_else_help = true)] - WorkAreaOffset(WorkAreaOffset), + #[clap(alias = "global-work-area-offset")] + GlobalWorkAreaOffset(GlobalWorkAreaOffset), + /// Set offsets for a monitor to exclude parts of the work area from tiling + #[clap(arg_required_else_help = true)] + MonitorWorkAreaOffset(MonitorWorkAreaOffset), /// Adjust container padding on the focused workspace #[clap(arg_required_else_help = true)] AdjustContainerPadding(AdjustContainerPadding), @@ -857,7 +875,21 @@ fn main() -> Result<()> { .as_bytes()?, )?; } - SubCommand::WorkAreaOffset(arg) => { + SubCommand::MonitorWorkAreaOffset(arg) => { + send_message( + &SocketMessage::MonitorWorkAreaOffset( + arg.monitor, + Rect { + left: arg.left, + top: arg.top, + right: arg.right, + bottom: arg.bottom, + }, + ) + .as_bytes()?, + )?; + } + SubCommand::GlobalWorkAreaOffset(arg) => { send_message( &SocketMessage::WorkAreaOffset(Rect { left: arg.left,