use std::fmt::Write as _;
use insta::assert_snapshot;
use niri_config::animations::{Curve, EasingParams, Kind};
use super::*;
fn format_tiles(layout: &Layout<TestWindow>) -> String {
let mut buf = String::new();
let ws = layout.active_workspace().unwrap();
let mut tiles: Vec<_> = ws.tiles_with_render_positions().collect();
// We sort by id since that gives us a consistent order (from first opened to last), but we
// don't print the id since it's nondeterministic (the id is a global counter across all
// running tests in the same binary).
tiles.sort_by_key(|(tile, _, _)| tile.window().id());
for (tile, pos, _visible) in tiles {
let Size { w, h, .. } = tile.animated_tile_size();
let Point { x, y, .. } = pos;
writeln!(&mut buf, "{w:>3.0} × {h:>3.0} at x:{x:>3.0} y:{y:>3.0}").unwrap();
}
buf
}
fn make_options() -> Options {
const LINEAR: Kind = Kind::Easing(EasingParams {
duration_ms: 1000,
curve: Curve::Linear,
});
let mut options = Options {
layout: niri_config::Layout {
gaps: 0.0,
..Default::default()
},
..Options::default()
};
options.animations.window_resize.anim.kind = LINEAR;
options.animations.window_movement.0.kind = LINEAR;
options
}
fn set_up_two_in_column() -> Layout<TestWindow> {
let ops = [
Op::AddOutput(1),
Op::AddWindow {
params: TestWindowParams::new(1),
},
Op::AddWindow {
params: TestWindowParams::new(2),
},
Op::FocusColumnLeft,
Op::ConsumeWindowIntoColumn,
Op::SetForcedSize {
id: 1,
size: Some(Size::new(100, 100)),
},
Op::SetForcedSize {
id: 2,
size: Some(Size::new(200, 200)),
},
Op::Communicate(1),
Op::Communicate(2),
Op::CompleteAnimations,
];
check_ops_with_options(make_options(), ops)
}
#[test]
fn height_resize_animates_next_y() {
let mut layout = set_up_two_in_column();
let ops = [
// Issue a resize.
Op::SetWindowHeight {
id: None,
change: SizeChange::AdjustFixed(-50),
},
// The top window shrinks in response, the bottom remains as is.
Op::SetForcedSize {
id: 1,
size: Some(Size::new(100, 50)),
},
Op::Communicate(1),
Op::Communicate(2),
];
check_ops_on_layout(&mut layout, ops);
// No time had passed yet, so we're at the initial state.
assert_snapshot!(format_tiles(&layout), @r"
100 × 100 at x: 0 y: 0
200 × 200 at x: 0 y:100
");
// Advance the time halfway.
Op::AdvanceAnimations { msec_delta: 500 }.apply(&mut layout);
// Top window is half-resized at 75 px tall, bottom window is at y=75 matching it.
assert_snapshot!(format_tiles(&layout), @r"
100 × 75 at x: 0 y: 0
200 × 200 at x: 0 y: 75
");
// Advance the time to completion.
Op::AdvanceAnimations { msec_delta: 500 }.apply(&mut layout);
// Final state at 50 px.
assert_snapshot!(format_tiles(&layout), @r"
100 × 50 at x: 0 y: 0
200 Ã