<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ida-tui.git/idatui/kittygfx.py, branch pre-codemode</title>
<subtitle>tui for headless ida</subtitle>
<id>https://git.sl0p.foo/ida-tui.git/atom/idatui/kittygfx.py?h=pre-codemode</id>
<link rel='self' href='https://git.sl0p.foo/ida-tui.git/atom/idatui/kittygfx.py?h=pre-codemode'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/'/>
<updated>2026-08-06T15:02:18Z</updated>
<entry>
<title>splash: blasty's transparent logo, and stop guessing the cell aspect</title>
<updated>2026-08-06T15:02:18Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-08-06T15:02:18Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=45ba9cf2f448b8c0e9548fce08ced7cea3d9cf69'/>
<id>urn:sha1:45ba9cf2f448b8c0e9548fce08ced7cea3d9cf69</id>
<content type='text'>
The artwork is now a proper transparent PNG with soft edges (24% of its pixels
carry partial alpha) instead of opaque art on black with a stray full-width
scan line along the bottom. Cropped to its content and resized 1024 -&gt; 768px,
which halves the file and costs nothing visible; logo-trans.png keeps the
master for future re-renders.

Two things the new art exposed, both wrong before it:

fit() assumed cells were 1:2. This terminal reports 9x22, i.e. 1:2.44. The old
logo was 474x516 -- close enough to the assumption that nobody noticed -- but a
square image at the hardcoded 60x33 would have been visibly stretched. The
graphics query now asks for the cell size too (CSI 16 t rides along in the same
round trip, before the DA1 that already synchronises it) and fit() uses the
answer.

The footprint was a constant. logo_cells() derives it from the artwork and the
measured cell size, so the art can be replaced without anyone remembering to
edit a number.

logo.ans was stale: the block-art fallback for terminals that can't draw an
image was still the OLD artwork, scan line included. tools/make_logo_ans.py
regenerates it from logo.png so the two cannot drift again. It understands
alpha -- a transparent cell emits no colour and lets the terminal background
through, and a cell with only one opaque half uses the matching half block so
the pixel lands on the correct side.
</content>
</entry>
<entry>
<title>splash: draw the real logo on terminals that can</title>
<updated>2026-08-06T14:12:13Z</updated>
<author>
<name>blasty</name>
<email>blasty@local</email>
</author>
<published>2026-08-06T14:01:57Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/ida-tui.git/commit/?id=6978c38b8bcc2dc7fb631a2223475a3164add22b'/>
<id>urn:sha1:6978c38b8bcc2dc7fb631a2223475a3164add22b</id>
<content type='text'>
logo.ans is 60x33 cells of half-blocks -- a 60x66 pixel image. logo.png is
474x516. On a terminal that speaks the kitty graphics protocol we now send the
real thing, in the same cell footprint (fit() lands on exactly 60x33, so the
layout is unchanged), and fall back to the block art everywhere else.

Three findings, each of which cost a round of "it renders nothing":

Support cannot be sniffed from the environment. Under a multiplexer that passes
the protocol through, TERM is xterm-256color and KITTY_WINDOW_ID, TERM_PROGRAM
and COLORTERM are all empty while the protocol answers OK -- detection by
terminal name would disable graphics on exactly the terminal that supports them.
So we ask: a 1x1 graphics query plus a Primary Device Attributes request, with
DA1 as the sync point.

Unicode placeholders are not usable. The tidy way to put an image in a TUI is a
virtual placement plus U+10EEEE cells that the compositor clips and moves like
text -- and it is what every Textual image library builds on -- but this
terminal answers ENOTSUPPORTED for placeholders while supporting everything
else. So the image is placed directly, anchored to screen cells Textual knows
nothing about. The splash therefore owns its lifetime: place after layout,
re-anchor when the note repaints (throttled; a placement is one short escape
with no image data), delete on unmount, or a leftover would sit on top of the
disassembly forever.

The query and the upload go on OPPOSITE sides of the alternate screen. The query
must run before Textual starts, which reads stdin on its own thread and would
eat the reply. The image must be uploaded after Textual has switched to the
alternate screen: an image uploaded to the primary screen cannot be placed from
the alternate one, and the placement reports success while drawing nothing. That
silent failure is why detection lives in launch.py and upload lives in the
splash's on_mount.

$IDATUI_KITTY_LOG traces the decisions, since none of this is visible to a test
-- correct escape sequences and visible pixels are not the same thing here.
Off-tty (the pilot suite, a pipe) detection returns False and the block art is
used, so the tests are unaffected.
</content>
</entry>
</feed>
