diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-09-20 12:57:42 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-10-02 09:33:08 +0300 |
| commit | 4c524b47196badd281bc159bef3137cf16f963e5 (patch) | |
| tree | 3284ab9c888e5883a525dbf04ad32818cc1c7f81 /src/layout/scrolling.rs | |
| parent | 1fa9dd32ed028c88248644a13421c098fef72894 (diff) | |
| download | niri-4c524b47196badd281bc159bef3137cf16f963e5.tar.gz niri-4c524b47196badd281bc159bef3137cf16f963e5.tar.bz2 niri-4c524b47196badd281bc159bef3137cf16f963e5.zip | |
layout: Store Layout directly in Options
Diffstat (limited to 'src/layout/scrolling.rs')
| -rw-r--r-- | src/layout/scrolling.rs | 149 |
1 files changed, 78 insertions, 71 deletions
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<W: LayoutElement> ScrollingSpace<W> { clock: Clock, options: Rc<Options>, ) -> 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<W: LayoutElement> ScrollingSpace<W> { scale: f64, options: Rc<Options>, ) { - 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<W: LayoutElement> ScrollingSpace<W> { } pub fn new_window_toplevel_bounds(&self, rules: &ResolvedWindowRules) -> Size<i32, Logical> { - 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<W: LayoutElement> ScrollingSpace<W> { border_config, self.working_area.size, extra_size, - self.options.gaps, + self.options.layout.gaps, ) } @@ -470,14 +470,14 @@ impl<W: LayoutElement> ScrollingSpace<W> { height: Option<PresetSize>, rules: &ResolvedWindowRules, ) -> Size<i32, Logical> { - 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { } 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { } 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { // 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<Item = ColumnData>) -> impl Iterator<Item = f64> { - 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { }; 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<W>, prev_col_w: Option<f64>, next_col_w: Option<f64>| { @@ -3297,8 +3301,8 @@ impl<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> ScrollingSpace<W> { 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<W: LayoutElement> Column<W> { .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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { // 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<W: LayoutElement> Column<W> { } // 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { .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::<f64>(); let tile = &self.tiles[non_auto_idx]; @@ -4318,7 +4323,7 @@ impl<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { // 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { let mut it = self .options + .layout .preset_column_widths .iter() .map(|preset| self.resolve_preset_width(*preset)); @@ -4624,7 +4630,7 @@ impl<W: LayoutElement> Column<W> { } }; - 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { let mut it = self .options + .layout .preset_window_heights .iter() .copied() @@ -4933,7 +4940,7 @@ impl<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { // 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<W: LayoutElement> Column<W> { } 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<W: LayoutElement> Column<W> { 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<W: LayoutElement> Column<W> { } 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)), } } |
