diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2025-02-08 15:24:02 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-02-10 07:29:33 -0800 |
| commit | 02eccf7762bf01cca0bf066d769e2533e2d5a3d2 (patch) | |
| tree | 25afba081f03c1f4d45a84f415dcf3651196d914 /src/layout/tile.rs | |
| parent | 89cf276779d75c52c261d9ef78e1e808021164e4 (diff) | |
| download | niri-02eccf7762bf01cca0bf066d769e2533e2d5a3d2.tar.gz niri-02eccf7762bf01cca0bf066d769e2533e2d5a3d2.tar.bz2 niri-02eccf7762bf01cca0bf066d769e2533e2d5a3d2.zip | |
layout: Fix/add animations around tabbed columns
Diffstat (limited to 'src/layout/tile.rs')
| -rw-r--r-- | src/layout/tile.rs | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/src/layout/tile.rs b/src/layout/tile.rs index 7a49f5ed..7877457b 100644 --- a/src/layout/tile.rs +++ b/src/layout/tile.rs @@ -84,6 +84,9 @@ pub struct Tile<W: LayoutElement> { /// The animation of a tile visually moving vertically. move_y_animation: Option<MoveAnimation>, + /// The animation of the tile's opacity. + pub(super) alpha_animation: Option<Animation>, + /// Offset during the initial interactive move rubberband. pub(super) interactive_move_offset: Point<f64, Logical>, @@ -168,6 +171,7 @@ impl<W: LayoutElement> Tile<W> { resize_animation: None, move_x_animation: None, move_y_animation: None, + alpha_animation: None, interactive_move_offset: Point::from((0., 0.)), unmap_snapshot: None, rounded_corner_damage: Default::default(), @@ -301,6 +305,12 @@ impl<W: LayoutElement> Tile<W> { self.move_y_animation = None; } } + + if let Some(alpha) = &mut self.alpha_animation { + if alpha.is_done() { + self.alpha_animation = None; + } + } } pub fn are_animations_ongoing(&self) -> bool { @@ -308,10 +318,12 @@ impl<W: LayoutElement> Tile<W> { || self.resize_animation.is_some() || self.move_x_animation.is_some() || self.move_y_animation.is_some() + || self.alpha_animation.is_some() } pub fn update_render_elements(&mut self, is_active: bool, view_rect: Rectangle<f64, Logical>) { let rules = self.window.rules(); + let alpha = self.tile_alpha(); let draw_border_with_background = rules .draw_border_with_background @@ -336,7 +348,7 @@ impl<W: LayoutElement> Tile<W> { ), radius, self.scale, - 1., + alpha, ); let radius = if self.is_fullscreen { @@ -351,7 +363,7 @@ impl<W: LayoutElement> Tile<W> { is_active, radius, self.scale, - 1., + alpha, ); let draw_focus_ring_with_background = if self.effective_border_width().is_some() { @@ -367,7 +379,7 @@ impl<W: LayoutElement> Tile<W> { view_rect, radius, self.scale, - 1., + alpha, ); } @@ -452,6 +464,31 @@ impl<W: LayoutElement> Tile<W> { self.move_y_animation = None; } + pub fn animate_alpha(&mut self, from: f64, to: f64, config: niri_config::Animation) { + let from = from.clamp(0., 1.); + let to = to.clamp(0., 1.); + let current = self.alpha_animation.take().map(|anim| anim.clamped_value()); + let current = current.unwrap_or(from); + self.alpha_animation = Some(Animation::new(self.clock.clone(), current, to, 0., config)); + } + + pub fn ensure_alpha_animates_to_1(&mut self) { + if let Some(anim) = &self.alpha_animation { + if anim.to() != 1. { + // Cancel animation instead of starting a new one because the user likely wants to + // see the tile right away. + self.alpha_animation = None; + } + } + } + + /// Opacity that applies to both window and decorations. + fn tile_alpha(&self) -> f32 { + self.alpha_animation + .as_ref() + .map_or(1., |anim| anim.clamped_value()) as f32 + } + pub fn window(&self) -> &W { &self.window } @@ -740,6 +777,9 @@ impl<W: LayoutElement> Tile<W> { self.window.rules().opacity.unwrap_or(1.).clamp(0., 1.) }; + let tile_alpha = self.tile_alpha(); + let win_alpha = win_alpha * tile_alpha; + let window_loc = self.window_loc(); let window_size = self.window_size().to_f64(); let animated_window_size = self.animated_window_size(); @@ -921,7 +961,7 @@ impl<W: LayoutElement> Tile<W> { SolidColorRenderElement::from_buffer( &self.fullscreen_backdrop, location, - 1., + tile_alpha, Kind::Unspecified, ) .into() |
