From a0e41a46a3b9b1f94c0449adeda18ff46fdf6a66 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Sat, 31 Oct 2015 14:32:22 +0000 Subject: Stop GIF animations when they are no longer in use, instead of waiting until they are destroyed. --- content/content.c | 7 +++++++ content/content_protected.h | 2 ++ image/gif.c | 27 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/content/content.c b/content/content.c index be39b15a6..3d06f8e07 100644 --- a/content/content.c +++ b/content/content.c @@ -670,6 +670,9 @@ bool content_add_user(struct content *c, user->next = c->user_list->next; c->user_list->next = user; + if (c->handler->add_user != NULL) + c->handler->add_user(c); + return true; } @@ -699,6 +702,10 @@ void content_remove_user(struct content *c, assert(0); return; } + + if (c->handler->remove_user != NULL) + c->handler->remove_user(c); + next = user->next; user->next = next->next; free(next); diff --git a/content/content_protected.h b/content/content_protected.h index 7311da604..e5ff1cae2 100644 --- a/content/content_protected.h +++ b/content/content_protected.h @@ -82,6 +82,8 @@ struct content_handler { bool (*matches_quirks)(const struct content *c, bool quirks); const char *(*get_encoding)(const struct content *c, enum content_encoding_type op); content_type (*type)(void); + void (*add_user)(struct content *c); + void (*remove_user)(struct content *c); /** handler dependant content sensitive internal data interface. */ void * (*get_internal)(const struct content *c, void *context); diff --git a/image/gif.c b/image/gif.c index 3f5f6307e..fb0985a45 100644 --- a/image/gif.c +++ b/image/gif.c @@ -392,6 +392,31 @@ static nserror nsgif_clone(const struct content *old, struct content **newc) return NSERROR_OK; } +static void nsgif_add_user(struct content *c) +{ + nsgif_content *gif = (nsgif_content *) c; + + /* Ensure this content has already been converted. + * If it hasn't, the animation will start at the conversion phase instead. */ + if (gif->gif == NULL) return; + + if (content_count_users(c) == 1) { + /* First user, and content already converted, so start the animation. */ + if (gif->gif->frame_count_partial > 1) { + guit->browser->schedule(gif->gif->frames[0].frame_delay * 10, + nsgif_animate, c); + } + } +} + +static void nsgif_remove_user(struct content *c) +{ + if (content_count_users(c) == 1) { + /* Last user is about to be removed from this content, so stop the animation. */ + guit->browser->schedule(-1, nsgif_animate, c); + } +} + static void *nsgif_get_internal(const struct content *c, void *context) { nsgif_content *gif = (nsgif_content *) c; @@ -415,6 +440,8 @@ static const content_handler nsgif_content_handler = { .destroy = nsgif_destroy, .redraw = nsgif_redraw, .clone = nsgif_clone, + .add_user = nsgif_add_user, + .remove_user = nsgif_remove_user, .get_internal = nsgif_get_internal, .type = nsgif_content_type, .no_share = false, -- cgit v1.2.3