From 3d53c602a7bfbbdab8a31b58a38425d58823b3a9 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Tue, 14 May 2024 14:39:37 -0700 Subject: [PATCH] feat(wm): single_window -> window_based offset This commit updates the initial design of single_window_work_area_offset to window_based_work_area_offset where the user can set window_based_work_area_offset_limit to determine the limit of windows on the screen that this offset should apply to. By default this is 1, and in the most extreme case of someone using a super ultrawide monitor this might be 2. --- komorebi/src/monitor.rs | 15 ++++++++--- komorebi/src/process_event.rs | 8 ++++-- komorebi/src/static_config.rs | 20 ++++++++++---- komorebi/src/window_manager.rs | 48 +++++++++++++++++++++++++--------- komorebi/src/workspace.rs | 9 ++++--- 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/komorebi/src/monitor.rs b/komorebi/src/monitor.rs index 820b6574b..74a38d640 100644 --- a/komorebi/src/monitor.rs +++ b/komorebi/src/monitor.rs @@ -37,7 +37,9 @@ pub struct Monitor { #[getset(get_copy = "pub", set = "pub")] work_area_offset: Option, #[getset(get_copy = "pub", set = "pub")] - single_window_work_area_offset: Option, + window_based_work_area_offset: Option, + #[getset(get_copy = "pub", set = "pub")] + window_based_work_area_offset_limit: isize, workspaces: Ring, #[serde(skip_serializing_if = "Option::is_none")] #[getset(get_copy = "pub", set = "pub")] @@ -60,7 +62,8 @@ pub fn new(id: isize, size: Rect, work_area_size: Rect, name: String) -> Monitor size, work_area_size, work_area_offset: None, - single_window_work_area_offset: None, + window_based_work_area_offset: None, + window_based_work_area_offset_limit: 1, workspaces, last_focused_workspace: None, workspace_names: HashMap::default(), @@ -197,7 +200,11 @@ impl Monitor { pub fn update_focused_workspace(&mut self, offset: Option) -> Result<()> { let work_area = *self.work_area_size(); - let single_window_work_area_offset = self.single_window_work_area_offset(); + let window_based_work_area_offset = ( + self.window_based_work_area_offset_limit(), + self.window_based_work_area_offset(), + ); + let offset = if self.work_area_offset().is_some() { self.work_area_offset() } else { @@ -206,7 +213,7 @@ impl Monitor { self.focused_workspace_mut() .ok_or_else(|| anyhow!("there is no workspace"))? - .update(&work_area, offset, single_window_work_area_offset)?; + .update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } diff --git a/komorebi/src/process_event.rs b/komorebi/src/process_event.rs index f5e65c912..e4d67b9dd 100644 --- a/komorebi/src/process_event.rs +++ b/komorebi/src/process_event.rs @@ -126,7 +126,11 @@ impl WindowManager { for (i, monitor) in self.monitors_mut().iter_mut().enumerate() { let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() } else { @@ -140,7 +144,7 @@ impl WindowManager { let reaped_orphans = workspace.reap_orphans()?; if reaped_orphans.0 > 0 || reaped_orphans.1 > 0 { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; tracing::info!( "reaped {} orphan window(s) and {} orphaned container(s) on monitor: {}, workspace: {}", reaped_orphans.0, diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 1a6e76f0d..af4ebb86c 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -201,9 +201,12 @@ pub struct MonitorConfig { /// Monitor-specific work area offset (default: None) #[serde(skip_serializing_if = "Option::is_none")] pub work_area_offset: Option, - /// Single window work area offset (default: None) + /// Window based work area offset (default: None) #[serde(skip_serializing_if = "Option::is_none")] - pub single_window_work_area_offset: Option, + pub window_based_work_area_offset: Option, + /// Open window limit after which the window based work area offset will no longer be applied (default: 1) + #[serde(skip_serializing_if = "Option::is_none")] + pub window_based_work_area_offset_limit: Option, } impl From<&Monitor> for MonitorConfig { @@ -216,7 +219,8 @@ impl From<&Monitor> for MonitorConfig { Self { workspaces, work_area_offset: value.work_area_offset(), - single_window_work_area_offset: value.single_window_work_area_offset(), + window_based_work_area_offset: value.window_based_work_area_offset(), + window_based_work_area_offset_limit: Some(value.window_based_work_area_offset_limit()), } } } @@ -698,7 +702,10 @@ impl StaticConfig { if let Some(m) = wm.monitors_mut().get_mut(i) { m.ensure_workspace_count(monitor.workspaces.len()); m.set_work_area_offset(monitor.work_area_offset); - m.set_single_window_work_area_offset(monitor.single_window_work_area_offset); + m.set_window_based_work_area_offset(monitor.window_based_work_area_offset); + m.set_window_based_work_area_offset_limit( + monitor.window_based_work_area_offset_limit.unwrap_or(1), + ); for (j, ws) in m.workspaces_mut().iter_mut().enumerate() { ws.load_static_config( @@ -754,7 +761,10 @@ impl StaticConfig { if let Some(m) = wm.monitors_mut().get_mut(i) { m.ensure_workspace_count(monitor.workspaces.len()); m.set_work_area_offset(monitor.work_area_offset); - m.set_single_window_work_area_offset(monitor.single_window_work_area_offset); + m.set_window_based_work_area_offset(monitor.window_based_work_area_offset); + m.set_window_based_work_area_offset_limit( + monitor.window_based_work_area_offset_limit.unwrap_or(1), + ); for (j, ws) in m.workspaces_mut().iter_mut().enumerate() { ws.load_static_config( diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index cf9f0e177..32875d303 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -713,7 +713,11 @@ impl WindowManager { for monitor in self.monitors_mut() { let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() } else { @@ -731,7 +735,7 @@ impl WindowManager { } } - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; } Ok(()) @@ -1944,7 +1948,11 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no monitor"))?; let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let focused_workspace_idx = monitor.focused_workspace_idx(); let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() @@ -1964,7 +1972,7 @@ impl WindowManager { // If this is the focused workspace on a non-focused screen, let's update it if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } else { Ok(self.update_focused_workspace(false, false)?) @@ -1993,7 +2001,11 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no monitor"))?; let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let focused_workspace_idx = monitor.focused_workspace_idx(); let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() @@ -2015,7 +2027,7 @@ impl WindowManager { // If this is the focused workspace on a non-focused screen, let's update it if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } else { Ok(self.update_focused_workspace(false, false)?) @@ -2039,7 +2051,11 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no monitor"))?; let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let focused_workspace_idx = monitor.focused_workspace_idx(); let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() @@ -2057,7 +2073,7 @@ impl WindowManager { // If this is the focused workspace on a non-focused screen, let's update it if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } else { Ok(self.update_focused_workspace(false, false)?) @@ -2082,7 +2098,11 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no monitor"))?; let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let focused_workspace_idx = monitor.focused_workspace_idx(); let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() @@ -2099,7 +2119,7 @@ impl WindowManager { // If this is the focused workspace on a non-focused screen, let's update it if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } else { Ok(self.update_focused_workspace(false, false)?) @@ -2127,7 +2147,11 @@ impl WindowManager { .ok_or_else(|| anyhow!("there is no monitor"))?; let work_area = *monitor.work_area_size(); - let single_window_work_area_offset = monitor.single_window_work_area_offset(); + let window_based_work_area_offset = ( + monitor.window_based_work_area_offset_limit(), + monitor.window_based_work_area_offset(), + ); + let focused_workspace_idx = monitor.focused_workspace_idx(); let offset = if monitor.work_area_offset().is_some() { monitor.work_area_offset() @@ -2145,7 +2169,7 @@ impl WindowManager { // If this is the focused workspace on a non-focused screen, let's update it if focused_monitor_idx != monitor_idx && focused_workspace_idx == workspace_idx { - workspace.update(&work_area, offset, single_window_work_area_offset)?; + workspace.update(&work_area, offset, window_based_work_area_offset)?; Ok(()) } else { Ok(self.update_focused_workspace(false, false)?) diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index a5282e2d7..37bb78636 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -223,12 +223,15 @@ impl Workspace { &mut self, work_area: &Rect, work_area_offset: Option, - single_window_work_area_offset: Option, + window_based_work_area_offset: (isize, Option), ) -> Result<()> { if !INITIAL_CONFIGURATION_LOADED.load(Ordering::SeqCst) { return Ok(()); } + let (window_based_work_area_offset_limit, window_based_work_area_offset) = + window_based_work_area_offset; + let container_padding = self.container_padding(); let mut adjusted_work_area = work_area_offset.map_or_else( || *work_area, @@ -243,8 +246,8 @@ impl Workspace { }, ); - if self.containers().len() == 1 { - adjusted_work_area = single_window_work_area_offset.map_or_else( + if self.containers().len() <= window_based_work_area_offset_limit as usize { + adjusted_work_area = window_based_work_area_offset.map_or_else( || adjusted_work_area, |offset| { let mut with_offset = adjusted_work_area;