diff --git a/komorebi/src/static_config.rs b/komorebi/src/static_config.rs index b268e93ae..9d70460ce 100644 --- a/komorebi/src/static_config.rs +++ b/komorebi/src/static_config.rs @@ -202,6 +202,9 @@ pub struct WorkspaceConfig { /// Layout rules in the format of threshold => layout (default: None) #[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 (default: None) #[serde(skip_serializing_if = "Option::is_none")] #[serde(deserialize_with = "resolve_option_hashmap_usize_path", default)] @@ -260,6 +263,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); @@ -318,6 +328,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/window_manager.rs b/komorebi/src/window_manager.rs index 86603a16e..07602f586 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -331,6 +331,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/workspace.rs b/komorebi/src/workspace.rs index c1d6057d3..7a6670982 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -60,6 +60,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, @@ -113,6 +114,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)), @@ -200,6 +202,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 = @@ -459,9 +470,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, @@ -475,7 +503,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