From 71bbf4ecb984ba263b04130f7d54c467d66fcb17 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 12 May 2024 14:13:14 +0530 Subject: [PATCH] Fix graphics being freed instead of deleted in draw_screen() --- kittens/choose_fonts/backend.py | 9 +++++--- kittens/choose_fonts/graphics.go | 38 ++++++++++++++++++-------------- kittens/choose_fonts/ui.go | 6 +++-- tools/tui/loop/api.go | 4 ++++ 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/kittens/choose_fonts/backend.py b/kittens/choose_fonts/backend.py index 0ea49e863..9f3c94f38 100644 --- a/kittens/choose_fonts/backend.py +++ b/kittens/choose_fonts/backend.py @@ -20,9 +20,12 @@ from kitty.utils import screen_size_function def send_to_kitten(x: Any) -> None: - sys.stdout.buffer.write(json.dumps(x).encode()) - sys.stdout.buffer.write(b'\n') - sys.stdout.buffer.flush() + try: + sys.stdout.buffer.write(json.dumps(x).encode()) + sys.stdout.buffer.write(b'\n') + sys.stdout.buffer.flush() + except BrokenPipeError: + raise SystemExit('Pipe to kitten was broken while sending data to it') class TextStyle(TypedDict): diff --git a/kittens/choose_fonts/graphics.go b/kittens/choose_fonts/graphics.go index abb595660..77eb60cab 100644 --- a/kittens/choose_fonts/graphics.go +++ b/kittens/choose_fonts/graphics.go @@ -6,17 +6,17 @@ import ( "kitty/tools/tui/graphics" "kitty/tools/tui/loop" + "kitty/tools/utils" ) var _ = fmt.Print type image struct { id, image_number uint32 - placement_id uint32 current_file string } -func (i image) graphics_command() *graphics.GraphicsCommand { +func (i image) new_graphics_command() *graphics.GraphicsCommand { gc := &graphics.GraphicsCommand{} if i.id > 0 { gc.SetImageId(i.id) @@ -55,19 +55,28 @@ func (g *graphics_manager) initialize(lp *loop.Loop) { } func (g *graphics_manager) clear_placements() { - gc := graphics.GraphicsCommand{} - gc.SetAction(graphics.GRT_action_delete).SetDelete(graphics.GRT_delete_visible) - gc.WriteWithPayloadToLoop(g.lp, nil) + buf := strings.Builder{} + for _, img := range g.images { + if img.current_file == "" { + continue + } + gc := img.new_graphics_command() + gc.SetAction(graphics.GRT_action_delete) + gc.SetDelete(utils.IfElse(img.id > 0, graphics.GRT_delete_by_id, graphics.GRT_delete_by_number)) + gc.WriteWithPayloadTo(&buf, nil) + } + g.lp.QueueWriteString(buf.String()) } func (g *graphics_manager) display_image(slot int, path string, img_width, img_height int) { img := g.images[slot] if img.current_file != path { - gc := img.graphics_command() - gc.SetAction(graphics.GRT_action_transmit).SetFormat(graphics.GRT_format_rgba).SetDataWidth(uint64(img_width)).SetDataHeight(uint64(img_height)).SetTransmission(graphics.GRT_transmission_file) + gc := img.new_graphics_command() + gc.SetAction(graphics.GRT_action_transmit).SetDataWidth(uint64(img_width)).SetDataHeight(uint64(img_height)).SetTransmission(graphics.GRT_transmission_file) gc.WriteWithPayloadToLoop(g.lp, []byte(path)) + img.current_file = path } - gc := img.graphics_command() + gc := img.new_graphics_command() gc.SetAction(graphics.GRT_action_display).SetCursorMovement(graphics.GRT_cursor_static) gc.WriteWithPayloadToLoop(g.lp, nil) } @@ -87,16 +96,11 @@ func (g *graphics_manager) on_response(gc *graphics.GraphicsCommand) (err error) func (g *graphics_manager) finalize() { buf := strings.Builder{} - gc := &graphics.GraphicsCommand{} - gc.SetAction(graphics.GRT_action_delete).SetDelete(graphics.GRT_free_by_number) - d := func(n uint32) { - gc.SetImageNumber(n) + for _, img := range g.images { + gc := img.new_graphics_command() + gc.SetAction(graphics.GRT_action_delete) + gc.SetDelete(utils.IfElse(img.id > 0, graphics.GRT_free_by_id, graphics.GRT_free_by_number)) gc.WriteWithPayloadTo(&buf, nil) } - d(g.main.image_number) - d(g.bold.image_number) - d(g.italic.image_number) - d(g.bi.image_number) - d(g.extra.image_number) g.lp.QueueWriteString(buf.String()) } diff --git a/kittens/choose_fonts/ui.go b/kittens/choose_fonts/ui.go index 06afb80c8..74b510153 100644 --- a/kittens/choose_fonts/ui.go +++ b/kittens/choose_fonts/ui.go @@ -9,6 +9,7 @@ import ( "kitty/tools/tui" "kitty/tools/tui/graphics" "kitty/tools/tui/loop" + "kitty/tools/utils" ) var _ = fmt.Print @@ -62,7 +63,8 @@ func (h *handler) initialize() (err error) { h.lp.OnQueryResponse = h.on_query_response h.lp.QueryTerminal("font_size", "dpi_x", "dpi_y", "foreground", "background") h.listing.initialize(h) - if h.temp_dir, err = os.MkdirTemp("", "kitten-choose-fonts-*"); err != nil { + // dont use /tmp as it may be mounted in RAM, Le Sigh + if h.temp_dir, err = os.MkdirTemp(utils.CacheDir(), "kitten-choose-fonts-*"); err != nil { return } initialize_variable_data_cache() @@ -131,7 +133,7 @@ func (h *handler) draw_screen() (err error) { h.lp.EndAtomicUpdate() }() h.graphics_manager.clear_placements() - h.lp.ClearScreen() + h.lp.ClearScreenButNotGraphics() h.lp.AllowLineWrapping(false) h.mouse_state.ClearCellRegions() switch h.state { diff --git a/tools/tui/loop/api.go b/tools/tui/loop/api.go index 18b98771d..653ed612a 100644 --- a/tools/tui/loop/api.go +++ b/tools/tui/loop/api.go @@ -448,6 +448,10 @@ func (self *Loop) ClearScreen() { self.QueueWriteString("\x1b[H\x1b[2J") } +func (self *Loop) ClearScreenButNotGraphics() { + self.QueueWriteString("\x1b[H\x1b[J") +} + func (self *Loop) SendOverlayReady() { self.QueueWriteString("\x1bP@kitty-overlay-ready|\x1b\\") }