From e82a6dedd942957b23d8c2be6bf25b77ba00456a Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 16 Dec 2020 18:57:46 +0530 Subject: [PATCH] Fix deletion with image numbers --- gen-apc-parsers.py | 2 +- kitty/graphics.c | 8 ++++---- kitty/parse-graphics-command.h | 25 +++++++++++++------------ kitty_tests/graphics.py | 20 +++++++++++++++++++- 4 files changed, 37 insertions(+), 18 deletions(-) diff --git a/gen-apc-parsers.py b/gen-apc-parsers.py index 6fe2c4a8e..b0e9e17ab 100755 --- a/gen-apc-parsers.py +++ b/gen-apc-parsers.py @@ -251,7 +251,7 @@ def graphics_parser() -> None: flag = frozenset keymap: KeymapType = { 'a': ('action', flag('tTqpd')), - 'd': ('delete_action', flag('aAiIcCpPqQxXyYzZ')), + 'd': ('delete_action', flag('aAiIcCnNpPqQxXyYzZ')), 't': ('transmission_type', flag('dfts')), 'o': ('compressed', flag('z')), 'f': ('format', 'uint'), diff --git a/kitty/graphics.c b/kitty/graphics.c index 9c5c9ef44..51a2bd571 100644 --- a/kitty/graphics.c +++ b/kitty/graphics.c @@ -805,14 +805,14 @@ grman_clear(GraphicsManager *self, bool all, CellPixelSize cell) { static inline bool id_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixelSize cell UNUSED) { const GraphicsCommand *g = data; - if (img->client_id == g->id) return !g->placement_id || ref->client_id == g->placement_id; + if (g->id && img->client_id == g->id) return !g->placement_id || ref->client_id == g->placement_id; return false; } static inline bool number_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixelSize cell UNUSED) { const GraphicsCommand *g = data; - if (img->client_number == g->image_number) return !g->placement_id || ref->client_id == g->placement_id; + if (g->image_number && img->client_number == g->image_number) return !g->placement_id || ref->client_id == g->placement_id; return false; } @@ -849,7 +849,7 @@ point3d_filter_func(const ImageRef *ref, Image *img, const void *data, CellPixel static void handle_delete_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c, bool *is_dirty, CellPixelSize cell) { - static GraphicsCommand d; + GraphicsCommand d; bool only_first_image = false; switch (g->delete_action) { #define I(u, data, func) filter_refs(self, data, g->delete_action == u, func, cell, only_first_image); *is_dirty = true; break @@ -870,7 +870,7 @@ handle_delete_command(GraphicsManager *self, const GraphicsCommand *g, Cursor *c case 'n': case 'N': only_first_image = true; - I('N', &g, number_filter_func); + I('N', g, number_filter_func); default: REPORT_ERROR("Unknown graphics command delete action: %c", g->delete_action); break; diff --git a/kitty/parse-graphics-command.h b/kitty/parse-graphics-command.h index 5c5f946dd..cae0978ad 100644 --- a/kitty/parse-graphics-command.h +++ b/kitty/parse-graphics-command.h @@ -144,8 +144,8 @@ static inline void parse_graphics_code(Screen *screen, case action: { g.action = screen->parser_buf[pos++] & 0xff; - if (g.action != 'T' && g.action != 'd' && g.action != 'p' && - g.action != 't' && g.action != 'q') { + if (g.action != 'T' && g.action != 'q' && g.action != 'd' && + g.action != 'p' && g.action != 't') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for action: 0x%x", g.action); @@ -155,14 +155,15 @@ static inline void parse_graphics_code(Screen *screen, case delete_action: { g.delete_action = screen->parser_buf[pos++] & 0xff; - if (g.delete_action != 'y' && g.delete_action != 'c' && - g.delete_action != 'x' && g.delete_action != 'p' && - g.delete_action != 'P' && g.delete_action != 'Q' && - g.delete_action != 'C' && g.delete_action != 'Y' && - g.delete_action != 'i' && g.delete_action != 'z' && - g.delete_action != 'A' && g.delete_action != 'a' && - g.delete_action != 'q' && g.delete_action != 'Z' && - g.delete_action != 'X' && g.delete_action != 'I') { + if (g.delete_action != 'C' && g.delete_action != 'z' && + g.delete_action != 'y' && g.delete_action != 'X' && + g.delete_action != 'a' && g.delete_action != 'P' && + g.delete_action != 'i' && g.delete_action != 'c' && + g.delete_action != 'N' && g.delete_action != 'I' && + g.delete_action != 'p' && g.delete_action != 'q' && + g.delete_action != 'Q' && g.delete_action != 'Z' && + g.delete_action != 'A' && g.delete_action != 'n' && + g.delete_action != 'x' && g.delete_action != 'Y') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for delete_action: 0x%x", g.delete_action); @@ -172,8 +173,8 @@ static inline void parse_graphics_code(Screen *screen, case transmission_type: { g.transmission_type = screen->parser_buf[pos++] & 0xff; - if (g.transmission_type != 's' && g.transmission_type != 'd' && - g.transmission_type != 't' && g.transmission_type != 'f') { + if (g.transmission_type != 'd' && g.transmission_type != 'f' && + g.transmission_type != 's' && g.transmission_type != 't') { REPORT_ERROR("Malformed GraphicsCommand control block, unknown flag " "value for transmission_type: 0x%x", g.transmission_type); diff --git a/kitty_tests/graphics.py b/kitty_tests/graphics.py index 7a5c2a81b..289babb9e 100644 --- a/kitty_tests/graphics.py +++ b/kitty_tests/graphics.py @@ -231,7 +231,7 @@ class TestGraphics(BaseTest): # test error handling for loading bad png data self.assertRaisesRegex(ValueError, '[EBADPNG]', load_png_data, b'dsfsdfsfsfd') - def test_load_with_numbers(self): + def test_gr_operations_with_numbers(self): s = self.create_screen() g = s.grman @@ -280,6 +280,24 @@ class TestGraphics(BaseTest): code, idstr = put(c=2, r=2, I=94) self.ae(code, 'ENOENT') + # test delete with number + def delete(ac='N', **kw): + cmd = 'a=d' + if ac: + cmd += ',d={}'.format(ac) + if kw: + cmd += ',' + ','.join('{}={}'.format(k, v) for k, v in kw.items()) + send_command(s, cmd) + + count = s.grman.image_count + put(i=1), put(i=2), put(i=3), put(i=4), put(i=5) + delete(I=94) + self.ae(s.grman.image_count, count) + delete(I=93) + self.ae(s.grman.image_count, count - 1) + delete(I=1) + self.ae(s.grman.image_count, count - 2) + def test_image_put(self): cw, ch = 10, 20 s, dx, dy, put_image, put_ref, layers, rect_eq = put_helpers(self, cw, ch)