mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
Separate tile X and Y movement animations
Helps with the jank caused by lack of transactions when consuming to the left/right. Resize triggers a few frames later and restarts the movement. Now it only restarts the vertical and not the horizontal movement.
This commit is contained in:
+52
-18
@@ -57,8 +57,11 @@ pub struct Tile<W: LayoutElement> {
|
|||||||
/// The animation of the window resizing.
|
/// The animation of the window resizing.
|
||||||
resize_animation: Option<ResizeAnimation>,
|
resize_animation: Option<ResizeAnimation>,
|
||||||
|
|
||||||
/// The animation of a tile visually moving.
|
/// The animation of a tile visually moving horizontally.
|
||||||
move_animation: Option<MoveAnimation>,
|
move_x_animation: Option<MoveAnimation>,
|
||||||
|
|
||||||
|
/// The animation of a tile visually moving vertically.
|
||||||
|
move_y_animation: Option<MoveAnimation>,
|
||||||
|
|
||||||
/// Configurable properties of the layout.
|
/// Configurable properties of the layout.
|
||||||
pub options: Rc<Options>,
|
pub options: Rc<Options>,
|
||||||
@@ -99,7 +102,7 @@ struct ResizeAnimation {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct MoveAnimation {
|
struct MoveAnimation {
|
||||||
anim: Animation,
|
anim: Animation,
|
||||||
from: Point<i32, Logical>,
|
from: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: LayoutElement> Tile<W> {
|
impl<W: LayoutElement> Tile<W> {
|
||||||
@@ -113,7 +116,8 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
fullscreen_size: Default::default(),
|
fullscreen_size: Default::default(),
|
||||||
open_animation: None,
|
open_animation: None,
|
||||||
resize_animation: None,
|
resize_animation: None,
|
||||||
move_animation: None,
|
move_x_animation: None,
|
||||||
|
move_y_animation: None,
|
||||||
options,
|
options,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -177,10 +181,16 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(move_) = &mut self.move_animation {
|
if let Some(move_) = &mut self.move_x_animation {
|
||||||
move_.anim.set_current_time(current_time);
|
move_.anim.set_current_time(current_time);
|
||||||
if move_.anim.is_done() {
|
if move_.anim.is_done() {
|
||||||
self.move_animation = None;
|
self.move_x_animation = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some(move_) = &mut self.move_y_animation {
|
||||||
|
move_.anim.set_current_time(current_time);
|
||||||
|
if move_.anim.is_done() {
|
||||||
|
self.move_y_animation = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,14 +216,18 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
pub fn are_animations_ongoing(&self) -> bool {
|
pub fn are_animations_ongoing(&self) -> bool {
|
||||||
self.open_animation.is_some()
|
self.open_animation.is_some()
|
||||||
|| self.resize_animation.is_some()
|
|| self.resize_animation.is_some()
|
||||||
|| self.move_animation.is_some()
|
|| self.move_x_animation.is_some()
|
||||||
|
|| self.move_y_animation.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_offset(&self) -> Point<i32, Logical> {
|
pub fn render_offset(&self) -> Point<i32, Logical> {
|
||||||
let mut offset = Point::from((0., 0.));
|
let mut offset = Point::from((0., 0.));
|
||||||
|
|
||||||
if let Some(move_) = &self.move_animation {
|
if let Some(move_) = &self.move_x_animation {
|
||||||
offset += move_.from.to_f64().upscale(move_.anim.value());
|
offset.x += f64::from(move_.from) * move_.anim.value();
|
||||||
|
}
|
||||||
|
if let Some(move_) = &self.move_y_animation {
|
||||||
|
offset.y += f64::from(move_.from) * move_.anim.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
offset.to_i32_round()
|
offset.to_i32_round()
|
||||||
@@ -237,23 +251,43 @@ impl<W: LayoutElement> Tile<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn animate_move_from(&mut self, from: Point<i32, Logical>) {
|
pub fn animate_move_from(&mut self, from: Point<i32, Logical>) {
|
||||||
self.animate_move_from_with_config(from, self.options.animations.window_movement.0);
|
self.animate_move_x_from(from.x);
|
||||||
|
self.animate_move_y_from(from.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn animate_move_from_with_config(
|
pub fn animate_move_x_from(&mut self, from: i32) {
|
||||||
&mut self,
|
self.animate_move_x_from_with_config(from, self.options.animations.window_movement.0);
|
||||||
from: Point<i32, Logical>,
|
}
|
||||||
config: niri_config::Animation,
|
|
||||||
) {
|
pub fn animate_move_x_from_with_config(&mut self, from: i32, config: niri_config::Animation) {
|
||||||
let current_offset = self.render_offset();
|
let current_offset = self.render_offset().x;
|
||||||
|
|
||||||
// Preserve the previous config if ongoing.
|
// Preserve the previous config if ongoing.
|
||||||
let anim = self.move_animation.take().map(|move_| move_.anim);
|
let anim = self.move_x_animation.take().map(|move_| move_.anim);
|
||||||
let anim = anim
|
let anim = anim
|
||||||
.map(|anim| anim.restarted(1., 0., 0.))
|
.map(|anim| anim.restarted(1., 0., 0.))
|
||||||
.unwrap_or_else(|| Animation::new(1., 0., 0., config));
|
.unwrap_or_else(|| Animation::new(1., 0., 0., config));
|
||||||
|
|
||||||
self.move_animation = Some(MoveAnimation {
|
self.move_x_animation = Some(MoveAnimation {
|
||||||
|
anim,
|
||||||
|
from: from + current_offset,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn animate_move_y_from(&mut self, from: i32) {
|
||||||
|
self.animate_move_y_from_with_config(from, self.options.animations.window_movement.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn animate_move_y_from_with_config(&mut self, from: i32, config: niri_config::Animation) {
|
||||||
|
let current_offset = self.render_offset().y;
|
||||||
|
|
||||||
|
// Preserve the previous config if ongoing.
|
||||||
|
let anim = self.move_y_animation.take().map(|move_| move_.anim);
|
||||||
|
let anim = anim
|
||||||
|
.map(|anim| anim.restarted(1., 0., 0.))
|
||||||
|
.unwrap_or_else(|| Animation::new(1., 0., 0., config));
|
||||||
|
|
||||||
|
self.move_y_animation = Some(MoveAnimation {
|
||||||
anim,
|
anim,
|
||||||
from: from + current_offset,
|
from: from + current_offset,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -920,7 +920,7 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
// Animate movement of other tiles.
|
// Animate movement of other tiles.
|
||||||
let offset_y = column.tile_y(window_idx + 1) - column.tile_y(window_idx);
|
let offset_y = column.tile_y(window_idx + 1) - column.tile_y(window_idx);
|
||||||
for tile in &mut column.tiles[window_idx + 1..] {
|
for tile in &mut column.tiles[window_idx + 1..] {
|
||||||
tile.animate_move_from(Point::from((0, offset_y)));
|
tile.animate_move_y_from(offset_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
let tile = column.tiles.remove(window_idx);
|
let tile = column.tiles.remove(window_idx);
|
||||||
@@ -2323,8 +2323,8 @@ impl<W: LayoutElement> Column<W> {
|
|||||||
// Move windows below in tandem with resizing.
|
// Move windows below in tandem with resizing.
|
||||||
if tile.resize_animation().is_some() && offset != 0 {
|
if tile.resize_animation().is_some() && offset != 0 {
|
||||||
for tile in &mut self.tiles[tile_idx + 1..] {
|
for tile in &mut self.tiles[tile_idx + 1..] {
|
||||||
tile.animate_move_from_with_config(
|
tile.animate_move_y_from_with_config(
|
||||||
Point::from((0, offset)),
|
offset,
|
||||||
self.options.animations.window_resize.0,
|
self.options.animations.window_resize.0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -2525,8 +2525,8 @@ impl<W: LayoutElement> Column<W> {
|
|||||||
|
|
||||||
// Animate the movement.
|
// Animate the movement.
|
||||||
let new_active_y = self.tile_y(new_idx);
|
let new_active_y = self.tile_y(new_idx);
|
||||||
self.tiles[new_idx].animate_move_from(Point::from((0, active_y - new_active_y)));
|
self.tiles[new_idx].animate_move_y_from(active_y - new_active_y);
|
||||||
self.tiles[new_idx + 1].animate_move_from(Point::from((0, active_y - next_y)));
|
self.tiles[new_idx + 1].animate_move_y_from(active_y - next_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_down(&mut self) {
|
fn move_down(&mut self) {
|
||||||
@@ -2546,8 +2546,8 @@ impl<W: LayoutElement> Column<W> {
|
|||||||
|
|
||||||
// Animate the movement.
|
// Animate the movement.
|
||||||
let new_active_y = self.tile_y(new_idx);
|
let new_active_y = self.tile_y(new_idx);
|
||||||
self.tiles[new_idx].animate_move_from(Point::from((0, active_y - new_active_y)));
|
self.tiles[new_idx].animate_move_y_from(active_y - new_active_y);
|
||||||
self.tiles[new_idx - 1].animate_move_from(Point::from((0, next_y - active_y)));
|
self.tiles[new_idx - 1].animate_move_y_from(next_y - active_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
Reference in New Issue
Block a user