diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-11 09:55:58 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-17 09:02:22 +0300 |
| commit | 2ffa1ae705516b5b52e8bfaff36d208d76ae5e01 (patch) | |
| tree | 9fdfba828dcfdb5a17422c262bbbd4a4c4b1cb0d | |
| parent | fee72b87cf732180889ebc9151b77249533d6995 (diff) | |
| download | niri-2ffa1ae705516b5b52e8bfaff36d208d76ae5e01.tar.gz niri-2ffa1ae705516b5b52e8bfaff36d208d76ae5e01.tar.bz2 niri-2ffa1ae705516b5b52e8bfaff36d208d76ae5e01.zip | |
layout: Cache scale and transform on the workspace
| -rw-r--r-- | src/layout/mod.rs | 5 | ||||
| -rw-r--r-- | src/layout/monitor.rs | 4 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 92 |
3 files changed, 49 insertions, 52 deletions
diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 3c660238..2183bdf1 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -923,12 +923,13 @@ impl<W: LayoutElement> Layout<W> { for mon in monitors { if &mon.output == output { + let scale = output.current_scale(); + let transform = output.current_transform(); let view_size = output_size(output); let working_area = compute_working_area(output, self.options.struts); for ws in &mut mon.workspaces { - ws.set_view_size(view_size, working_area); - ws.update_output_scale_transform(); + ws.set_view_size(scale, transform, view_size, working_area); } break; diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs index c4bf8429..b166879b 100644 --- a/src/layout/monitor.rs +++ b/src/layout/monitor.rs @@ -681,11 +681,13 @@ impl<W: LayoutElement> Monitor<W> { } if self.options.struts != options.struts { + let scale = self.output.current_scale(); + let transform = self.output.current_transform(); let view_size = output_size(&self.output); let working_area = compute_working_area(&self.output, options.struts); for ws in &mut self.workspaces { - ws.set_view_size(view_size, working_area); + ws.set_view_size(scale, transform, view_size, working_area); } } diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 3b74f159..d3f583d2 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -10,7 +10,7 @@ use smithay::desktop::{layer_map_for_output, Window}; use smithay::output::Output; use smithay::reexports::wayland_protocols::xdg::shell::server::xdg_toplevel; use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface; -use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size}; +use smithay::utils::{Logical, Point, Rectangle, Scale, Serial, Size, Transform}; use super::closing_window::{ClosingWindow, ClosingWindowRenderElement}; use super::tile::{Tile, TileRenderElement}; @@ -38,6 +38,18 @@ pub struct Workspace<W: LayoutElement> { /// Current output of this workspace. output: Option<Output>, + /// Latest known output scale for this workspace. + /// + /// This should be set from the current workspace output, or, if all outputs have been + /// disconnected, preserved until a new output is connected. + scale: smithay::output::Scale, + + /// Latest known output transform for this workspace. + /// + /// This should be set from the current workspace output, or, if all outputs have been + /// disconnected, preserved until a new output is connected. + transform: Transform, + /// Latest known view size for this workspace. /// /// This should be computed from the current workspace output size, or, if all outputs have @@ -332,6 +344,8 @@ impl<W: LayoutElement> Workspace<W> { let working_area = compute_working_area(&output, options.struts); Self { original_output, + scale: output.current_scale(), + transform: output.current_transform(), view_size: output_size(&output), working_area, output: Some(output), @@ -362,6 +376,8 @@ impl<W: LayoutElement> Workspace<W> { ); Self { output: None, + scale: smithay::output::Scale::Integer(1), + transform: Transform::Normal, original_output, view_size: Size::from((1280, 720)), working_area: Rectangle::from_loc_and_size((0, 0), (1280, 720)), @@ -488,8 +504,10 @@ impl<W: LayoutElement> Workspace<W> { self.output = output; if let Some(output) = &self.output { + let scale = output.current_scale(); + let transform = output.current_transform(); let working_area = compute_working_area(output, self.options.struts); - self.set_view_size(output_size(output), working_area); + self.set_view_size(scale, transform, output_size(output), working_area); for win in self.windows() { self.enter_output_for_window(win); @@ -499,41 +517,45 @@ impl<W: LayoutElement> Workspace<W> { fn enter_output_for_window(&self, window: &W) { if let Some(output) = &self.output { - set_preferred_scale_transform(window, output); + window.set_preferred_scale_transform(self.scale, self.transform); window.output_enter(output); } } pub fn set_view_size( &mut self, + scale: smithay::output::Scale, + transform: Transform, size: Size<i32, Logical>, working_area: Rectangle<i32, Logical>, ) { - if self.view_size == size && self.working_area == working_area { + let scale_transform_changed = self.transform != transform + || self.scale.integer_scale() != scale.integer_scale() + || self.scale.fractional_scale() != scale.fractional_scale(); + if !scale_transform_changed && self.view_size == size && self.working_area == working_area { return; } + self.scale = scale; + self.transform = transform; self.view_size = size; self.working_area = working_area; for col in &mut self.columns { col.set_view_size(self.view_size, self.working_area); } + + if scale_transform_changed { + for window in self.windows() { + window.set_preferred_scale_transform(self.scale, self.transform); + } + } } pub fn view_size(&self) -> Size<i32, Logical> { self.view_size } - pub fn update_output_scale_transform(&mut self) { - let Some(output) = self.output.as_ref() else { - return; - }; - for window in self.windows() { - set_preferred_scale_transform(window, output); - } - } - fn toplevel_bounds(&self, rules: &ResolvedWindowRules) -> Size<i32, Logical> { let border_config = rules.border.resolve_against(self.options.border); compute_toplevel_bounds(border_config, self.working_area.size, self.options.gaps) @@ -585,13 +607,9 @@ impl<W: LayoutElement> Workspace<W> { width: Option<ColumnWidth>, rules: &ResolvedWindowRules, ) { - if let Some(output) = self.output.as_ref() { - let scale = output.current_scale(); - let transform = output.current_transform(); - window.with_surfaces(|surface, data| { - send_scale_transform(surface, data, scale, transform); - }); - } + window.with_surfaces(|surface, data| { + send_scale_transform(surface, data, self.scale, self.transform); + }); window .toplevel() @@ -1367,14 +1385,7 @@ impl<W: LayoutElement> Workspace<W> { } pub fn store_unmap_snapshot_if_empty(&mut self, renderer: &mut GlesRenderer, window: &W::Id) { - // FIXME: workspaces should probably cache their last used scale so they can be correctly - // rendered even with no outputs connected. - let output_scale = self - .output - .as_ref() - .map(|o| Scale::from(o.current_scale().fractional_scale())) - .unwrap_or(Scale::from(1.)); - + let output_scale = Scale::from(self.scale.fractional_scale()); let view_size = self.view_size(); for (tile, tile_pos) in self.tiles_with_render_positions_mut() { if tile.window().id() == window { @@ -1403,13 +1414,7 @@ impl<W: LayoutElement> Workspace<W> { renderer: &mut GlesRenderer, window: &W::Id, ) { - // FIXME: workspaces should probably cache their last used scale so they can be correctly - // rendered even with no outputs connected. - let output_scale = self - .output - .as_ref() - .map(|o| Scale::from(o.current_scale().fractional_scale())) - .unwrap_or(Scale::from(1.)); + let output_scale = Scale::from(self.scale.fractional_scale()); let (tile, mut tile_pos) = self .tiles_with_render_positions_mut() @@ -1472,6 +1477,8 @@ impl<W: LayoutElement> Workspace<W> { pub fn verify_invariants(&self) { assert!(self.view_size.w > 0); assert!(self.view_size.h > 0); + assert!(self.scale.fractional_scale() > 0.); + assert!(self.scale.fractional_scale().is_finite()); assert_eq!(self.columns.len(), self.data.len()); if !self.columns.is_empty() { @@ -2243,13 +2250,7 @@ impl<W: LayoutElement> Workspace<W> { renderer: &mut R, target: RenderTarget, ) -> Vec<WorkspaceRenderElement<R>> { - // FIXME: workspaces should probably cache their last used scale so they can be correctly - // rendered even with no outputs connected. - let output_scale = self - .output - .as_ref() - .map(|o| Scale::from(o.current_scale().fractional_scale())) - .unwrap_or(Scale::from(1.)); + let output_scale = Scale::from(self.scale.fractional_scale()); let mut rv = vec![]; @@ -3386,13 +3387,6 @@ fn compute_new_view_offset( } } -fn set_preferred_scale_transform(window: &impl LayoutElement, output: &Output) { - // FIXME: cache this on the workspace. - let scale = output.current_scale(); - let transform = output.current_transform(); - window.set_preferred_scale_transform(scale, transform); -} - pub fn compute_working_area(output: &Output, struts: Struts) -> Rectangle<i32, Logical> { // Start with the layer-shell non-exclusive zone. let mut working_area = layer_map_for_output(output).non_exclusive_zone(); |
