aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--niri-visual-tests/src/cases/tile.rs17
-rw-r--r--src/layout/floating.rs41
-rw-r--r--src/layout/mod.rs6
-rw-r--r--src/layout/scrolling.rs7
-rw-r--r--src/layout/tile.rs71
-rw-r--r--src/layout/workspace.rs7
6 files changed, 105 insertions, 44 deletions
diff --git a/niri-visual-tests/src/cases/tile.rs b/niri-visual-tests/src/cases/tile.rs
index f50edf37..0be80054 100644
--- a/niri-visual-tests/src/cases/tile.rs
+++ b/niri-visual-tests/src/cases/tile.rs
@@ -55,6 +55,8 @@ impl Tile {
}
pub fn with_window(args: Args, window: TestWindow) -> Self {
+ let Args { size, clock } = args;
+
let options = Options {
focus_ring: niri_config::FocusRing {
off: true,
@@ -69,10 +71,15 @@ impl Tile {
..Default::default()
};
- let mut tile =
- niri::layout::tile::Tile::new(window.clone(), 1., args.clock, Rc::new(options));
+ let mut tile = niri::layout::tile::Tile::new(
+ window.clone(),
+ size.to_f64(),
+ 1.,
+ clock,
+ Rc::new(options),
+ );
- tile.request_tile_size(args.size.to_f64(), false, None);
+ tile.request_tile_size(size.to_f64(), false, None);
window.communicate();
Self { window, tile }
@@ -81,8 +88,10 @@ impl Tile {
impl TestCase for Tile {
fn resize(&mut self, width: i32, height: i32) {
+ let size = Size::from((width, height)).to_f64();
self.tile
- .request_tile_size(Size::from((width, height)).to_f64(), false, None);
+ .update_config(size, 1., self.tile.options().clone());
+ self.tile.request_tile_size(size, false, None);
self.window.communicate();
}
diff --git a/src/layout/floating.rs b/src/layout/floating.rs
index 39adf7aa..94831228 100644
--- a/src/layout/floating.rs
+++ b/src/layout/floating.rs
@@ -50,6 +50,9 @@ pub struct FloatingSpace<W: LayoutElement> {
/// Windows in the closing animation.
closing_windows: Vec<ClosingWindow>,
+ /// View size for this space.
+ view_size: Size<f64, Logical>,
+
/// Working area for this space.
working_area: Rectangle<f64, Logical>,
@@ -193,6 +196,7 @@ impl Data {
impl<W: LayoutElement> FloatingSpace<W> {
pub fn new(
+ view_size: Size<f64, Logical>,
working_area: Rectangle<f64, Logical>,
scale: f64,
clock: Clock,
@@ -204,6 +208,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
active_window_id: None,
interactive_resize: None,
closing_windows: Vec::new(),
+ view_size,
working_area,
scale,
clock,
@@ -213,16 +218,18 @@ impl<W: LayoutElement> FloatingSpace<W> {
pub fn update_config(
&mut self,
+ view_size: Size<f64, Logical>,
working_area: Rectangle<f64, Logical>,
scale: f64,
options: Rc<Options>,
) {
for (tile, data) in zip(&mut self.tiles, &mut self.data) {
- tile.update_config(scale, options.clone());
+ tile.update_config(view_size, scale, options.clone());
data.update(tile);
data.update_config(working_area);
}
+ self.view_size = view_size;
self.working_area = working_area;
self.scale = scale;
self.options = options;
@@ -371,7 +378,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
}
fn add_tile_at(&mut self, mut idx: usize, mut tile: Tile<W>, activate: bool) {
- tile.update_config(self.scale, self.options.clone());
+ tile.update_config(self.view_size, self.scale, self.options.clone());
// Restore the previous floating window size, and in case the tile is fullscreen,
// unfullscreen it.
@@ -602,7 +609,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
};
let idx = self.idx_of(&id).unwrap();
- let view_size = self.working_area.size.w;
+ let available_size = self.working_area.size.w;
let tile = &mut self.tiles[idx];
let preset_idx = if let Some(idx) = tile.floating_preset_width_idx {
@@ -615,7 +622,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
.preset_column_widths
.iter()
.position(|preset| {
- let resolved = preset.resolve_no_gaps(&self.options, view_size);
+ let resolved = preset.resolve_no_gaps(&self.options, available_size);
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => current_tile + 1. < resolved,
@@ -643,7 +650,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
};
let idx = self.idx_of(&id).unwrap();
- let view_size = self.working_area.size.h;
+ let available_size = self.working_area.size.h;
let tile = &mut self.tiles[idx];
let preset_idx = if let Some(idx) = tile.floating_preset_height_idx {
@@ -656,7 +663,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
.preset_window_heights
.iter()
.position(|preset| {
- let resolved = resolve_preset_size(*preset, view_size);
+ let resolved = resolve_preset_size(*preset, available_size);
match resolved {
// Some allowance for fractional scaling purposes.
ResolvedSize::Tile(resolved) => current_tile + 1. < resolved,
@@ -687,7 +694,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
let tile = &mut self.tiles[idx];
tile.floating_preset_width_idx = None;
- let view_size = self.working_area.size.w;
+ let available_size = self.working_area.size.w;
let win = tile.window();
let current_window = win.expected_size().unwrap_or_else(|| win.size()).w;
let current_tile = tile.tile_expected_or_current_size().w;
@@ -699,14 +706,14 @@ impl<W: LayoutElement> FloatingSpace<W> {
SizeChange::SetFixed(win_width) => f64::from(win_width),
SizeChange::SetProportion(prop) => {
let prop = (prop / 100.).clamp(0., MAX_F);
- let tile_width = view_size * prop;
+ let tile_width = available_size * prop;
tile.window_width_for_tile_width(tile_width)
}
SizeChange::AdjustFixed(delta) => f64::from(current_window.saturating_add(delta)),
SizeChange::AdjustProportion(delta) => {
- let current_prop = current_tile / view_size;
+ let current_prop = current_tile / available_size;
let prop = (current_prop + delta / 100.).clamp(0., MAX_F);
- let tile_width = view_size * prop;
+ let tile_width = available_size * prop;
tile.window_width_for_tile_width(tile_width)
}
};
@@ -734,7 +741,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
let tile = &mut self.tiles[idx];
tile.floating_preset_width_idx = None;
- let view_size = self.working_area.size.h;
+ let available_size = self.working_area.size.h;
let win = tile.window();
let current_window = win.expected_size().unwrap_or_else(|| win.size()).h;
let current_tile = tile.tile_expected_or_current_size().h;
@@ -746,14 +753,14 @@ impl<W: LayoutElement> FloatingSpace<W> {
SizeChange::SetFixed(win_height) => f64::from(win_height),
SizeChange::SetProportion(prop) => {
let prop = (prop / 100.).clamp(0., MAX_F);
- let tile_height = view_size * prop;
+ let tile_height = available_size * prop;
tile.window_height_for_tile_height(tile_height)
}
SizeChange::AdjustFixed(delta) => f64::from(current_window.saturating_add(delta)),
SizeChange::AdjustProportion(delta) => {
- let current_prop = current_tile / view_size;
+ let current_prop = current_tile / available_size;
let prop = (current_prop + delta / 100.).clamp(0., MAX_F);
- let tile_height = view_size * prop;
+ let tile_height = available_size * prop;
tile.window_height_for_tile_height(tile_height)
}
};
@@ -1096,6 +1103,11 @@ impl<W: LayoutElement> FloatingSpace<W> {
}
#[cfg(test)]
+ pub fn view_size(&self) -> Size<f64, Logical> {
+ self.view_size
+ }
+
+ #[cfg(test)]
pub fn working_area(&self) -> Rectangle<f64, Logical> {
self.working_area
}
@@ -1123,6 +1135,7 @@ impl<W: LayoutElement> FloatingSpace<W> {
for (i, (tile, data)) in zip(&self.tiles, &self.data).enumerate() {
assert!(Rc::ptr_eq(&self.options, &tile.options));
+ assert_eq!(self.view_size, tile.view_size());
assert_eq!(self.clock, tile.clock);
assert_eq!(self.scale, tile.scale());
tile.verify_invariants();
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 53549154..691140a2 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -2577,8 +2577,10 @@ impl<W: LayoutElement> Layout<W> {
let options = Rc::new(options);
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
+ let view_size = output_size(&move_.output);
let scale = move_.output.current_scale().fractional_scale();
move_.tile.update_config(
+ view_size,
scale,
Rc::new(Options::clone(&options).adjusted_for_scale(scale)),
);
@@ -3261,8 +3263,10 @@ impl<W: LayoutElement> Layout<W> {
output.current_transform(),
);
+ let view_size = output_size(&output);
let scale = output.current_scale().fractional_scale();
tile.update_config(
+ view_size,
scale,
Rc::new(Options::clone(&self.options).adjusted_for_scale(scale)),
);
@@ -3324,8 +3328,10 @@ impl<W: LayoutElement> Layout<W> {
output.current_scale(),
output.current_transform(),
);
+ let view_size = output_size(&output);
let scale = output.current_scale().fractional_scale();
move_.tile.update_config(
+ view_size,
scale,
Rc::new(Options::clone(&self.options).adjusted_for_scale(scale)),
);
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs
index 7cb01218..b7b7b84a 100644
--- a/src/layout/scrolling.rs
+++ b/src/layout/scrolling.rs
@@ -2933,7 +2933,7 @@ impl<W: LayoutElement> Column<W> {
}
for (tile, data) in zip(&mut self.tiles, &mut self.data) {
- tile.update_config(scale, options.clone());
+ tile.update_config(view_size, scale, options.clone());
data.update(tile);
}
@@ -3033,7 +3033,7 @@ impl<W: LayoutElement> Column<W> {
}
fn add_tile_at(&mut self, idx: usize, mut tile: Tile<W>, animate: bool) {
- tile.update_config(self.scale, self.options.clone());
+ tile.update_config(self.view_size, self.scale, self.options.clone());
// Inserting a tile pushes down all tiles below it, but also in always-centering mode it
// will affect the X position of all tiles in the column.
@@ -3096,7 +3096,7 @@ impl<W: LayoutElement> Column<W> {
fn update_tile_sizes_with_transaction(&mut self, animate: bool, transaction: Transaction) {
if self.is_fullscreen {
- self.tiles[0].request_fullscreen(self.view_size);
+ self.tiles[0].request_fullscreen();
return;
}
@@ -3787,6 +3787,7 @@ impl<W: LayoutElement> Column<W> {
assert_eq!(self.clock, tile.clock);
assert_eq!(self.scale, tile.scale());
assert_eq!(self.is_fullscreen, tile.window().is_pending_fullscreen());
+ assert_eq!(self.view_size, tile.view_size());
tile.verify_invariants();
let mut data2 = *data;
diff --git a/src/layout/tile.rs b/src/layout/tile.rs
index fac2c5c4..96936d26 100644
--- a/src/layout/tile.rs
+++ b/src/layout/tile.rs
@@ -48,9 +48,6 @@ pub struct Tile<W: LayoutElement> {
/// The black backdrop for fullscreen windows.
fullscreen_backdrop: SolidColorBuffer,
- /// The size we were requested to fullscreen into.
- fullscreen_size: Size<f64, Logical>,
-
/// Whether the tile should float upon unfullscreening.
pub(super) unfullscreen_to_floating: bool,
@@ -94,6 +91,11 @@ pub struct Tile<W: LayoutElement> {
/// Extra damage for clipped surface corner radius changes.
rounded_corner_damage: RoundedCornerDamage,
+ /// The view size for the tile's workspace.
+ ///
+ /// Used as the fullscreen target size.
+ view_size: Size<f64, Logical>,
+
/// Scale of the output the tile is on (and rounds its sizes to).
scale: f64,
@@ -134,18 +136,24 @@ struct MoveAnimation {
}
impl<W: LayoutElement> Tile<W> {
- pub fn new(window: W, scale: f64, clock: Clock, options: Rc<Options>) -> Self {
+ pub fn new(
+ window: W,
+ view_size: Size<f64, Logical>,
+ scale: f64,
+ clock: Clock,
+ options: Rc<Options>,
+ ) -> Self {
let rules = window.rules();
let border_config = rules.border.resolve_against(options.border);
let focus_ring_config = rules.focus_ring.resolve_against(options.focus_ring.into());
+ let is_fullscreen = window.is_fullscreen();
Self {
window,
border: FocusRing::new(border_config.into()),
focus_ring: FocusRing::new(focus_ring_config.into()),
- is_fullscreen: false, // FIXME: up-to-date fullscreen right away, but we need size.
- fullscreen_backdrop: SolidColorBuffer::new((0., 0.), [0., 0., 0., 1.]),
- fullscreen_size: Default::default(),
+ is_fullscreen,
+ fullscreen_backdrop: SolidColorBuffer::new(view_size, [0., 0., 0., 1.]),
unfullscreen_to_floating: false,
floating_window_size: None,
floating_pos: None,
@@ -158,13 +166,19 @@ impl<W: LayoutElement> Tile<W> {
interactive_move_offset: Point::from((0., 0.)),
unmap_snapshot: None,
rounded_corner_damage: Default::default(),
+ view_size,
scale,
clock,
options,
}
}
- pub fn update_config(&mut self, scale: f64, options: Rc<Options>) {
+ pub fn update_config(
+ &mut self,
+ view_size: Size<f64, Logical>,
+ scale: f64,
+ options: Rc<Options>,
+ ) {
// If preset widths or heights changed, clear our stored preset index.
if self.options.preset_column_widths != options.preset_column_widths {
self.floating_preset_width_idx = None;
@@ -173,6 +187,7 @@ impl<W: LayoutElement> Tile<W> {
self.floating_preset_height_idx = None;
}
+ self.view_size = view_size;
self.scale = scale;
self.options = options;
@@ -185,6 +200,8 @@ impl<W: LayoutElement> Tile<W> {
.focus_ring
.resolve_against(self.options.focus_ring.into());
self.focus_ring.update_config(focus_ring_config.into());
+
+ self.fullscreen_backdrop.resize(view_size);
}
pub fn update_shaders(&mut self) {
@@ -193,10 +210,7 @@ impl<W: LayoutElement> Tile<W> {
}
pub fn update_window(&mut self) {
- // FIXME: remove when we can get a fullscreen size right away.
- if self.fullscreen_size != Size::from((0., 0.)) {
- self.is_fullscreen = self.window.is_fullscreen();
- }
+ self.is_fullscreen = self.window.is_fullscreen();
if let Some(animate_from) = self.window.take_animation_snapshot() {
let size_from = if let Some(resize) = self.resize_animation.take() {
@@ -448,7 +462,7 @@ impl<W: LayoutElement> Tile<W> {
// In fullscreen, center the window in the given size.
if self.is_fullscreen {
let window_size = self.window_size();
- let target_size = self.fullscreen_size;
+ let target_size = self.view_size;
// Windows aren't supposed to be larger than the fullscreen size, but in case we get
// one, leave it at the top-left as usual.
@@ -478,8 +492,8 @@ impl<W: LayoutElement> Tile<W> {
if self.is_fullscreen {
// Normally we'd just return the fullscreen size here, but this makes things a bit
// nicer if a fullscreen window is bigger than the fullscreen size for some reason.
- size.w = f64::max(size.w, self.fullscreen_size.w);
- size.h = f64::max(size.h, self.fullscreen_size.h);
+ size.w = f64::max(size.w, self.view_size.w);
+ size.h = f64::max(size.h, self.view_size.h);
return size;
}
@@ -497,8 +511,8 @@ impl<W: LayoutElement> Tile<W> {
if self.is_fullscreen {
// Normally we'd just return the fullscreen size here, but this makes things a bit
// nicer if a fullscreen window is bigger than the fullscreen size for some reason.
- size.w = f64::max(size.w, self.fullscreen_size.w);
- size.h = f64::max(size.h, self.fullscreen_size.h);
+ size.w = f64::max(size.w, self.view_size.w);
+ size.h = f64::max(size.h, self.view_size.h);
return size;
}
@@ -550,8 +564,8 @@ impl<W: LayoutElement> Tile<W> {
if self.is_fullscreen {
// Normally we'd just return the fullscreen size here, but this makes things a bit
// nicer if a fullscreen window is bigger than the fullscreen size for some reason.
- size.w = f64::max(size.w, self.fullscreen_size.w);
- size.h = f64::max(size.h, self.fullscreen_size.h);
+ size.w = f64::max(size.w, self.view_size.w);
+ size.h = f64::max(size.h, self.view_size.h);
return size;
}
@@ -632,10 +646,9 @@ impl<W: LayoutElement> Tile<W> {
}
}
- pub fn request_fullscreen(&mut self, size: Size<f64, Logical>) {
- self.fullscreen_backdrop.resize(size);
- self.fullscreen_size = size;
- self.window.request_fullscreen(size.to_i32_round());
+ pub fn request_fullscreen(&mut self) {
+ self.window
+ .request_fullscreen(self.view_size.to_i32_round());
}
pub fn min_size(&self) -> Size<f64, Logical> {
@@ -982,10 +995,22 @@ impl<W: LayoutElement> Tile<W> {
self.unmap_snapshot.take()
}
+ pub fn options(&self) -> &Rc<Options> {
+ &self.options
+ }
+
+ #[cfg(test)]
+ pub fn view_size(&self) -> Size<f64, Logical> {
+ self.view_size
+ }
+
#[cfg(test)]
pub fn verify_invariants(&self) {
use approx::assert_abs_diff_eq;
+ assert_eq!(self.is_fullscreen, self.window.is_fullscreen());
+ assert_eq!(self.fullscreen_backdrop.size(), self.view_size);
+
let scale = self.scale;
let size = self.tile_size();
let rounded = size.to_physical_precise_round(scale).to_logical(scale);
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index e3757ff5..9956a982 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -203,6 +203,7 @@ impl<W: LayoutElement> Workspace<W> {
);
let floating = FloatingSpace::new(
+ view_size,
working_area,
scale.fractional_scale(),
clock.clone(),
@@ -255,6 +256,7 @@ impl<W: LayoutElement> Workspace<W> {
);
let floating = FloatingSpace::new(
+ view_size,
working_area,
scale.fractional_scale(),
clock.clone(),
@@ -337,6 +339,7 @@ impl<W: LayoutElement> Workspace<W> {
);
self.floating.update_config(
+ self.view_size,
self.working_area,
self.scale.fractional_scale(),
options.clone(),
@@ -467,6 +470,7 @@ impl<W: LayoutElement> Workspace<W> {
self.options.clone(),
);
self.floating.update_config(
+ size,
working_area,
scale.fractional_scale(),
self.options.clone(),
@@ -494,6 +498,7 @@ impl<W: LayoutElement> Workspace<W> {
) {
let mut tile = Tile::new(
window,
+ self.view_size,
self.scale.fractional_scale(),
self.clock.clone(),
self.options.clone(),
@@ -562,6 +567,7 @@ impl<W: LayoutElement> Workspace<W> {
) {
let mut tile = Tile::new(
window,
+ self.view_size,
self.scale.fractional_scale(),
self.clock.clone(),
self.options.clone(),
@@ -1471,6 +1477,7 @@ impl<W: LayoutElement> Workspace<W> {
assert!(Rc::ptr_eq(&self.options, self.scrolling.options()));
self.scrolling.verify_invariants(self.working_area);
+ assert_eq!(self.view_size, self.floating.view_size());
assert_eq!(self.working_area, self.floating.working_area());
assert_eq!(&self.clock, self.floating.clock());
assert!(Rc::ptr_eq(&self.options, self.floating.options()));