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. --- niri-visual-tests/src/cases/gradient_angle.rs | 6 +++--- niri-visual-tests/src/cases/gradient_area.rs | 16 +++++++++------- niri-visual-tests/src/cases/layout.rs | 4 ++-- niri-visual-tests/src/cases/tile.rs | 21 +++++++++++---------- niri-visual-tests/src/cases/window.rs | 4 +++- 5 files changed, 28 insertions(+), 23 deletions(-) (limited to 'niri-visual-tests/src/cases') diff --git a/niri-visual-tests/src/cases/gradient_angle.rs b/niri-visual-tests/src/cases/gradient_angle.rs index f9871a93..203f31b1 100644 --- a/niri-visual-tests/src/cases/gradient_angle.rs +++ b/niri-visual-tests/src/cases/gradient_angle.rs @@ -59,15 +59,15 @@ impl TestCase for GradientAngle { ) -> Vec>> { let (a, b) = (size.w / 4, size.h / 4); let size = (size.w - a * 2, size.h - b * 2); - let area = Rectangle::from_loc_and_size((a, b), size); + let area = Rectangle::from_loc_and_size((a, b), size).to_f64(); [BorderRenderElement::new( area.size, - Rectangle::from_loc_and_size((0, 0), area.size), + Rectangle::from_loc_and_size((0., 0.), area.size), [1., 0., 0., 1.], [0., 1., 0., 1.], self.angle - FRAC_PI_2, - Rectangle::from_loc_and_size((0, 0), area.size), + Rectangle::from_loc_and_size((0., 0.), area.size), 0., CornerRadius::default(), ) diff --git a/niri-visual-tests/src/cases/gradient_area.rs b/niri-visual-tests/src/cases/gradient_area.rs index b6741575..e76820fd 100644 --- a/niri-visual-tests/src/cases/gradient_area.rs +++ b/niri-visual-tests/src/cases/gradient_area.rs @@ -5,10 +5,10 @@ use std::time::Duration; use niri::animation::ANIMATION_SLOWDOWN; use niri::layout::focus_ring::FocusRing; use niri::render_helpers::border::BorderRenderElement; -use niri_config::{Color, CornerRadius}; +use niri_config::{Color, CornerRadius, FloatOrInt}; use smithay::backend::renderer::element::RenderElement; use smithay::backend::renderer::gles::GlesRenderer; -use smithay::utils::{Logical, Physical, Point, Rectangle, Scale, Size}; +use smithay::utils::{Logical, Physical, Point, Rectangle, Size}; use super::TestCase; @@ -22,7 +22,7 @@ impl GradientArea { pub fn new(_size: Size) -> Self { let border = FocusRing::new(niri_config::FocusRing { off: false, - width: 1, + width: FloatOrInt(1.), active_color: Color::new(255, 255, 255, 128), inactive_color: Color::default(), active_gradient: None, @@ -75,13 +75,14 @@ impl TestCase for GradientArea { let (a, b) = (size.w / 4, size.h / 4); let rect_size = (size.w - a * 2, size.h - b * 2); - let area = Rectangle::from_loc_and_size((a, b), rect_size); + let area = Rectangle::from_loc_and_size((a, b), rect_size).to_f64(); let g_size = Size::from(( (size.w as f32 / 8. + size.w as f32 / 8. * 7. * f).round() as i32, (size.h as f32 / 8. + size.h as f32 / 8. * 7. * f).round() as i32, )); - let g_loc = ((size.w - g_size.w) / 2, (size.h - g_size.h) / 2); + let g_loc = Point::from(((size.w - g_size.w) / 2, (size.h - g_size.h) / 2)).to_f64(); + let g_size = g_size.to_f64(); let mut g_area = Rectangle::from_loc_and_size(g_loc, g_size); g_area.loc -= area.loc; @@ -91,10 +92,11 @@ impl TestCase for GradientArea { true, Rectangle::default(), CornerRadius::default(), + 1., ); rv.extend( self.border - .render(renderer, Point::from(g_loc), Scale::from(1.)) + .render(renderer, g_loc) .map(|elem| Box::new(elem) as _), ); @@ -105,7 +107,7 @@ impl TestCase for GradientArea { [1., 0., 0., 1.], [0., 1., 0., 1.], FRAC_PI_4, - Rectangle::from_loc_and_size((0, 0), rect_size), + Rectangle::from_loc_and_size((0, 0), rect_size).to_f64(), 0., CornerRadius::default(), ) diff --git a/niri-visual-tests/src/cases/layout.rs b/niri-visual-tests/src/cases/layout.rs index d7872173..2e730dbe 100644 --- a/niri-visual-tests/src/cases/layout.rs +++ b/niri-visual-tests/src/cases/layout.rs @@ -5,7 +5,7 @@ use niri::layout::workspace::ColumnWidth; use niri::layout::{LayoutElement as _, Options}; use niri::render_helpers::RenderTarget; use niri::utils::get_monotonic_time; -use niri_config::Color; +use niri_config::{Color, FloatOrInt}; use smithay::backend::renderer::element::RenderElement; use smithay::backend::renderer::gles::GlesRenderer; use smithay::desktop::layer_map_for_output; @@ -49,7 +49,7 @@ impl Layout { }, border: niri_config::Border { off: false, - width: 4, + width: FloatOrInt(4.), active_color: Color::new(255, 163, 72, 255), inactive_color: Color::new(50, 50, 50, 255), active_gradient: None, diff --git a/niri-visual-tests/src/cases/tile.rs b/niri-visual-tests/src/cases/tile.rs index 301fc19f..95261877 100644 --- a/niri-visual-tests/src/cases/tile.rs +++ b/niri-visual-tests/src/cases/tile.rs @@ -3,7 +3,7 @@ use std::time::Duration; use niri::layout::Options; use niri::render_helpers::RenderTarget; -use niri_config::Color; +use niri_config::{Color, FloatOrInt}; use smithay::backend::renderer::element::RenderElement; use smithay::backend::renderer::gles::GlesRenderer; use smithay::utils::{Logical, Physical, Point, Rectangle, Scale, Size}; @@ -20,7 +20,7 @@ impl Tile { pub fn freeform(size: Size) -> Self { let window = TestWindow::freeform(0); let mut rv = Self::with_window(window); - rv.tile.request_tile_size(size, false); + rv.tile.request_tile_size(size.to_f64(), false); rv.window.communicate(); rv } @@ -28,7 +28,7 @@ impl Tile { pub fn fixed_size(size: Size) -> Self { let window = TestWindow::fixed_size(0); let mut rv = Self::with_window(window); - rv.tile.request_tile_size(size, false); + rv.tile.request_tile_size(size.to_f64(), false); rv.window.communicate(); rv } @@ -37,7 +37,7 @@ impl Tile { let window = TestWindow::fixed_size(0); window.set_csd_shadow_width(64); let mut rv = Self::with_window(window); - rv.tile.request_tile_size(size, false); + rv.tile.request_tile_size(size.to_f64(), false); rv.window.communicate(); rv } @@ -71,13 +71,13 @@ impl Tile { }, border: niri_config::Border { off: false, - width: 32, + width: FloatOrInt(32.), active_color: Color::new(255, 163, 72, 255), ..Default::default() }, ..Default::default() }; - let tile = niri::layout::tile::Tile::new(window.clone(), Rc::new(options)); + let tile = niri::layout::tile::Tile::new(window.clone(), 1., Rc::new(options)); Self { window, tile } } } @@ -85,7 +85,7 @@ impl Tile { impl TestCase for Tile { fn resize(&mut self, width: i32, height: i32) { self.tile - .request_tile_size(Size::from((width, height)), false); + .request_tile_size(Size::from((width, height)).to_f64(), false); self.window.communicate(); } @@ -102,12 +102,13 @@ impl TestCase for Tile { renderer: &mut GlesRenderer, size: Size, ) -> Vec>> { - let tile_size = self.tile.tile_size().to_physical(1); - let location = Point::from(((size.w - tile_size.w) / 2, (size.h - tile_size.h) / 2)); + let size = size.to_f64(); + let tile_size = self.tile.tile_size().to_physical(1.); + let location = Point::from((size.w - tile_size.w, size.h - tile_size.h)).downscale(2.); self.tile.update( true, - Rectangle::from_loc_and_size((-location.x, -location.y), size.to_logical(1)), + Rectangle::from_loc_and_size((-location.x, -location.y), size.to_logical(1.)), ); self.tile .render( diff --git a/niri-visual-tests/src/cases/window.rs b/niri-visual-tests/src/cases/window.rs index f19ec5ba..be6150d4 100644 --- a/niri-visual-tests/src/cases/window.rs +++ b/niri-visual-tests/src/cases/window.rs @@ -47,7 +47,9 @@ impl TestCase for Window { size: Size, ) -> Vec>> { let win_size = self.window.size().to_physical(1); - let location = Point::from(((size.w - win_size.w) / 2, (size.h - win_size.h) / 2)); + let location = Point::from((size.w - win_size.w, size.h - win_size.h)) + .to_f64() + .downscale(2.); self.window .render( -- cgit