aboutsummaryrefslogtreecommitdiff
path: root/src/layout/monitor.rs
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-06-17 09:16:28 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2024-06-18 14:01:28 +0300
commit1dae45c58d7eabeda21ef490d712915890bf6cff (patch)
tree62c473ab1662a1161ed522517ea57b7bd8db340c /src/layout/monitor.rs
parent997119c44338ad96a40b4a1d6e958f77062a37ef (diff)
downloadniri-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.rs56
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.