diff options
| author | user <user@clank> | 2026-08-14 23:13:56 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-14 23:13:56 +0200 |
| commit | d1442bc9550b00080c2f5671fa93eaad67fb0299 (patch) | |
| tree | a745d9485501510c354ee02eaf8d0017dbfed4f2 /vendor/libghostty-vt | |
| parent | sl0ppty: a shader's strength can be an expression (diff) | |
| download | slosh-d1442bc9550b00080c2f5671fa93eaad67fb0299.tar.gz slosh-d1442bc9550b00080c2f5671fa93eaad67fb0299.tar.xz slosh-d1442bc9550b00080c2f5671fa93eaad67fb0299.zip | |
vendor: keep kitty images across a screen clear
libghostty-vt's eraseDisplay called kitty_images.delete(.{ .all = true }) for
ED 2 and ED 3, where the `true` also frees the image *data* of anything no
longer placed. A full-screen program that clears and redraws therefore loses
every image it uploaded, and every later placement of that id draws nothing.
That breaks the half of the protocol worth having. Kitty separates
transmitting an image (`a=t`, stored under an id) from placing it (`a=p`,
put on screen) precisely so a program can upload once and place many times --
which is also why the delete command distinguishes `d=a` (placements) from
`d=A` (placements and data). A screen clear should be the former.
The patch removes only the freeing: placements on the cleared screen still
go, and the image store still bounds itself with its 320MB limit and LRU
eviction on insert -- the mechanism that makes keeping them safe, and that
would be pointless if a clear dropped everything anyway.
Found with a bouncing-DVD screensaver that uploads ten frames up front and
places one per frame. It works in kitty; under us it drew nothing.
D12 said "with a patches file if we ever need one". vendor/patches is that
file, with the reasoning and what a re-vendor has to re-apply; the vendor
json lists it. Worth sending upstream.
Diffstat (limited to 'vendor/libghostty-vt')
| -rw-r--r-- | vendor/libghostty-vt/src/terminal/Terminal.zig | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/vendor/libghostty-vt/src/terminal/Terminal.zig b/vendor/libghostty-vt/src/terminal/Terminal.zig index b157994..e10132a 100644 --- a/vendor/libghostty-vt/src/terminal/Terminal.zig +++ b/vendor/libghostty-vt/src/terminal/Terminal.zig @@ -3341,12 +3341,17 @@ pub fn eraseDisplay( self.screens.active.cursor.pending_wrap = false; if (comptime build_options.kitty_graphics) { - // Clear all Kitty graphics state for this screen + // Clear the placements on this screen, but keep the images + // themselves: a client transmits with `a=t` once and places + // with `a=p` per frame, and freeing the data on a screen clear + // makes every later placement of that id draw nothing. The + // storage limit (320MB, LRU) is what bounds this, which is why + // it exists. sl0ppty patch; see vendor/patches. self.screens.active.kitty_images.delete( self.io(), self.screens.active.alloc, self, - .{ .all = true }, + .{ .all = false }, ); } }, @@ -3399,12 +3404,17 @@ pub fn eraseDisplay( self.screens.active.cursor.pending_wrap = false; if (comptime build_options.kitty_graphics) { - // Clear all Kitty graphics state for this screen + // Clear the placements on this screen, but keep the images + // themselves: a client transmits with `a=t` once and places + // with `a=p` per frame, and freeing the data on a screen clear + // makes every later placement of that id draw nothing. The + // storage limit (320MB, LRU) is what bounds this, which is why + // it exists. sl0ppty patch; see vendor/patches. self.screens.active.kitty_images.delete( self.io(), self.screens.active.alloc, self, - .{ .all = true }, + .{ .all = false }, ); } |
