Skip to content

Keep at least three screens of kitty images in the registry - #168

Merged
tomlm merged 3 commits into
mainfrom
tomlm/kitty-registry-screens
Oct 13, 2026
Merged

tomlm merged 3 commits into
mainfrom
tomlm/kitty-registry-screens

Conversation

@tomlm

@tomlm tomlm commented Oct 10, 2026

Copy link
Copy Markdown
Owner

Problem

MaxImageRegistryBytes defaults to 32 MB and the registry trims the oldest images by id regardless of screen size. A client that tiles a full-screen picture (Consolonia's kitty renderer keeps up to three screens' worth of tiles in the terminal to show them again without resending) exceeds that from about 2560x1440 up, and a 4K screen alone is 33 MB. Once the registry has dropped a tile the client still counts on, placing it again silently shows nothing.

Change

The option becomes a floor: the kitty registry budget is max(MaxImageRegistryBytes, 3 × Cols × CellWidthPixels × Rows × CellHeightPixels × 4). Zero or less still means no limit, and a configured budget larger than three screens still applies. Only the two kitty store/charge sites use the registry budget for storage; the iTerm2 OSC sites keep using the option as a per-image sanity ceiling, so their tests at 1 and 1024 bytes are unchanged.

Three tests cover the floor, an image beyond it, and a larger configured budget.

🤖 Generated with Claude Code

MaxImageRegistryBytes (32 MB) is now a floor: the registry holds at
least three screens' worth of pixels, computed from the terminal's size
and cell pixel size. A client that tiles a full-screen picture, as
Consolonia does, keeps a few screens of tiles in the terminal by id to
show them again without resending; at 32 MB a 2560x1440 screen already
could not hold three of them, and a tile the registry had dropped
placed as nothing. Zero or less still means no limit, and a configured
budget larger than three screens still applies.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Perf comparison — this change, against its base

3 run(s) of each side, alternating on one machine. Allocation is a count and is gated exactly. Time is a measurement, so its gate is derived from the spread this job just observed in itself rather than fixed in advance.

corpus bytes/char gen0/Mchar ns/char Δ time noise gate
scroll-ascii 0.00 → 0.00 0.00 → 0.00 3.82 → 3.82 +0.0% ±8% 23%
sgr-churn 0.00 → 0.00 0.00 → 0.00 8.94 → 8.82 -1.4% ±12% 35%
truecolor 0.00 → 0.00 0.00 → 0.00 8.40 → 8.43 +0.3% ±2% 6%
alt-redraw 0.00 → 0.00 0.00 → 0.00 11.41 → 11.41 -0.0% ±1% 4%
unicode 7.66 → 7.66 0.09 → 0.09 30.45 → 30.28 -0.5% ±9% 26%
flood 0.00 → 0.00 0.00 → 0.00 117.76 → 117.33 -0.4% ±12% 35%

Each corpus is gated at max(4%, 3 × its own noise). A wide noise column means this runner was busy and the timing half of the table should be read as advisory; the allocation half is exact either way.

assemblies measured
  • base: XTerm.NET 2.0.7.0 mvid:e66938d7-863d-4d2d-9d1c-d905837c5013
  • head: XTerm.NET 2.0.7.0 mvid:86847d8b-d6b4-4891-a1ff-7390d4b7a377

Perf comparison — cumulative, everything since 2.0.3

3 run(s) of each side, alternating on one machine. Allocation is a count and is gated exactly. Time is a measurement, so its gate is derived from the spread this job just observed in itself rather than fixed in advance.

corpus bytes/char gen0/Mchar ns/char Δ time noise gate
scroll-ascii 0.00 → 0.00 0.00 → 0.00 3.89 → 3.82 -1.8% ±7% 21%
sgr-churn 0.00 → 0.00 0.00 → 0.00 8.98 → 8.82 -1.8% ±10% 30%
truecolor 0.00 → 0.00 0.00 → 0.00 8.42 → 8.43 +0.1% ±4% 13%
alt-redraw 0.00 → 0.00 0.00 → 0.00 11.45 → 11.41 -0.4% ±2% 5%
unicode 7.66 → 7.66 0.09 → 0.09 29.89 → 30.28 +1.3% ±10% 29%
flood 0.00 → 0.00 0.00 → 0.00 117.90 → 117.33 -0.5% ±14% 42%

Each corpus is gated at max(5%, 3 × its own noise). A wide noise column means this runner was busy and the timing half of the table should be read as advisory; the allocation half is exact either way.

assemblies measured
  • base: XTerm.NET 2.0.3.0 mvid:9ba0ce98-0d1e-4424-8aa1-9ab012cdc07a
  • head: XTerm.NET 2.0.7.0 mvid:86847d8b-d6b4-4891-a1ff-7390d4b7a377

@tomlm

tomlm commented Oct 13, 2026

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts in this pull request

tomlm and others added 2 commits October 12, 2026 22:22
Main's #170 changed how the kitty registry trims: by recency, never
the image just stored or one on screen, and a retransmitted id drops
the placements of the image it replaces. This branch makes the budget
a floor of three screens. Both are kept.

InputHandler.KittyGraphics.cs conflicted at the Store call: main's
DropPlacements for a retransmitted id and its ShowsImage argument are
kept, with this branch's KittyRegistryBudget as the budget.

Two tests had to be reconciled. KittyPlacementDeleteTests set budgets
of 300 and 600 bytes on a 20x5 terminal of 8x16-pixel cells, which the
floor now raises to 153,600 bytes, so nothing ever trimmed; the images
are now 256x256 (262,144 bytes), placed into one cell with c=1,r=1,
and the budgets 300,000 and 600,000, keeping the same ratios. This
branch's test that a lone image beyond three screens is dropped
contradicted main's rule that the image just stored is never trimmed;
it now shows the floor as a budget the way main trims: an older image
nothing shows goes once three screens are exceeded, and the one just
stored stays.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@tomlm
tomlm merged commit 64a8827 into main Oct 13, 2026
4 checks passed
@tomlm
tomlm deleted the tomlm/kitty-registry-screens branch October 13, 2026 05:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant