From 1dae45c58d7eabeda21ef490d712915890bf6cff Mon Sep 17 00:00:00 2001 From: Ivan Molodetskikh Date: Mon, 17 Jun 2024 09:16:28 +0300 Subject: 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. --- src/layout/monitor.rs | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'src/layout/monitor.rs') 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 Monitor { /// 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> { + pub fn active_tile_visual_rectangle(&self) -> Option> { 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 Monitor { pub fn window_under( &self, pos_within_output: Point, - ) -> Option<(&W, Option>)> { + ) -> Option<(&W, Option>)> { 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 Monitor { 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 Monitor { 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 Monitor { 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 Monitor { ) -> Vec> { 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 Monitor { 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 Monitor { 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 Monitor { (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 Monitor { 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 Monitor { 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. -- cgit