fix(shell): lagging tab animations

Fixes lagging tab animations by discarding the expired animations.
This commit is contained in:
Michael Aaron Murphy 2023-10-17 16:52:11 +02:00 committed by Victoria Brekenfeld
parent 41998433c7
commit c16b86d1bf

View file

@ -248,6 +248,14 @@ where
} }
impl State { impl State {
fn next_tab_animation(&self) -> Option<&TabAnimationState> {
let now = Instant::now();
self.tab_animations
.iter()
.find(|anim| now.duration_since(anim.start_time) <= TAB_ANIMATION_DURATION)
}
pub fn offset(&self, bounds: Rectangle, content_bounds: Size) -> Vector { pub fn offset(&self, bounds: Rectangle, content_bounds: Size) -> Vector {
if let Some(animation) = self.scroll_animation { if let Some(animation) = self.scroll_animation {
let percentage = { let percentage = {
@ -275,19 +283,41 @@ impl State {
} }
pub fn cleanup_old_animations(&mut self) { pub fn cleanup_old_animations(&mut self) {
let start_time = Instant::now();
if let Some(animation) = self.scroll_animation.as_ref() { if let Some(animation) = self.scroll_animation.as_ref() {
if Instant::now().duration_since(animation.start_time) > SCROLL_ANIMATION_DURATION { if start_time.duration_since(animation.start_time) > SCROLL_ANIMATION_DURATION {
self.scroll_animation.take(); self.scroll_animation.take();
} }
} }
if let Some(animation) = self.tab_animations.front() { Self::discard_expired_tab_animations(&mut self.tab_animations, start_time);
if Instant::now().duration_since(animation.start_time) > TAB_ANIMATION_DURATION { }
self.tab_animations.pop_front();
if let Some(next_animation) = self.tab_animations.front_mut() { /// Remove expired tab animations from the queue.
next_animation.start_time = Instant::now(); fn discard_expired_tab_animations(
tab_animations: &mut VecDeque<TabAnimationState>,
start_time: Instant,
) {
if let Some(mut animation) = tab_animations.pop_front() {
let mut set_next_start = false;
while start_time.duration_since(animation.start_time) > TAB_ANIMATION_DURATION {
set_next_start = true;
if let Some(next) = tab_animations.pop_front() {
animation = next;
continue;
} }
return;
} }
if set_next_start {
animation.start_time = start_time;
}
tab_animations.push_front(animation);
} }
} }
} }
@ -532,7 +562,9 @@ where
renderer.with_layer(bounds, |renderer| { renderer.with_layer(bounds, |renderer| {
renderer.with_translation(Vector::new(-offset.x, -offset.y), |renderer| { renderer.with_translation(Vector::new(-offset.x, -offset.y), |renderer| {
let percentage = if let Some(animation) = state.tab_animations.front() { let tab_animation = state.next_tab_animation();
let percentage = if let Some(animation) = tab_animation {
let percentage = Instant::now() let percentage = Instant::now()
.duration_since(animation.start_time) .duration_since(animation.start_time)
.as_millis() as f32 .as_millis() as f32
@ -547,7 +579,7 @@ where
.zip(tree.children.iter().skip(2)) .zip(tree.children.iter().skip(2))
.zip(layout.children().skip(2)) .zip(layout.children().skip(2))
{ {
let bounds = if let Some(animation) = state.tab_animations.front() { let bounds = if let Some(animation) = tab_animation {
let id = tab.as_widget().id().unwrap(); let id = tab.as_widget().id().unwrap();
let previous = let previous =
animation animation
@ -755,11 +787,15 @@ where
if unknown_keys || changes.is_some() { if unknown_keys || changes.is_some() {
if !scrolling || !matches!(changes, Some(Difference::Focus)) { if !scrolling || !matches!(changes, Some(Difference::Focus)) {
let start_time = Instant::now();
State::discard_expired_tab_animations(&mut state.tab_animations, start_time);
// new tab_animation // new tab_animation
state.tab_animations.push_back(TabAnimationState { state.tab_animations.push_back(TabAnimationState {
previous_bounds: last_state.clone(), previous_bounds: last_state.clone(),
next_bounds: current_state.clone(), next_bounds: current_state.clone(),
start_time: Instant::now(), start_time,
}); });
} }