diff --git a/include/img/img.h b/include/img/img.h index cc7abed2..7621e950 100644 --- a/include/img/img.h +++ b/include/img/img.h @@ -3,6 +3,7 @@ #define LABWC_IMG_H #include +#include #include #include @@ -19,6 +20,9 @@ struct lab_img { struct theme *theme; /* Used by modifier functions */ struct wl_array modifiers; /* lab_img_modifier_func_t */ struct lab_img_cache *cache; + + bool dropped; + int nr_locks; }; struct lab_img *lab_img_load(enum lab_img_type type, const char *path, @@ -69,10 +73,9 @@ void lab_img_add_modifier(struct lab_img *img, lab_img_modifier_func_t modifier, struct lab_data_buffer *lab_img_render(struct lab_img *img, int width, int height, int padding, double scale); -/** - * lab_img_destroy() - destroy lab_img - * @img: lab_img to destroy - */ -void lab_img_destroy(struct lab_img *img); +/* These functions closely follow the APIs of wlr_buffer */ +void lab_img_lock(struct lab_img *img); +void lab_img_unlock(struct lab_img *img); +void lab_img_drop(struct lab_img *img); #endif /* LABWC_IMG_H */ diff --git a/include/ssd-internal.h b/include/ssd-internal.h index 3600b1c6..6d1d7ae7 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -79,7 +79,6 @@ struct ssd { } title; char *app_id; - struct lab_img *icon_img; } state; /* An invisible area around the view which allows resizing */ diff --git a/src/common/scaled-img-buffer.c b/src/common/scaled-img-buffer.c index 27d65b9c..620b10a6 100644 --- a/src/common/scaled-img-buffer.c +++ b/src/common/scaled-img-buffer.c @@ -26,6 +26,7 @@ static void _destroy(struct scaled_scene_buffer *scaled_buffer) { struct scaled_img_buffer *self = scaled_buffer->data; + lab_img_unlock(self->img); free(self); } @@ -57,6 +58,7 @@ scaled_img_buffer_create(struct wlr_scene_tree *parent, struct lab_img *img, struct scaled_img_buffer *self = znew(*self); self->scaled_buffer = scaled_buffer; self->scene_buffer = scaled_buffer->scene_buffer; + lab_img_lock(img); self->img = img; self->width = width; self->height = height; @@ -73,6 +75,8 @@ void scaled_img_buffer_update(struct scaled_img_buffer *self, struct lab_img *img, int width, int height, int padding) { + lab_img_unlock(self->img); + lab_img_lock(img); self->img = img; self->width = width; self->height = height; diff --git a/src/img/img.c b/src/img/img.c index ccb7cdcc..f521fcce 100644 --- a/src/img/img.c +++ b/src/img/img.c @@ -195,10 +195,10 @@ lab_img_render(struct lab_img *img, int width, int height, int padding, return buffer; } -void -lab_img_destroy(struct lab_img *img) +static void +consider_destroy_img(struct lab_img *img) { - if (!img) { + if (!img->dropped || img->nr_locks > 0) { return; } @@ -220,3 +220,28 @@ lab_img_destroy(struct lab_img *img) wl_array_release(&img->modifiers); free(img); } + +void +lab_img_lock(struct lab_img *img) +{ + assert(img); + img->nr_locks++; +} + +void +lab_img_unlock(struct lab_img *img) +{ + assert(img); + img->nr_locks--; + consider_destroy_img(img); +} + +void +lab_img_drop(struct lab_img *img) +{ + if (!img) { + return; + } + img->dropped = true; + consider_destroy_img(img); +} diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 9c24b431..f8ef9814 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -345,9 +345,6 @@ ssd_titlebar_destroy(struct ssd *ssd) if (ssd->state.app_id) { zfree(ssd->state.app_id); } - if (ssd->state.icon_img) { - lab_img_destroy(ssd->state.icon_img); - } wlr_scene_node_destroy(&ssd->titlebar.tree->node); ssd->titlebar.tree = NULL; @@ -642,10 +639,7 @@ ssd_update_window_icon(struct ssd *ssd) } } FOR_EACH_END - if (ssd->state.icon_img) { - lab_img_destroy(ssd->state.icon_img); - } - ssd->state.icon_img = icon_img; + lab_img_drop(icon_img); #endif } diff --git a/src/theme.c b/src/theme.c index 8b88baf3..73aff01b 100644 --- a/src/theme.c +++ b/src/theme.c @@ -1515,7 +1515,7 @@ theme_init(struct theme *theme, struct server *server, const char *theme_name) static void destroy_img(struct lab_img **img) { - lab_img_destroy(*img); + lab_img_drop(*img); *img = NULL; }