diff --git a/docs/graphics-protocol.rst b/docs/graphics-protocol.rst index 64b0b0e65..e31c868bb 100644 --- a/docs/graphics-protocol.rst +++ b/docs/graphics-protocol.rst @@ -551,7 +551,7 @@ Key Value Default Description ``c`` Positive integer ``0`` The 1-based frame number of the frame whose image data serves as the base data when creating a new frame, by default the base data is black, fully transparent pixels ``r`` Positive integer ``0`` The 1-based frame number of the frame that is being edited. By default, a new frame is created -``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the previous one. A value of +``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the next one. A value of zero is ignored. Negative values create a *gapless* frame. If not specified, frames have a default gap of ``40ms``. The root frame defaults to zero gap. @@ -559,7 +559,7 @@ Key Value Default Description ----------------------------------------------------------- ``s`` Positive integer ``0`` ``1`` - start animation, ``>1`` - stop animation ``r`` Positive integer ``0`` The 1-based frame number of the frame that is being affected -``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the previous one. A value of +``z`` 32-bit integer ``0`` The gap (in milliseconds) of this frame from the next one. A value of zero is ignored. Negative values create a *gapless* frame. ``c`` Positive integer ``0`` The 1-based frame number of the frame that should be made the current frame diff --git a/kitty/graphics.c b/kitty/graphics.c index a2723e6ab..9d12659b3 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -1031,19 +1031,21 @@ scan_active_animations(GraphicsManager *self, const monotonic_t now, monotonic_t for (size_t i = self->image_count; i-- > 0;) { Image *img = self->images + i; if (img->animation_enabled && img->extra_framecnt && img->is_drawn && img->animation_duration) { - self->has_images_needing_animation = true; - Frame *next_frame = img->current_frame_index + 1 < img->extra_framecnt ? img->extra_frames + img->current_frame_index + 1 : &img->root_frame; - monotonic_t next_frame_at = img->current_frame_shown_at + ms_to_monotonic_t(next_frame->gap); - if (now >= next_frame_at) { - dirtied = true; - do { - img->current_frame_index = (img->current_frame_index + 1) % (img->extra_framecnt + 1); - } while(!current_frame(img)->gap); - update_current_frame(self, img, NULL); - next_frame = img->current_frame_index + 1 < img->extra_framecnt ? img->extra_frames + img->current_frame_index + 1 : &img->root_frame; + Frame *f = current_frame(img); + if (f) { + self->has_images_needing_animation = true; + monotonic_t next_frame_at = img->current_frame_shown_at + ms_to_monotonic_t(f->gap); + if (now >= next_frame_at) { + dirtied = true; + do { + img->current_frame_index = (img->current_frame_index + 1) % (img->extra_framecnt + 1); + } while(!current_frame(img)->gap); + update_current_frame(self, img, NULL); + f = current_frame(img); + next_frame_at = img->current_frame_shown_at + ms_to_monotonic_t(f->gap); + } + if (next_frame_at > now && next_frame_at - now < *minimum_gap) *minimum_gap = next_frame_at - now; } - next_frame_at = img->current_frame_shown_at + ms_to_monotonic_t(next_frame->gap); - if (next_frame_at - now < *minimum_gap) *minimum_gap = next_frame_at - now; } } return dirtied;