diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-17 09:16:28 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-06-18 14:01:28 +0300 |
| commit | 1dae45c58d7eabeda21ef490d712915890bf6cff (patch) | |
| tree | 62c473ab1662a1161ed522517ea57b7bd8db340c /src/layout/monitor.rs | |
| parent | 997119c44338ad96a40b4a1d6e958f77062a37ef (diff) | |
| download | niri-1dae45c58d7eabeda21ef490d712915890bf6cff.tar.gz niri-1dae45c58d7eabeda21ef490d712915890bf6cff.tar.bz2 niri-1dae45c58d7eabeda21ef490d712915890bf6cff.zip | |
Refactor layout to fractional-logical
Lets borders, gaps, and everything else stay pixel-perfect even with
fractional scale. Allows setting fractional border widths, gaps,
struts.
See the new wiki .md for more details.
Diffstat (limited to 'src/layout/monitor.rs')
| -rw-r--r-- | src/layout/monitor.rs | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs index b166879b..eb72242f 100644 --- a/src/layout/monitor.rs +++ b/src/layout/monitor.rs @@ -7,7 +7,7 @@ use smithay::backend::renderer::element::utils::{ CropRenderElement, Relocate, RelocateRenderElement, }; use smithay::output::Output; -use smithay::utils::{Logical, Point, Rectangle, Scale}; +use smithay::utils::{Logical, Point, Rectangle}; use super::workspace::{ compute_working_area, Column, ColumnWidth, OutputId, Workspace, WorkspaceId, @@ -19,7 +19,7 @@ use crate::input::swipe_tracker::SwipeTracker; use crate::render_helpers::renderer::NiriRenderer; use crate::render_helpers::RenderTarget; use crate::rubber_band::RubberBand; -use crate::utils::{output_size, ResizeEdge}; +use crate::utils::{output_size, to_physical_precise_round, ResizeEdge}; /// Amount of touchpad movement to scroll the height of one workspace. const WORKSPACE_GESTURE_MOVEMENT: f64 = 300.; @@ -761,16 +761,16 @@ impl<W: LayoutElement> Monitor<W> { /// Returns the geometry of the active tile relative to and clamped to the output. /// /// During animations, assumes the final view position. - pub fn active_tile_visual_rectangle(&self) -> Option<Rectangle<i32, Logical>> { + pub fn active_tile_visual_rectangle(&self) -> Option<Rectangle<f64, Logical>> { let mut rect = self.active_workspace_ref().active_tile_visual_rectangle()?; if let Some(switch) = &self.workspace_switch { - let size = output_size(&self.output); + let size = output_size(&self.output).to_f64(); let offset = switch.target_idx() - self.active_workspace_idx as f64; - let offset = (offset * size.h as f64).round() as i32; + let offset = offset * size.h; - let clip_rect = Rectangle::from_loc_and_size((0, -offset), size); + let clip_rect = Rectangle::from_loc_and_size((0., -offset), size); rect = rect.intersection(clip_rect)?; } @@ -780,16 +780,16 @@ impl<W: LayoutElement> Monitor<W> { pub fn window_under( &self, pos_within_output: Point<f64, Logical>, - ) -> Option<(&W, Option<Point<i32, Logical>>)> { + ) -> Option<(&W, Option<Point<f64, Logical>>)> { match &self.workspace_switch { Some(switch) => { - let size = output_size(&self.output); + let size = output_size(&self.output).to_f64(); let render_idx = switch.current_idx(); let before_idx = render_idx.floor(); let after_idx = render_idx.ceil(); - let offset = ((render_idx - before_idx) * size.h as f64).round() as i32; + let offset = (render_idx - before_idx) * size.h; if after_idx < 0. || before_idx as usize >= self.workspaces.len() { return None; @@ -797,22 +797,22 @@ impl<W: LayoutElement> Monitor<W> { let after_idx = after_idx as usize; - let (idx, ws_offset) = if pos_within_output.y < (size.h - offset) as f64 { + let (idx, ws_offset) = if pos_within_output.y < size.h - offset { if before_idx < 0. { return None; } - (before_idx as usize, Point::from((0, offset))) + (before_idx as usize, Point::from((0., offset))) } else { if after_idx >= self.workspaces.len() { return None; } - (after_idx, Point::from((0, -size.h + offset))) + (after_idx, Point::from((0., -size.h + offset))) }; let ws = &self.workspaces[idx]; - let (win, win_pos) = ws.window_under(pos_within_output + ws_offset.to_f64())?; + let (win, win_pos) = ws.window_under(pos_within_output + ws_offset)?; Some((win, win_pos.map(|p| p - ws_offset))) } None => { @@ -831,7 +831,7 @@ impl<W: LayoutElement> Monitor<W> { let before_idx = render_idx.floor(); let after_idx = render_idx.ceil(); - let offset = ((render_idx - before_idx) * size.h as f64).round() as i32; + let offset = (render_idx - before_idx) * size.h; if after_idx < 0. || before_idx as usize >= self.workspaces.len() { return None; @@ -839,22 +839,22 @@ impl<W: LayoutElement> Monitor<W> { let after_idx = after_idx as usize; - let (idx, ws_offset) = if pos_within_output.y < (size.h - offset) as f64 { + let (idx, ws_offset) = if pos_within_output.y < size.h - offset { if before_idx < 0. { return None; } - (before_idx as usize, Point::from((0, offset))) + (before_idx as usize, Point::from((0., offset))) } else { if after_idx >= self.workspaces.len() { return None; } - (after_idx, Point::from((0, -size.h + offset))) + (after_idx, Point::from((0., -size.h + offset))) }; let ws = &self.workspaces[idx]; - ws.resize_edges_under(pos_within_output + ws_offset.to_f64()) + ws.resize_edges_under(pos_within_output + ws_offset) } None => { let ws = &self.workspaces[self.active_workspace_idx]; @@ -880,10 +880,8 @@ impl<W: LayoutElement> Monitor<W> { ) -> Vec<MonitorRenderElement<R>> { let _span = tracy_client::span!("Monitor::render_elements"); - let output_scale = Scale::from(self.output.current_scale().fractional_scale()); - let output_transform = self.output.current_transform(); - let output_mode = self.output.current_mode().unwrap(); - let size = output_transform.transform_size(output_mode.size); + let scale = self.output.current_scale().fractional_scale(); + let size = output_size(&self.output); match &self.workspace_switch { Some(switch) => { @@ -891,7 +889,7 @@ impl<W: LayoutElement> Monitor<W> { let before_idx = render_idx.floor(); let after_idx = render_idx.ceil(); - let offset = ((render_idx - before_idx) * size.h as f64).round() as i32; + let offset = (render_idx - before_idx) * size.h; if after_idx < 0. || before_idx as usize >= self.workspaces.len() { return vec![]; @@ -904,7 +902,7 @@ impl<W: LayoutElement> Monitor<W> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - output_scale, + scale, // HACK: crop to infinite bounds for all sides except the side // where the workspaces join, // otherwise it will cut pixel shaders and mess up @@ -914,7 +912,7 @@ impl<W: LayoutElement> Monitor<W> { (i32::MAX / 2, i32::MAX / 2), ), )?, - (0, -offset + size.h), + Point::from((0., -offset + size.h)).to_physical_precise_round(scale), Relocate::Relative, )) }); @@ -934,13 +932,13 @@ impl<W: LayoutElement> Monitor<W> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - output_scale, + scale, Rectangle::from_extemities( (-i32::MAX / 2, -i32::MAX / 2), - (i32::MAX / 2, size.h), + (i32::MAX / 2, to_physical_precise_round(scale, size.h)), ), )?, - (0, -offset), + Point::from((0., -offset)).to_physical_precise_round(scale), Relocate::Relative, )) }); @@ -955,7 +953,7 @@ impl<W: LayoutElement> Monitor<W> { Some(RelocateRenderElement::from_element( CropRenderElement::from_element( elem, - output_scale, + scale, // HACK: set infinite crop bounds due to a damage tracking bug // which causes glitched rendering for maximized GTK windows. // FIXME: use proper bounds after fixing the Crop element. |
