gpui: Update animated image timing to pause when inactive (#52685)

- only advance frames and request animation frames while the window is
active.
- Reset last_frame_time to None when inactive to avoid fast catch-up
after resuming focus
- This fixes an issue where if you would have a gif open and lose focus,
the app tries to speedup to catch up the elapsed time


Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Might Close #21563, I shall measure the performance, I originally only
intended the fix to fix the speed up issue as I faced it while working
on gifs.


Release Notes:

- N/A or Added/Fixed/Improved ...
This commit is contained in:
MostlyK authored and GitHub committed 2026-03-30 07:31:22 +00:00
1 parent ce7512b115
commit 086060558f
1 file changed
+19 -12
+19 -12
View File
@@ -315,20 +315,24 @@ impl Element for Img {
if let Some(state) = &mut state {
let frame_count = data.frame_count();
if frame_count > 1 {
let current_time = Instant::now();
if let Some(last_frame_time) = state.last_frame_time {
let elapsed = current_time - last_frame_time;
let frame_duration =
Duration::from(data.delay(state.frame_index));
if window.is_window_active() {
let current_time = Instant::now();
if let Some(last_frame_time) = state.last_frame_time {
let elapsed = current_time - last_frame_time;
let frame_duration =
Duration::from(data.delay(state.frame_index));
if elapsed >= frame_duration {
state.frame_index =
(state.frame_index + 1) % frame_count;
state.last_frame_time =
Some(current_time - (elapsed - frame_duration));
if elapsed >= frame_duration {
state.frame_index =
(state.frame_index + 1) % frame_count;
state.last_frame_time =
Some(current_time - (elapsed - frame_duration));
}
} else {
state.last_frame_time = Some(current_time);
}
} else {
state.last_frame_time = Some(current_time);
state.last_frame_time = None;
}
}
state.started_loading = None;
@@ -365,7 +369,10 @@ impl Element for Img {
};
}
if global_id.is_some() && data.frame_count() > 1 {
if global_id.is_some()
&& data.frame_count() > 1
&& window.is_window_active()
{
window.request_animation_frame();
}
}