diff --git a/niri-visual-tests/src/cases/layout.rs b/niri-visual-tests/src/cases/layout.rs index 50a27ae7..d6175efe 100644 --- a/niri-visual-tests/src/cases/layout.rs +++ b/niri-visual-tests/src/cases/layout.rs @@ -52,20 +52,23 @@ impl Layout { }); let options = Options { - focus_ring: niri_config::FocusRing { - off: true, + layout: niri_config::Layout { + focus_ring: niri_config::FocusRing { + off: true, + ..Default::default() + }, + border: niri_config::Border { + off: false, + width: 4., + active_color: Color::from_rgba8_unpremul(255, 163, 72, 255), + inactive_color: Color::from_rgba8_unpremul(50, 50, 50, 255), + urgent_color: Color::from_rgba8_unpremul(155, 0, 0, 255), + active_gradient: None, + inactive_gradient: None, + urgent_gradient: None, + }, ..Default::default() }, - border: niri_config::Border { - off: false, - width: 4., - active_color: Color::from_rgba8_unpremul(255, 163, 72, 255), - inactive_color: Color::from_rgba8_unpremul(50, 50, 50, 255), - urgent_color: Color::from_rgba8_unpremul(155, 0, 0, 255), - active_gradient: None, - inactive_gradient: None, - urgent_gradient: None, - }, ..Default::default() }; let mut layout = niri::layout::Layout::with_options(clock.clone(), options); diff --git a/niri-visual-tests/src/cases/tile.rs b/niri-visual-tests/src/cases/tile.rs index 1823fe99..23edc4f2 100644 --- a/niri-visual-tests/src/cases/tile.rs +++ b/niri-visual-tests/src/cases/tile.rs @@ -58,14 +58,17 @@ impl Tile { let Args { size, clock } = args; let options = Options { - focus_ring: niri_config::FocusRing { - off: true, - ..Default::default() - }, - border: niri_config::Border { - off: false, - width: 32., - active_color: Color::from_rgba8_unpremul(255, 163, 72, 255), + layout: niri_config::Layout { + focus_ring: niri_config::FocusRing { + off: true, + ..Default::default() + }, + border: niri_config::Border { + off: false, + width: 32., + active_color: Color::from_rgba8_unpremul(255, 163, 72, 255), + ..Default::default() + }, ..Default::default() }, ..Default::default() diff --git a/src/layout/floating.rs b/src/layout/floating.rs index 5f5767ad..260775d3 100644 --- a/src/layout/floating.rs +++ b/src/layout/floating.rs @@ -340,7 +340,7 @@ impl FloatingSpace { } pub fn new_window_toplevel_bounds(&self, rules: &ResolvedWindowRules) -> Size { - let border_config = self.options.border.merged_with(&rules.border); + let border_config = self.options.layout.border.merged_with(&rules.border); compute_toplevel_bounds(border_config, self.working_area.size) } @@ -633,7 +633,7 @@ impl FloatingSpace { let available_size = self.working_area.size.w; - let len = self.options.preset_column_widths.len(); + let len = self.options.layout.preset_column_widths.len(); let tile = &mut self.tiles[idx]; let preset_idx = if let Some(idx) = tile.floating_preset_width_idx { (idx + if forwards { 1 } else { len - 1 }) % len @@ -643,6 +643,7 @@ impl FloatingSpace { let mut it = self .options + .layout .preset_column_widths .iter() .map(|preset| resolve_preset_size(*preset, available_size)); @@ -668,7 +669,7 @@ impl FloatingSpace { } }; - let preset = self.options.preset_column_widths[preset_idx]; + let preset = self.options.layout.preset_column_widths[preset_idx]; self.set_window_width(Some(&id), SizeChange::from(preset), true); self.tiles[idx].floating_preset_width_idx = Some(preset_idx); @@ -693,7 +694,7 @@ impl FloatingSpace { let available_size = self.working_area.size.h; - let len = self.options.preset_window_heights.len(); + let len = self.options.layout.preset_window_heights.len(); let tile = &mut self.tiles[idx]; let preset_idx = if let Some(idx) = tile.floating_preset_height_idx { (idx + if forwards { 1 } else { len - 1 }) % len @@ -703,6 +704,7 @@ impl FloatingSpace { let mut it = self .options + .layout .preset_window_heights .iter() .map(|preset| resolve_preset_size(*preset, available_size)); @@ -728,7 +730,7 @@ impl FloatingSpace { } }; - let preset = self.options.preset_window_heights[preset_idx]; + let preset = self.options.layout.preset_window_heights[preset_idx]; self.set_window_height(Some(&id), SizeChange::from(preset), true); let tile = &mut self.tiles[idx]; @@ -1156,7 +1158,7 @@ impl FloatingSpace { .map(|resize| resize.data); win.set_interactive_resize(resize_data); - let border_config = self.options.border.merged_with(&win.rules().border); + let border_config = self.options.layout.border.merged_with(&win.rules().border); let bounds = compute_toplevel_bounds(border_config, self.working_area.size); win.set_bounds(bounds); @@ -1220,7 +1222,7 @@ impl FloatingSpace { height: Option, rules: &ResolvedWindowRules, ) -> Size { - let border = self.options.border.merged_with(&rules.border); + let border = self.options.layout.border.merged_with(&rules.border); let resolve = |size: Option, working_area_size: f64| { if let Some(size) = size { @@ -1317,10 +1319,10 @@ impl FloatingSpace { tile.verify_invariants(); if let Some(idx) = tile.floating_preset_width_idx { - assert!(idx < self.options.preset_column_widths.len()); + assert!(idx < self.options.layout.preset_column_widths.len()); } if let Some(idx) = tile.floating_preset_height_idx { - assert!(idx < self.options.preset_window_heights.len()); + assert!(idx < self.options.layout.preset_window_heights.len()); } assert!( diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 40f1deed..ff13ee23 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -40,8 +40,7 @@ use std::time::Duration; use monitor::{InsertHint, InsertPosition, InsertWorkspace, MonitorAddWindowTarget}; use niri_config::utils::MergeWith as _; use niri_config::{ - CenterFocusedColumn, Config, CornerRadius, PresetSize, Struts, Workspace as WorkspaceConfig, - WorkspaceReference, + Config, CornerRadius, PresetSize, Workspace as WorkspaceConfig, WorkspaceReference, }; use niri_ipc::{ColumnDisplay, PositionChange, SizeChange, WindowLayout}; use scrolling::{Column, ColumnWidth}; @@ -334,27 +333,9 @@ enum MonitorSet { }, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Default, Clone, PartialEq)] pub struct Options { - /// Padding around windows in logical pixels. - pub gaps: f64, - /// Extra padding around the working area in logical pixels. - pub struts: Struts, - pub focus_ring: niri_config::FocusRing, - pub border: niri_config::Border, - pub shadow: niri_config::Shadow, - pub tab_indicator: niri_config::TabIndicator, - pub insert_hint: niri_config::InsertHint, - pub center_focused_column: CenterFocusedColumn, - pub always_center_single_column: bool, - pub empty_workspace_above_first: bool, - pub default_column_display: ColumnDisplay, - /// Column or window widths that `toggle_width()` switches between. - pub preset_column_widths: Vec, - /// Initial width for new columns. - pub default_column_width: Option, - /// Window height that `toggle_window_height()` switches between. - pub preset_window_heights: Vec, + pub layout: niri_config::Layout, pub animations: niri_config::Animations, pub gestures: niri_config::Gestures, pub overview: niri_config::Overview, @@ -364,41 +345,6 @@ pub struct Options { pub deactivate_unfocused_windows: bool, } -impl Default for Options { - fn default() -> Self { - Self { - gaps: 16., - struts: Default::default(), - focus_ring: Default::default(), - border: Default::default(), - shadow: Default::default(), - tab_indicator: Default::default(), - insert_hint: Default::default(), - center_focused_column: Default::default(), - always_center_single_column: false, - empty_workspace_above_first: false, - default_column_display: ColumnDisplay::Normal, - preset_column_widths: vec![ - PresetSize::Proportion(1. / 3.), - PresetSize::Proportion(0.5), - PresetSize::Proportion(2. / 3.), - ], - default_column_width: None, - animations: Default::default(), - gestures: Default::default(), - overview: Default::default(), - disable_resize_throttling: false, - disable_transactions: false, - preset_window_heights: vec![ - PresetSize::Proportion(1. / 3.), - PresetSize::Proportion(0.5), - PresetSize::Proportion(2. / 3.), - ], - deactivate_unfocused_windows: false, - } - } -} - #[allow(clippy::large_enum_variant)] #[derive(Debug)] enum InteractiveMoveState { @@ -620,49 +566,23 @@ impl HitType { impl Options { fn from_config(config: &Config) -> Self { - let layout = config.resolve_layout(); - - let preset_column_widths = if layout.preset_column_widths.is_empty() { - Options::default().preset_column_widths - } else { - layout.preset_column_widths.clone() - }; - let preset_window_heights = if layout.preset_window_heights.is_empty() { - Options::default().preset_window_heights - } else { - layout.preset_window_heights.clone() - }; - Self { - gaps: layout.gaps, - struts: layout.struts, - focus_ring: layout.focus_ring, - border: layout.border, - shadow: layout.shadow, - tab_indicator: layout.tab_indicator, - insert_hint: layout.insert_hint, - center_focused_column: layout.center_focused_column, - always_center_single_column: layout.always_center_single_column, - empty_workspace_above_first: layout.empty_workspace_above_first, - default_column_display: layout.default_column_display, - preset_column_widths, - default_column_width: layout.default_column_width, + layout: config.resolve_layout(), animations: config.animations.clone(), gestures: config.gestures, overview: config.overview, disable_resize_throttling: config.debug.disable_resize_throttling, disable_transactions: config.debug.disable_transactions, deactivate_unfocused_windows: config.debug.deactivate_unfocused_windows, - preset_window_heights, } } fn adjusted_for_scale(mut self, scale: f64) -> Self { let round = |logical: f64| round_logical_in_physical_max1(scale, logical); - self.gaps = round(self.gaps); - self.focus_ring.width = round(self.focus_ring.width); - self.border.width = round(self.border.width); + self.layout.gaps = round(self.layout.gaps); + self.layout.focus_ring.width = round(self.layout.focus_ring.width); + self.layout.border.width = round(self.layout.border.width); self } @@ -775,7 +695,7 @@ impl Layout { // workspaces set up across multiple monitors. Without this check, the // first monitor to connect can end up with the first empty workspace // focused instead of the first named workspace. - && !(self.options.empty_workspace_above_first + && !(self.options.layout.empty_workspace_above_first && primary.active_workspace_idx == 1) { primary.active_workspace_idx = @@ -790,7 +710,7 @@ impl Layout { // takes care of this. if stopped_primary_ws_switch - || (primary.options.empty_workspace_above_first + || (primary.options.layout.empty_workspace_above_first && primary.workspaces.len() == 2) { primary.clean_up_workspaces(); @@ -810,7 +730,7 @@ impl Layout { self.options.clone(), )); - if self.options.empty_workspace_above_first && workspaces.len() > 1 { + if self.options.layout.empty_workspace_above_first && workspaces.len() > 1 { workspaces.insert( 0, Workspace::new(output.clone(), self.clock.clone(), self.options.clone()), @@ -844,7 +764,7 @@ impl Layout { )); let mut active_workspace_idx = 0; - if self.options.empty_workspace_above_first && workspaces.len() > 1 { + if self.options.layout.empty_workspace_above_first && workspaces.len() > 1 { workspaces.insert( 0, Workspace::new(output.clone(), self.clock.clone(), self.options.clone()), @@ -944,7 +864,7 @@ impl Layout { // If empty_workspace_above_first is set and the first workspace is now no // longer empty, add a new empty workspace on top. - if primary.options.empty_workspace_above_first + if primary.options.layout.empty_workspace_above_first && primary.workspaces[0].has_windows_or_name() { primary.add_workspace_top(); @@ -1242,7 +1162,7 @@ impl Layout { // Special case handling when empty_workspace_above_first is set and all // workspaces are empty. - if mon.options.empty_workspace_above_first + if mon.options.layout.empty_workspace_above_first && mon.workspaces.len() == 2 && mon.workspace_switch.is_none() { @@ -2637,7 +2557,7 @@ impl Layout { !monitor.workspaces.last().unwrap().has_windows(), "monitor must have an empty workspace in the end" ); - if monitor.options.empty_workspace_above_first { + if monitor.options.layout.empty_workspace_above_first { assert!( !monitor.workspaces.first().unwrap().has_windows(), "first workspace must be empty when empty_workspace_above_first is set" @@ -2648,14 +2568,14 @@ impl Layout { monitor.workspaces.last().unwrap().name.is_none(), "monitor must have an unnamed workspace in the end" ); - if monitor.options.empty_workspace_above_first { + if monitor.options.layout.empty_workspace_above_first { assert!( monitor.workspaces.first().unwrap().name.is_none(), "first workspace must be unnamed when empty_workspace_above_first is set" ) } - if monitor.options.empty_workspace_above_first { + if monitor.options.layout.empty_workspace_above_first { assert!( monitor.workspaces.len() != 2, "if empty_workspace_above_first is set there must be just 1 or 3+ workspaces" @@ -2665,7 +2585,7 @@ impl Layout { // If there's no workspace switch in progress, there can't be any non-last non-active // empty workspaces. If empty_workspace_above_first is set then the first workspace // will be empty too. - let pre_skip = if monitor.options.empty_workspace_above_first { + let pre_skip = if monitor.options.layout.empty_workspace_above_first { 1 } else { 0 @@ -3107,7 +3027,7 @@ impl Layout { let mon = &mut monitors[mon_idx]; let mut insert_idx = 0; - if mon.options.empty_workspace_above_first { + if mon.options.layout.empty_workspace_above_first { // need to insert new empty workspace on top mon.add_workspace_top(); insert_idx += 1; @@ -3622,7 +3542,7 @@ impl Layout { // Insert a new empty workspace. current.add_workspace_bottom(); } - if current.options.empty_workspace_above_first && current.active_workspace_idx == 0 { + if current.options.layout.empty_workspace_above_first && current.active_workspace_idx == 0 { current.add_workspace_top(); } @@ -3642,7 +3562,7 @@ impl Layout { target.previous_workspace_id = Some(target.workspaces[target.active_workspace_idx].id()); - if target.options.empty_workspace_above_first && target.workspaces.len() == 1 { + if target.options.layout.empty_workspace_above_first && target.workspaces.len() == 1 { // Insert a new empty workspace on top to prepare for insertion of new workspace. target.add_workspace_top(); } @@ -3711,7 +3631,7 @@ impl Layout { let mut ws = current.workspaces.remove(old_idx); - if current.options.empty_workspace_above_first && old_idx == 0 { + if current.options.layout.empty_workspace_above_first && old_idx == 0 { current.add_workspace_top(); } @@ -3728,7 +3648,7 @@ impl Layout { target.previous_workspace_id = Some(target.workspaces[target.active_workspace_idx].id()); - if target.options.empty_workspace_above_first && target.workspaces.len() == 1 { + if target.options.layout.empty_workspace_above_first && target.workspaces.len() == 1 { // Insert a new empty workspace on top to prepare for insertion of new workspace. target.add_workspace_top(); } @@ -4480,7 +4400,7 @@ impl Layout { .position(|ws| ws.id() == ws_id) .unwrap(), InsertWorkspace::NewAt(ws_idx) => { - if self.options.empty_workspace_above_first && ws_idx == 0 { + if self.options.layout.empty_workspace_above_first && ws_idx == 0 { // Reuse the top empty workspace. 0 } else if mon.workspaces.len() - 1 <= ws_idx { @@ -4813,7 +4733,7 @@ impl Layout { } = &mut self.monitor_set { let monitor = &mut monitors[*active_monitor_idx]; - if self.options.empty_workspace_above_first + if self.options.layout.empty_workspace_above_first && monitor .workspaces .first() @@ -5242,7 +5162,7 @@ impl Layout { // Add border width since ColumnWidth includes borders. let rules = window.rules(); - let border = self.options.border.merged_with(&rules.border); + let border = self.options.layout.border.merged_with(&rules.border); if !border.off { fixed += border.width * 2.; } diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs index 5dc0aed6..bcb6a5c3 100644 --- a/src/layout/monitor.rs +++ b/src/layout/monitor.rs @@ -293,7 +293,7 @@ impl Monitor { active_workspace_idx: 0, previous_workspace_id: None, insert_hint: None, - insert_hint_element: InsertHintElement::new(options.insert_hint), + insert_hint_element: InsertHintElement::new(options.layout.insert_hint), insert_hint_render_loc: None, overview_open: false, overview_progress: None, @@ -463,7 +463,7 @@ impl Monitor { if workspace_idx == self.workspaces.len() - 1 { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && workspace_idx == 0 { + if self.options.layout.empty_workspace_above_first && workspace_idx == 0 { self.add_workspace_top(); workspace_idx += 1; } @@ -522,7 +522,7 @@ impl Monitor { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && workspace_idx == 0 { + if self.options.layout.empty_workspace_above_first && workspace_idx == 0 { self.add_workspace_top(); workspace_idx += 1; } @@ -562,7 +562,7 @@ impl Monitor { pub fn clean_up_workspaces(&mut self) { assert!(self.workspace_switch.is_none()); - let range_start = if self.options.empty_workspace_above_first { + let range_start = if self.options.layout.empty_workspace_above_first { 1 } else { 0 @@ -582,7 +582,7 @@ impl Monitor { // Special case handling when empty_workspace_above_first is set and all workspaces // are empty. - if self.options.empty_workspace_above_first && self.workspaces.len() == 2 { + if self.options.layout.empty_workspace_above_first && self.workspaces.len() == 2 { assert!(!self.workspaces[0].has_windows_or_name()); assert!(!self.workspaces[1].has_windows_or_name()); self.workspaces.remove(1); @@ -1023,10 +1023,11 @@ impl Monitor { } pub fn update_config(&mut self, options: Rc) { - if self.options.empty_workspace_above_first != options.empty_workspace_above_first + if self.options.layout.empty_workspace_above_first + != options.layout.empty_workspace_above_first && self.workspaces.len() > 1 { - if options.empty_workspace_above_first { + if options.layout.empty_workspace_above_first { self.add_workspace_top(); } else if self.workspace_switch.is_none() && self.active_workspace_idx != 0 { self.workspaces.remove(0); @@ -1038,7 +1039,8 @@ impl Monitor { ws.update_config(options.clone()); } - self.insert_hint_element.update_config(options.insert_hint); + self.insert_hint_element + .update_config(options.layout.insert_hint); self.options = options; } @@ -1074,7 +1076,7 @@ impl Monitor { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && self.active_workspace_idx == 0 { + if self.options.layout.empty_workspace_above_first && self.active_workspace_idx == 0 { self.add_workspace_top(); new_idx += 1; } @@ -1100,7 +1102,7 @@ impl Monitor { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && new_idx == 0 { + if self.options.layout.empty_workspace_above_first && new_idx == 0 { self.add_workspace_top(); new_idx += 1; } @@ -1132,7 +1134,7 @@ impl Monitor { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && old_idx == 0 { + if self.options.layout.empty_workspace_above_first && old_idx == 0 { self.add_workspace_top(); new_idx += 1; } @@ -1142,7 +1144,7 @@ impl Monitor { self.add_workspace_bottom(); } - if self.options.empty_workspace_above_first && new_idx == 0 { + if self.options.layout.empty_workspace_above_first && new_idx == 0 { self.add_workspace_top(); new_idx += 1; } @@ -1464,7 +1466,7 @@ impl Monitor { ) -> impl Iterator> { let mut rv = None; - if !self.options.insert_hint.off { + if !self.options.layout.insert_hint.off { if let Some(render_loc) = self.insert_hint_render_loc { if let InsertWorkspace::NewAt(_) = render_loc.workspace { let iter = self @@ -1525,7 +1527,7 @@ impl Monitor { // Draw the insert hint. let mut insert_hint = None; - if !self.options.insert_hint.off { + if !self.options.layout.insert_hint.off { if let Some(render_loc) = self.insert_hint_render_loc { if let InsertWorkspace::Existing(workspace_id) = render_loc.workspace { insert_hint = Some(( diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index 52869024..9c483e72 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -276,7 +276,7 @@ impl ScrollingSpace { clock: Clock, options: Rc, ) -> Self { - let working_area = compute_working_area(parent_area, scale, options.struts); + let working_area = compute_working_area(parent_area, scale, options.layout.struts); Self { columns: Vec::new(), @@ -303,7 +303,7 @@ impl ScrollingSpace { scale: f64, options: Rc, ) { - let working_area = compute_working_area(parent_area, scale, options.struts); + let working_area = compute_working_area(parent_area, scale, options.layout.struts); for (column, data) in zip(&mut self.columns, &mut self.data) { column.update_config(view_size, working_area, scale, options.clone()); @@ -444,14 +444,14 @@ impl ScrollingSpace { } pub fn new_window_toplevel_bounds(&self, rules: &ResolvedWindowRules) -> Size { - let border_config = self.options.border.merged_with(&rules.border); + let border_config = self.options.layout.border.merged_with(&rules.border); let display_mode = rules .default_column_display - .unwrap_or(self.options.default_column_display); + .unwrap_or(self.options.layout.default_column_display); let will_tab = display_mode == ColumnDisplay::Tabbed; let extra_size = if will_tab { - TabIndicator::new(self.options.tab_indicator).extra_size(1, self.scale) + TabIndicator::new(self.options.layout.tab_indicator).extra_size(1, self.scale) } else { Size::from((0., 0.)) }; @@ -460,7 +460,7 @@ impl ScrollingSpace { border_config, self.working_area.size, extra_size, - self.options.gaps, + self.options.layout.gaps, ) } @@ -470,14 +470,14 @@ impl ScrollingSpace { height: Option, rules: &ResolvedWindowRules, ) -> Size { - let border = self.options.border.merged_with(&rules.border); + let border = self.options.layout.border.merged_with(&rules.border); let display_mode = rules .default_column_display - .unwrap_or(self.options.default_column_display); + .unwrap_or(self.options.layout.default_column_display); let will_tab = display_mode == ColumnDisplay::Tabbed; let extra = if will_tab { - TabIndicator::new(self.options.tab_indicator).extra_size(1, self.scale) + TabIndicator::new(self.options.layout.tab_indicator).extra_size(1, self.scale) } else { Size::from((0., 0.)) }; @@ -500,7 +500,7 @@ impl ScrollingSpace { 0 }; - let mut full_height = self.working_area.size.h - self.options.gaps * 2.; + let mut full_height = self.working_area.size.h - self.options.layout.gaps * 2.; if !border.off { full_height -= border.width * 2.; } @@ -524,8 +524,8 @@ impl ScrollingSpace { } pub fn is_centering_focused_column(&self) -> bool { - self.options.center_focused_column == CenterFocusedColumn::Always - || (self.options.always_center_single_column && self.columns.len() <= 1) + self.options.layout.center_focused_column == CenterFocusedColumn::Always + || (self.options.layout.always_center_single_column && self.columns.len() <= 1) } fn compute_new_view_offset_fit( @@ -546,7 +546,7 @@ impl ScrollingSpace { self.working_area.size.w, col_x, width, - self.options.gaps, + self.options.layout.gaps, ); // Non-fullscreen windows are always offset at least by the working area position. @@ -606,7 +606,7 @@ impl ScrollingSpace { return self.compute_new_view_offset_for_column_centered(target_x, idx); } - match self.options.center_focused_column { + match self.options.layout.center_focused_column { CenterFocusedColumn::Always => { self.compute_new_view_offset_for_column_centered(target_x, idx) } @@ -639,7 +639,7 @@ impl ScrollingSpace { } else { // Source is right from target. source_col_x - target_col_x + source_col_width - } + self.options.gaps * 2.; + } + self.options.layout.gaps * 2.; // If it fits together, do a normal animation, otherwise center the new column. if total_width <= self.working_area.size.w { @@ -783,8 +783,8 @@ impl ScrollingSpace { let x = pos.x + self.view_pos(); // Aim for the center of the gap. - let x = x + self.options.gaps / 2.; - let y = pos.y + self.options.gaps / 2.; + let x = x + self.options.layout.gaps / 2.; + let y = pos.y + self.options.layout.gaps / 2.; // Insert position is before the first column. if x < 0. { @@ -2224,7 +2224,7 @@ impl ScrollingSpace { let mut leftmost_col_x = None; let mut active_col_x = None; - let gap = self.options.gaps; + let gap = self.options.layout.gaps; let col_xs = self.column_xs(self.data.iter().copied()); for (idx, col_x) in col_xs.take(self.columns.len()).enumerate() { if col_x < view_x + working_x + gap { @@ -2274,7 +2274,7 @@ impl ScrollingSpace { // HACK: pass a self.data iterator in manually as a workaround for the lack of method partial // borrowing. Note that this method's return value does not borrow the entire &Self! fn column_xs(&self, data: impl Iterator) -> impl Iterator { - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let mut x = 0.; // Chain with a dummy value to be able to get one past all columns' X. @@ -2408,25 +2408,29 @@ impl ScrollingSpace { let mut hint_area = match position { InsertPosition::NewColumn(column_index) => { if column_index == 0 || column_index == self.columns.len() { - let size = - Size::from((300., self.working_area.size.h - self.options.gaps * 2.)); + let size = Size::from(( + 300., + self.working_area.size.h - self.options.layout.gaps * 2., + )); let mut loc = Point::from(( self.column_x(column_index), - self.working_area.loc.y + self.options.gaps, + self.working_area.loc.y + self.options.layout.gaps, )); if column_index == 0 && !self.columns.is_empty() { - loc.x -= size.w + self.options.gaps; + loc.x -= size.w + self.options.layout.gaps; } Rectangle::new(loc, size) } else if column_index > self.columns.len() { error!("insert hint column index is out of range"); return None; } else { - let size = - Size::from((300., self.working_area.size.h - self.options.gaps * 2.)); + let size = Size::from(( + 300., + self.working_area.size.h - self.options.layout.gaps * 2., + )); let loc = Point::from(( - self.column_x(column_index) - size.w / 2. - self.options.gaps / 2., - self.working_area.loc.y + self.options.gaps, + self.column_x(column_index) - size.w / 2. - self.options.layout.gaps / 2., + self.working_area.loc.y + self.options.layout.gaps, )); Rectangle::new(loc, size) } @@ -2462,9 +2466,9 @@ impl ScrollingSpace { if tile_index == 0 { (150., top) } else if tile_index == col.tiles.len() { - (150., top - self.options.gaps - 150.) + (150., top - self.options.layout.gaps - 150.) } else { - (300., top - self.options.gaps / 2. - 150.) + (300., top - self.options.layout.gaps / 2. - 150.) } }; @@ -2716,7 +2720,7 @@ impl ScrollingSpace { let mut active_col_x = None; let mut counted_non_active_column = false; - let gap = self.options.gaps; + let gap = self.options.layout.gaps; let col_xs = self.column_xs(self.data.iter().copied()); for (idx, col_x) in col_xs.take(self.columns.len()).enumerate() { if col_x < view_x + working_x + gap { @@ -3051,7 +3055,7 @@ impl ScrollingSpace { let (leftmost, rightmost) = if self.columns.is_empty() { (0., 0.) } else { - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let mut leftmost = -self.working_area.size.w; @@ -3147,17 +3151,17 @@ impl ScrollingSpace { }; snapping_points.push(Snap { view_pos, col_idx }); - col_x += col_w + self.options.gaps; + col_x += col_w + self.options.layout.gaps; } } else { let center_on_overflow = matches!( - self.options.center_focused_column, + self.options.layout.center_focused_column, CenterFocusedColumn::OnOverflow ); let view_width = self.view_size.w; let working_area_width = self.working_area.size.w; - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let snap_points = |col_x, col: &Column, prev_col_w: Option, next_col_w: Option| { @@ -3297,8 +3301,8 @@ impl ScrollingSpace { break; } } else { - let padding = - ((self.working_area.size.w - col_w) / 2.).clamp(0., self.options.gaps); + let padding = ((self.working_area.size.w - col_w) / 2.) + .clamp(0., self.options.layout.gaps); if target_snap.view_pos + left_strut + self.working_area.size.w < col_x + col_w + padding { @@ -3319,8 +3323,8 @@ impl ScrollingSpace { break; } } else { - let padding = - ((self.working_area.size.w - col_w) / 2.).clamp(0., self.options.gaps); + let padding = ((self.working_area.size.w - col_w) / 2.) + .clamp(0., self.options.layout.gaps); if col_x - padding < target_snap.view_pos + left_strut { break; } @@ -3548,12 +3552,12 @@ impl ScrollingSpace { win.set_interactive_resize(col_resize_data); - let border_config = self.options.border.merged_with(&win.rules().border); + let border_config = self.options.layout.border.merged_with(&win.rules().border); let bounds = compute_toplevel_bounds( border_config, self.working_area.size, extra_size, - self.options.gaps, + self.options.layout.gaps, ); win.set_bounds(bounds); @@ -3614,7 +3618,7 @@ impl ScrollingSpace { assert_eq!(self.columns.len(), self.data.len()); assert_eq!( self.working_area, - compute_working_area(self.parent_area, self.scale, self.options.struts) + compute_working_area(self.parent_area, self.scale, self.options.layout.struts) ); if !self.columns.is_empty() { @@ -3802,7 +3806,7 @@ impl Column { .window() .rules() .default_column_display - .unwrap_or(options.default_column_display); + .unwrap_or(options.layout.default_column_display); let mut rv = Self { tiles: vec![], @@ -3813,7 +3817,7 @@ impl Column { is_full_width, is_pending_fullscreen: false, display_mode, - tab_indicator: TabIndicator::new(options.tab_indicator), + tab_indicator: TabIndicator::new(options.layout.tab_indicator), move_animation: None, view_size, working_area, @@ -3832,7 +3836,7 @@ impl Column { // Animate the tab indicator for new columns. if display_mode == ColumnDisplay::Tabbed - && !rv.options.tab_indicator.hide_when_single_tab + && !rv.options.layout.tab_indicator.hide_when_single_tab && !rv.is_fullscreen() { // Usually new columns are created together with window movement actions. For new @@ -3858,27 +3862,27 @@ impl Column { } // If preset widths changed, clear our stored preset index. - if self.options.preset_column_widths != options.preset_column_widths { + if self.options.layout.preset_column_widths != options.layout.preset_column_widths { self.preset_width_idx = None; } // If preset heights changed, make our heights non-preset. - if self.options.preset_window_heights != options.preset_window_heights { + if self.options.layout.preset_window_heights != options.layout.preset_window_heights { self.convert_heights_to_auto(); update_sizes = true; } - if self.options.gaps != options.gaps { + if self.options.layout.gaps != options.layout.gaps { update_sizes = true; } - if self.options.border.off != options.border.off - || self.options.border.width != options.border.width + if self.options.layout.border.off != options.layout.border.off + || self.options.layout.border.width != options.layout.border.width { update_sizes = true; } - if self.options.tab_indicator != options.tab_indicator { + if self.options.layout.tab_indicator != options.layout.tab_indicator { update_sizes = true; } @@ -3887,7 +3891,8 @@ impl Column { data.update(tile); } - self.tab_indicator.update_config(options.tab_indicator); + self.tab_indicator + .update_config(options.layout.tab_indicator); self.view_size = view_size; self.working_area = working_area; self.scale = scale; @@ -4192,7 +4197,7 @@ impl Column { fn resolve_column_width(&self, width: ColumnWidth) -> f64 { let working_size = self.working_area.size; - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let extra = self.extra_size(); match width { @@ -4274,7 +4279,7 @@ impl Column { let width = self.resolve_column_width(width); let width = f64::max(f64::min(width, max_width), min_width); - let max_tile_height = working_size.h - self.options.gaps * 2. - extra_size.h; + let max_tile_height = working_size.h - self.options.layout.gaps * 2. - extra_size.h; // If there are multiple windows in a column, clamp the non-auto window's height according // to other windows' min sizes. @@ -4289,7 +4294,7 @@ impl Column { .iter() .enumerate() .filter(|(idx, _)| *idx != non_auto_idx) - .map(|(_, min_size)| min_size.h + self.options.gaps) + .map(|(_, min_size)| min_size.h + self.options.layout.gaps) .sum::(); let tile = &self.tiles[non_auto_idx]; @@ -4318,7 +4323,7 @@ impl Column { WindowHeight::Fixed(tile.tile_height_for_window_height(window_height)) } WindowHeight::Preset(idx) => { - let preset = self.options.preset_window_heights[idx]; + let preset = self.options.layout.preset_window_heights[idx]; let window_height = match self.resolve_preset_height(preset) { ResolvedSize::Tile(h) => tile.window_height_for_tile_height(h), ResolvedSize::Window(h) => h, @@ -4366,7 +4371,7 @@ impl Column { // The following logic will apply individual min/max height, etc. } - let gaps_left = self.options.gaps * (self.tiles.len() + 1) as f64; + let gaps_left = self.options.layout.gaps * (self.tiles.len() + 1) as f64; let mut height_left = working_size.h - gaps_left; let mut auto_tiles_left = self.tiles.len(); @@ -4589,7 +4594,7 @@ impl Column { self.preset_width_idx }; - let len = self.options.preset_column_widths.len(); + let len = self.options.layout.preset_column_widths.len(); let preset_idx = if let Some(idx) = preset_idx { (idx + if forwards { 1 } else { len - 1 }) % len } else { @@ -4599,6 +4604,7 @@ impl Column { let mut it = self .options + .layout .preset_column_widths .iter() .map(|preset| self.resolve_preset_width(*preset)); @@ -4624,7 +4630,7 @@ impl Column { } }; - let preset = self.options.preset_column_widths[preset_idx]; + let preset = self.options.layout.preset_column_widths[preset_idx]; self.set_column_width(SizeChange::from(preset), Some(tile_idx), true); self.preset_width_idx = Some(preset_idx); @@ -4672,11 +4678,11 @@ impl Column { ColumnWidth::Proportion(proportion) } (ColumnWidth::Fixed(_), SizeChange::AdjustProportion(delta)) => { - let full = self.working_area.size.w - self.options.gaps; + let full = self.working_area.size.w - self.options.layout.gaps; let current = if full == 0. { 1. } else { - (current_px + self.options.gaps + self.extra_size().w) / full + (current_px + self.options.layout.gaps + self.extra_size().w) / full }; let proportion = (current + delta / 100.).clamp(0., MAX_F); ColumnWidth::Proportion(proportion) @@ -4710,7 +4716,7 @@ impl Column { let current_tile_px = tile.tile_height_for_window_height(current_window_px); let working_size = self.working_area.size.h; - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let extra_size = self.extra_size().h; let full = working_size - gaps; let current_prop = if full == 0. { @@ -4794,7 +4800,7 @@ impl Column { self.convert_heights_to_auto(); } - let len = self.options.preset_window_heights.len(); + let len = self.options.layout.preset_window_heights.len(); let preset_idx = match self.data[tile_idx].height { WindowHeight::Preset(idx) => (idx + if forwards { 1 } else { len - 1 }) % len, _ => { @@ -4803,6 +4809,7 @@ impl Column { let mut it = self .options + .layout .preset_window_heights .iter() .copied() @@ -4933,7 +4940,7 @@ impl Column { return origin; } - origin.y += self.working_area.loc.y + self.options.gaps; + origin.y += self.working_area.loc.y + self.options.layout.gaps; if self.display_mode == ColumnDisplay::Tabbed { origin += self @@ -4953,8 +4960,8 @@ impl Column { // FIXME: this should take into account always-center-single-column, which means that // Column should somehow know when it is being centered due to being the single column on // the workspace or some other reason. - let center = self.options.center_focused_column == CenterFocusedColumn::Always; - let gaps = self.options.gaps; + let center = self.options.layout.center_focused_column == CenterFocusedColumn::Always; + let gaps = self.options.layout.gaps; let tabbed = self.display_mode == ColumnDisplay::Tabbed; // Does not include extra size from the tab indicator. @@ -5117,7 +5124,7 @@ impl Column { } if let Some(idx) = self.preset_width_idx { - assert!(idx < self.options.preset_column_widths.len()); + assert!(idx < self.options.layout.preset_column_widths.len()); } let is_tabbed = self.display_mode == ColumnDisplay::Tabbed; @@ -5134,7 +5141,7 @@ impl Column { let working_size = self.working_area.size; let extra_size = self.extra_size(); - let gaps = self.options.gaps; + let gaps = self.options.layout.gaps; let mut found_fixed = false; let mut total_height = 0.; @@ -5163,7 +5170,7 @@ impl Column { } if let WindowHeight::Preset(idx) = data.height { - assert!(self.options.preset_window_heights.len() > idx); + assert!(self.options.layout.preset_window_heights.len() > idx); } let requested_size = tile.window().requested_size().unwrap(); @@ -5312,9 +5319,9 @@ fn resolve_preset_size( extra_size: f64, ) -> ResolvedSize { match preset { - PresetSize::Proportion(proportion) => { - ResolvedSize::Tile((view_size - options.gaps) * proportion - options.gaps - extra_size) - } + PresetSize::Proportion(proportion) => ResolvedSize::Tile( + (view_size - options.layout.gaps) * proportion - options.layout.gaps - extra_size, + ), PresetSize::Fixed(width) => ResolvedSize::Window(f64::from(width)), } } diff --git a/src/layout/tests.rs b/src/layout/tests.rs index 1c071eb0..94ca0b92 100644 --- a/src/layout/tests.rs +++ b/src/layout/tests.rs @@ -2,7 +2,8 @@ use std::cell::{Cell, OnceCell, RefCell}; use niri_config::workspace::WorkspaceName; use niri_config::{ - FloatOrInt, OutputName, TabIndicatorLength, TabIndicatorPosition, WorkspaceReference, + CenterFocusedColumn, FloatOrInt, OutputName, Struts, TabIndicatorLength, TabIndicatorPosition, + WorkspaceReference, }; use proptest::prelude::*; use proptest_derive::Arbitrary; @@ -2066,8 +2067,8 @@ fn large_negative_height_change() { ]; let mut options = Options::default(); - options.border.off = false; - options.border.width = 1.; + options.layout.border.off = false; + options.layout.border.width = 1.; check_ops_with_options(options, ops); } @@ -2085,8 +2086,8 @@ fn large_max_size() { ]; let mut options = Options::default(); - options.border.off = false; - options.border.width = 1.; + options.layout.border.off = false; + options.layout.border.width = 1.; check_ops_with_options(options, ops); } @@ -2244,7 +2245,10 @@ fn open_right_of_on_different_workspace_ewaf() { ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; let layout = check_ops_with_options(options, ops); @@ -2306,11 +2310,7 @@ fn config_change_updates_cached_sizes() { } .apply(&mut layout); - config - .layout - .border - .get_or_insert_with(Default::default) - .width = Some(FloatOrInt(4.)); + config.layout.border.as_mut().unwrap().width = Some(FloatOrInt(4.)); layout.update_config(&config); layout.verify_invariants(); @@ -2427,12 +2427,15 @@ fn fixed_height_takes_max_non_auto_into_account() { ]; let options = Options { - border: niri_config::Border { - off: false, - width: 4., + layout: niri_config::Layout { + border: niri_config::Border { + off: false, + width: 4., + ..Default::default() + }, + gaps: 0., ..Default::default() }, - gaps: 0., ..Default::default() }; check_ops_with_options(options, ops); @@ -2511,7 +2514,10 @@ fn interactive_move_onto_empty_output_ewaf() { ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2572,7 +2578,10 @@ fn interactive_move_onto_first_empty_workspace() { Op::InteractiveMoveEnd { window: 1 }, ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2653,7 +2662,10 @@ fn named_workspace_to_output_ewaf() { Op::AddOutput(2), ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2672,7 +2684,10 @@ fn move_window_to_empty_workspace_above_first() { Op::MoveWorkspaceDown, ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2689,7 +2704,10 @@ fn move_window_to_different_output() { Op::MoveWorkspaceToOutput(2), ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2705,7 +2723,10 @@ fn close_window_empty_ws_above_first() { Op::CloseWindow(1), ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2722,7 +2743,10 @@ fn add_and_remove_output() { Op::RemoveOutput(2), ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -2739,7 +2763,10 @@ fn switch_ewaf_on() { let mut layout = check_ops(ops); layout.update_options(Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }); layout.verify_invariants(); @@ -2755,7 +2782,10 @@ fn switch_ewaf_off() { ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; let mut layout = check_ops_with_options(options, ops); @@ -3074,7 +3104,10 @@ fn set_first_workspace_name_ewaf() { ]; let options = Options { - empty_workspace_above_first: true, + layout: niri_config::Layout { + empty_workspace_above_first: true, + ..Default::default() + }, ..Default::default() }; check_ops_with_options(options, ops); @@ -3165,7 +3198,10 @@ fn preset_column_width_fixed_correct_with_border() { ]; let options = Options { - preset_column_widths: vec![PresetSize::Fixed(500)], + layout: niri_config::Layout { + preset_column_widths: vec![PresetSize::Fixed(500)], + ..Default::default() + }, ..Default::default() }; let mut layout = check_ops_with_options(options, ops); @@ -3175,10 +3211,13 @@ fn preset_column_width_fixed_correct_with_border() { // Add border. let options = Options { - preset_column_widths: vec![PresetSize::Fixed(500)], - border: niri_config::Border { - off: false, - width: 5., + layout: niri_config::Layout { + preset_column_widths: vec![PresetSize::Fixed(500)], + border: niri_config::Border { + off: false, + width: 5., + ..Default::default() + }, ..Default::default() }, ..Default::default() @@ -3211,7 +3250,10 @@ fn preset_column_width_reset_after_set_width() { ]; let options = Options { - preset_column_widths: vec![PresetSize::Fixed(500), PresetSize::Fixed(1000)], + layout: niri_config::Layout { + preset_column_widths: vec![PresetSize::Fixed(500), PresetSize::Fixed(1000)], + ..Default::default() + }, ..Default::default() }; let layout = check_ops_with_options(options, ops); @@ -3469,7 +3511,7 @@ prop_compose! { } prop_compose! { - fn arbitrary_options()( + fn arbitrary_layout_config()( gaps in arbitrary_spacing(), struts in arbitrary_struts(), focus_ring in arbitrary_focus_ring(), @@ -3479,8 +3521,8 @@ prop_compose! { center_focused_column in arbitrary_center_focused_column(), always_center_single_column in any::(), empty_workspace_above_first in any::(), - ) -> Options { - Options { + ) -> niri_config::Layout { + niri_config::Layout { gaps, struts, center_focused_column, @@ -3495,6 +3537,17 @@ prop_compose! { } } +prop_compose! { + fn arbitrary_options()( + layout in arbitrary_layout_config() + ) -> Options { + Options { + layout, + ..Default::default() + } + } +} + proptest! { #![proptest_config(ProptestConfig { cases: if std::env::var_os("RUN_SLOW_TESTS").is_none() { diff --git a/src/layout/tests/animations.rs b/src/layout/tests/animations.rs index 21be56f1..85df548c 100644 --- a/src/layout/tests/animations.rs +++ b/src/layout/tests/animations.rs @@ -29,7 +29,10 @@ fn make_options() -> Options { }); let mut options = Options { - gaps: 0.0, + layout: niri_config::Layout { + gaps: 0.0, + ..Default::default() + }, ..Options::default() }; options.animations.window_resize.anim.kind = LINEAR; diff --git a/src/layout/tests/fullscreen.rs b/src/layout/tests/fullscreen.rs index 904595f5..0f20abf6 100644 --- a/src/layout/tests/fullscreen.rs +++ b/src/layout/tests/fullscreen.rs @@ -188,9 +188,12 @@ fn unfullscreen_with_large_border() { ]; let options = Options { - border: niri_config::Border { - off: false, - width: 10000., + layout: niri_config::Layout { + border: niri_config::Border { + off: false, + width: 10000., + ..Default::default() + }, ..Default::default() }, ..Default::default() diff --git a/src/layout/tile.rs b/src/layout/tile.rs index a560bd55..b574b7a2 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -175,9 +175,9 @@ impl Tile { options: Rc, ) -> Self { let rules = window.rules(); - let border_config = options.border.merged_with(&rules.border); - let focus_ring_config = options.focus_ring.merged_with(&rules.focus_ring); - let shadow_config = options.shadow.merged_with(&rules.shadow); + let border_config = options.layout.border.merged_with(&rules.border); + let focus_ring_config = options.layout.focus_ring.merged_with(&rules.focus_ring); + let shadow_config = options.layout.shadow.merged_with(&rules.shadow); let is_fullscreen = window.is_fullscreen(); Self { @@ -214,10 +214,10 @@ impl Tile { options: Rc, ) { // If preset widths or heights changed, clear our stored preset index. - if self.options.preset_column_widths != options.preset_column_widths { + if self.options.layout.preset_column_widths != options.layout.preset_column_widths { self.floating_preset_width_idx = None; } - if self.options.preset_window_heights != options.preset_window_heights { + if self.options.layout.preset_window_heights != options.layout.preset_window_heights { self.floating_preset_height_idx = None; } @@ -227,13 +227,17 @@ impl Tile { let rules = self.window.rules(); - let border_config = self.options.border.merged_with(&rules.border); + let border_config = self.options.layout.border.merged_with(&rules.border); self.border.update_config(border_config.into()); - let focus_ring_config = self.options.focus_ring.merged_with(&rules.focus_ring); + let focus_ring_config = self + .options + .layout + .focus_ring + .merged_with(&rules.focus_ring); self.focus_ring.update_config(focus_ring_config); - let shadow_config = self.options.shadow.merged_with(&rules.shadow); + let shadow_config = self.options.layout.shadow.merged_with(&rules.shadow); self.shadow.update_config(shadow_config); } @@ -332,12 +336,16 @@ impl Tile { } let rules = self.window.rules(); - let border_config = self.options.border.merged_with(&rules.border); + let border_config = self.options.layout.border.merged_with(&rules.border); self.border.update_config(border_config.into()); - let focus_ring_config = self.options.focus_ring.merged_with(&rules.focus_ring); + let focus_ring_config = self + .options + .layout + .focus_ring + .merged_with(&rules.focus_ring); self.focus_ring.update_config(focus_ring_config); - let shadow_config = self.options.shadow.merged_with(&rules.shadow); + let shadow_config = self.options.layout.shadow.merged_with(&rules.shadow); self.shadow.update_config(shadow_config); let window_size = self.window_size(); diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 8c1c36d3..2d71ad1b 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -754,7 +754,7 @@ impl Workspace { Some(Some(width)) => Some(width), Some(None) => None, None if is_floating => None, - None => self.options.default_column_width, + None => self.options.layout.default_column_width, } } @@ -1272,11 +1272,12 @@ impl Workspace { // Come up with a default floating position close to the tile position. let stored_or_default = self.floating.stored_or_default_tile_pos(&removed.tile); if stored_or_default.is_none() { - let offset = if self.options.center_focused_column == CenterFocusedColumn::Always { - Point::from((0., 0.)) - } else { - Point::from((50., 50.)) - }; + let offset = + if self.options.layout.center_focused_column == CenterFocusedColumn::Always { + Point::from((0., 0.)) + } else { + Point::from((50., 50.)) + }; let pos = render_pos + offset; let size = removed.tile.tile_size(); let pos = self.floating.clamp_within_working_area(pos, size);