mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Set window-resize animation config for view-offset anim caused by resize
This commit is contained in:
+33
-7
@@ -15,6 +15,7 @@ pub static ANIMATION_SLOWDOWN: AtomicF64 = AtomicF64::new(1.);
|
|||||||
pub struct Animation {
|
pub struct Animation {
|
||||||
from: f64,
|
from: f64,
|
||||||
to: f64,
|
to: f64,
|
||||||
|
initial_velocity: f64,
|
||||||
duration: Duration,
|
duration: Duration,
|
||||||
/// Time until the animation first reaches `to`.
|
/// Time until the animation first reaches `to`.
|
||||||
///
|
///
|
||||||
@@ -52,10 +53,23 @@ impl Animation {
|
|||||||
config: niri_config::Animation,
|
config: niri_config::Animation,
|
||||||
default: niri_config::Animation,
|
default: niri_config::Animation,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let mut rv = Self::ease(from, to, initial_velocity, 0, Curve::EaseOutCubic);
|
||||||
if config.off {
|
if config.off {
|
||||||
return Self::ease(from, to, 0, Curve::EaseOutCubic);
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rv.replace_config(config, default);
|
||||||
|
rv
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn replace_config(
|
||||||
|
&mut self,
|
||||||
|
config: niri_config::Animation,
|
||||||
|
default: niri_config::Animation,
|
||||||
|
) {
|
||||||
|
let start_time = self.start_time;
|
||||||
|
let current_time = self.current_time;
|
||||||
|
|
||||||
// Resolve defaults.
|
// Resolve defaults.
|
||||||
let (kind, easing_defaults) = match (config.kind, default.kind) {
|
let (kind, easing_defaults) = match (config.kind, default.kind) {
|
||||||
// Configured spring.
|
// Configured spring.
|
||||||
@@ -82,23 +96,32 @@ impl Animation {
|
|||||||
let params = SpringParams::new(p.damping_ratio, f64::from(p.stiffness), p.epsilon);
|
let params = SpringParams::new(p.damping_ratio, f64::from(p.stiffness), p.epsilon);
|
||||||
|
|
||||||
let spring = Spring {
|
let spring = Spring {
|
||||||
from,
|
from: self.from,
|
||||||
to,
|
to: self.to,
|
||||||
initial_velocity,
|
initial_velocity: self.initial_velocity,
|
||||||
params,
|
params,
|
||||||
};
|
};
|
||||||
Self::spring(spring)
|
*self = Self::spring(spring);
|
||||||
}
|
}
|
||||||
niri_config::AnimationKind::Easing(p) => {
|
niri_config::AnimationKind::Easing(p) => {
|
||||||
let defaults = easing_defaults.unwrap_or(niri_config::EasingParams::default());
|
let defaults = easing_defaults.unwrap_or(niri_config::EasingParams::default());
|
||||||
let duration_ms = p.duration_ms.or(defaults.duration_ms).unwrap();
|
let duration_ms = p.duration_ms.or(defaults.duration_ms).unwrap();
|
||||||
let curve = Curve::from(p.curve.or(defaults.curve).unwrap());
|
let curve = Curve::from(p.curve.or(defaults.curve).unwrap());
|
||||||
Self::ease(from, to, u64::from(duration_ms), curve)
|
*self = Self::ease(
|
||||||
|
self.from,
|
||||||
|
self.to,
|
||||||
|
self.initial_velocity,
|
||||||
|
u64::from(duration_ms),
|
||||||
|
curve,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.start_time = start_time;
|
||||||
|
self.current_time = current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ease(from: f64, to: f64, duration_ms: u64, curve: Curve) -> Self {
|
pub fn ease(from: f64, to: f64, initial_velocity: f64, duration_ms: u64, curve: Curve) -> Self {
|
||||||
// FIXME: ideally we shouldn't use current time here because animations started within the
|
// FIXME: ideally we shouldn't use current time here because animations started within the
|
||||||
// same frame cycle should have the same start time to be synchronized.
|
// same frame cycle should have the same start time to be synchronized.
|
||||||
let now = get_monotonic_time();
|
let now = get_monotonic_time();
|
||||||
@@ -109,6 +132,7 @@ impl Animation {
|
|||||||
Self {
|
Self {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
initial_velocity,
|
||||||
duration,
|
duration,
|
||||||
// Our current curves never overshoot.
|
// Our current curves never overshoot.
|
||||||
clamped_duration: duration,
|
clamped_duration: duration,
|
||||||
@@ -132,6 +156,7 @@ impl Animation {
|
|||||||
Self {
|
Self {
|
||||||
from: spring.from,
|
from: spring.from,
|
||||||
to: spring.to,
|
to: spring.to,
|
||||||
|
initial_velocity: spring.initial_velocity,
|
||||||
duration,
|
duration,
|
||||||
clamped_duration,
|
clamped_duration,
|
||||||
start_time: now,
|
start_time: now,
|
||||||
@@ -168,6 +193,7 @@ impl Animation {
|
|||||||
Self {
|
Self {
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
|
initial_velocity,
|
||||||
duration,
|
duration,
|
||||||
clamped_duration: duration,
|
clamped_duration: duration,
|
||||||
start_time: now,
|
start_time: now,
|
||||||
|
|||||||
+16
-1
@@ -903,7 +903,8 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
column.update_tile_sizes(false);
|
column.update_tile_sizes(false);
|
||||||
|
|
||||||
// Move other columns in tandem with resizing.
|
// Move other columns in tandem with resizing.
|
||||||
if column.tiles[tile_idx].resize_animation().is_some() && offset != 0 {
|
let started_animation = column.tiles[tile_idx].resize_animation().is_some() && offset != 0;
|
||||||
|
if started_animation {
|
||||||
if self.active_column_idx <= col_idx {
|
if self.active_column_idx <= col_idx {
|
||||||
for col in &mut self.columns[col_idx + 1..] {
|
for col in &mut self.columns[col_idx + 1..] {
|
||||||
col.animate_move_from_with_config(
|
col.animate_move_from_with_config(
|
||||||
@@ -932,6 +933,20 @@ impl<W: LayoutElement> Workspace<W> {
|
|||||||
// FIXME: we will want to skip the animation in some cases here to make continuously
|
// FIXME: we will want to skip the animation in some cases here to make continuously
|
||||||
// resizing windows not look janky.
|
// resizing windows not look janky.
|
||||||
self.animate_view_offset_to_column(current_x, col_idx, None);
|
self.animate_view_offset_to_column(current_x, col_idx, None);
|
||||||
|
|
||||||
|
// If this animated resize caused a view animation, make sure that it uses the same
|
||||||
|
// config. This is important for always-centered view.
|
||||||
|
if let Some(ViewOffsetAdjustment::Animation(anim)) = &mut self.view_offset_adj {
|
||||||
|
// FIXME: animate_view_offset_to_column() will keep the previous running view
|
||||||
|
// offset animation if the target was the same; maybe we shouldn't replace in this
|
||||||
|
// case?
|
||||||
|
if started_animation {
|
||||||
|
anim.replace_config(
|
||||||
|
self.options.animations.window_resize,
|
||||||
|
niri_config::Animation::default_window_resize(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,7 @@ All horizontal camera view movement animations, such as:
|
|||||||
- When a window off-screen is focused and the camera scrolls to it.
|
- When a window off-screen is focused and the camera scrolls to it.
|
||||||
- When a new window appears off-screen and the camera scrolls to it.
|
- When a new window appears off-screen and the camera scrolls to it.
|
||||||
- When a window resizes bigger and the camera scrolls to show it in full.
|
- When a window resizes bigger and the camera scrolls to show it in full.
|
||||||
|
- Since 0.1.5, animated window resizes will use the `window-resize` animation parameters for the view animation to make them synchronized.
|
||||||
- After a horizontal touchpad gesture (a spring is recommended).
|
- After a horizontal touchpad gesture (a spring is recommended).
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user