diff --git a/komorebi/src/state.rs b/komorebi/src/state.rs index 9e3b60d8..9309feae 100644 --- a/komorebi/src/state.rs +++ b/komorebi/src/state.rs @@ -253,6 +253,7 @@ impl From<&WindowManager> for State { layout: workspace.layout.clone(), layout_options: workspace.layout_options, layout_rules: workspace.layout_rules.clone(), + work_area_offset_rules: workspace.work_area_offset_rules.clone(), layout_flip: workspace.layout_flip, workspace_padding: workspace.workspace_padding, container_padding: workspace.container_padding, diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index 9383e125..223ec171 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -223,6 +223,9 @@ pub struct WorkspaceConfig { /// Layout rules in the format of threshold => layout #[serde(skip_serializing_if = "Option::is_none")] pub layout_rules: Option>, + /// Work area offset rules in the format of threshold => Rect (default: None) + #[serde(skip_serializing_if = "Option::is_none")] + pub work_area_offset_rules: Option>, /// END OF LIFE FEATURE: Custom layout rules #[deprecated(note = "End of life feature")] #[serde(skip_serializing_if = "Option::is_none")] @@ -287,6 +290,13 @@ impl From<&Workspace> for WorkspaceConfig { } let layout_rules = (!layout_rules.is_empty()).then_some(layout_rules); + let mut work_area_offset_rules = HashMap::new(); + for (threshold, offset) in &value.work_area_offset_rules { + work_area_offset_rules.insert(*threshold, *offset); + } + let work_area_offset_rules = + (!work_area_offset_rules.is_empty()).then_some(work_area_offset_rules); + let mut window_container_behaviour_rules = HashMap::new(); for (threshold, behaviour) in value.window_container_behaviour_rules.iter().flatten() { window_container_behaviour_rules.insert(*threshold, *behaviour); @@ -353,6 +363,7 @@ impl From<&Workspace> for WorkspaceConfig { .workspace_config .as_ref() .and_then(|c| c.workspace_rules.clone()), + work_area_offset_rules, work_area_offset: value.work_area_offset, apply_window_based_work_area_offset: Some(value.apply_window_based_work_area_offset), window_container_behaviour: value.window_container_behaviour, diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index dd395a6a..43678976 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -61,6 +61,7 @@ pub struct Workspace { pub layout: Layout, pub layout_options: Option, pub layout_rules: Vec<(usize, Layout)>, + pub work_area_offset_rules: Vec<(usize, Rect)>, pub layout_flip: Option, pub workspace_padding: Option, pub container_padding: Option, @@ -118,6 +119,7 @@ impl Default for Workspace { layout: Layout::Default(DefaultLayout::BSP), layout_options: None, layout_rules: vec![], + work_area_offset_rules: vec![], layout_flip: None, workspace_padding: Option::from(DEFAULT_WORKSPACE_PADDING.load(Ordering::SeqCst)), container_padding: Option::from(DEFAULT_CONTAINER_PADDING.load(Ordering::SeqCst)), @@ -213,6 +215,15 @@ impl Workspace { self.layout_rules = all_layout_rules; } + let mut all_work_area_offset_rules = vec![]; + if let Some(work_area_offset_rules) = &config.work_area_offset_rules { + for (count, rect) in work_area_offset_rules { + all_work_area_offset_rules.push((*count, *rect)); + } + all_work_area_offset_rules.sort_by_key(|(i, _)| *i); + self.work_area_offset_rules = all_work_area_offset_rules; + } + self.work_area_offset = config.work_area_offset; self.apply_window_based_work_area_offset = @@ -479,9 +490,26 @@ impl Workspace { let border_width = self.globals.border_width; let border_offset = self.globals.border_offset; let work_area = self.globals.work_area; - let work_area_offset = self.work_area_offset.or(self.globals.work_area_offset); let window_based_work_area_offset = self.globals.window_based_work_area_offset; let window_based_work_area_offset_limit = self.globals.window_based_work_area_offset_limit; + let mut rules_work_area_offset = None; + if !self.work_area_offset_rules.is_empty() && self.monocle_container.is_none() { + for (threshold, work_area_offset_rule) in &self.work_area_offset_rules { + if self.containers().len() >= *threshold { + rules_work_area_offset = Some(*work_area_offset_rule); + } + } + // if self.monocle_container.is_some() { + // for (threshold, work_area_offset) in &self.work_area_offset_rules { + // if 1 >= *threshold { + // updated_work_area_offset = Option::from(work_area_offset); + // } + // } + // } + }; + let work_area_offset = rules_work_area_offset + .or(self.work_area_offset) + .or(self.globals.work_area_offset); let mut adjusted_work_area = work_area_offset.map_or_else( || work_area, @@ -495,7 +523,6 @@ impl Workspace { with_offset }, ); - if (self.containers().len() <= window_based_work_area_offset_limit as usize || self.monocle_container.is_some() && window_based_work_area_offset_limit > 0) && self.apply_window_based_work_area_offset