From 24a195c7c7f73b7cee8691254341e70709e5e232 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Tue, 24 Dec 2024 09:39:01 +0530 Subject: [PATCH] Graphics: Fix deletion of images by id not working for images with no placements --- docs/changelog.rst | 2 ++ kitty/graphics.c | 17 +++++++++++++++++ kitty_tests/graphics.py | 15 +++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 77a5bf8a3..b5f96eb8e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -99,6 +99,8 @@ Detailed list of changes - Cursor trails: Fix pure vertical movement sometimes not triggering a trail and holding down a key in nvim causing the trail to be glitchy (:pull:`8152`, :pull:`8153`) +- Graphics: Fix deletion of images by id not working for images with no placements + 0.38.0 [2024-12-15] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/kitty/graphics.c b/kitty/graphics.c index 62f45a52a..6a3b7e7e5 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -2090,6 +2090,23 @@ static void handle_delete_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, bool *is_dirty, CellPixelSize cell) { if (self->currently_loading.loading_for.image_id) free_load_data(&self->currently_loading); GraphicsCommand d; + if (!g->placement_id) { + // special case freeing of images with no refs by id or number as + // filter_refs doesnt handle this + Image *img = NULL; + switch(g->delete_action) { + case 'I': img = img_by_client_id(self, g->id); break; + case 'N': img = img_by_client_number(self, g->image_number); break; + case 'R': { + for (image_map_itr ii = vt_first(&self->images_by_internal_id); !vt_is_end(ii); ) { + img = ii.data->val; + if (id_range_filter_func(NULL, img, g, cell) && !vt_size(&img->refs_by_internal_id)) ii = remove_image_itr(self, ii); + else ii = vt_next(ii); + } + } img = NULL; break; + } + if (img && !vt_size(&img->refs_by_internal_id)) remove_image(self, img); + } switch (g->delete_action) { #define I(u, data, func) filter_refs(self, data, g->delete_action == u, func, cell, false, true); *is_dirty = true; break #define D(l, u, data, func) case l: case u: I(u, data, func) diff --git a/kitty_tests/graphics.py b/kitty_tests/graphics.py index e8763b6fa..6b16654fc 100644 --- a/kitty_tests/graphics.py +++ b/kitty_tests/graphics.py @@ -137,10 +137,11 @@ def put_helpers(self, cw, ch, cols=10, lines=5): iid += 1 imgid = kw.pop('id', None) or iid no_id = kw.pop('no_id', False) + a = kw.pop('a', 'T') if no_id: - cmd = 'a=T,f=24,s=%d,v=%d,%s' % (w, h, put_cmd(**kw)) + cmd = f'a={a},f=24,s=%d,v=%d,%s' % (w, h, put_cmd(**kw)) else: - cmd = 'a=T,f=24,i=%d,s=%d,v=%d,%s' % (imgid, w, h, put_cmd(**kw)) + cmd = f'a={a},f=24,i=%d,s=%d,v=%d,%s' % (imgid, w, h, put_cmd(**kw)) data = b'x' * w * h * 3 res = send_command(screen, cmd, data) return imgid, parse_response(res) @@ -1051,6 +1052,16 @@ class TestGraphics(BaseTest): cmd += ',' + ','.join(f'{k}={v}' for k, v in kw.items()) send_command(s, cmd) + iid = put_image(s, cw, ch, a='t')[0] + self.ae(s.grman.image_count, 1) + delete('I', i=iid) + self.ae(s.grman.image_count, 0) + iid1 = put_image(s, cw, ch, a='t')[0] + iid2 = put_image(s, cw, ch, a='t')[0] + self.ae(s.grman.image_count, 2) + delete('R', x=iid1, y=iid2) + self.ae(s.grman.image_count, 0) + put_image(s, cw, ch) delete() self.ae(s.grman.image_count, 1)