Kitty graphics: anonymous placements accumulate on same-id retransmit instead of replacing #13719
Issue DescriptionA Kitty graphics client that retransmits an image with Ghostty:
Kitty:
Root causeSource read at
const key: PlacementKey = .{
.image_id = image_id,
.placement_id = if (placement_id == 0) .{
.tag = .internal,
.id = id: {
defer self.next_internal_placement_id +%= 1;
break :id self.next_internal_placement_id;
},
} else .{
.tag = .external,
.id = placement_id,
},
};The other half is
Each placement also holds a tracked pin ( Not a duplicateDistinct from #13468 (placements anchored to pruned scrollback rows). These placements sit on live rows and are never marked garbage, so the Why kitty differs
Spec wording
The guarantee of multiple anonymous placements is scoped to Possible fixes
I'd LOVE to make a PR for whichever. AI disclosureFound the initial bug myself, but I thoroughly verified and tested it with Claude Code (Claude Fable 5 & Opus 5). And of course, everything AI-generated was also thoroughly verified by me. Expected BehaviorRetransmitting the same image id with Actual BehaviorEvery transmit adds a placement. Sending 24 transmits of the same image id at 24 different cursor positions leaves 24 rectangles on screen in Ghostty, versus 1 in kitty under the identical input. Adding Reproduction Steps
NOTE: This is a fully AI-generated python script, that I read and verified works.
|


Fixed: #13723