<feed xmlns='http://www.w3.org/2005/Atom'>
<title>pardes.git/test/pdf_pointer_bench.zig, branch main</title>
<subtitle>Pardes</subtitle>
<id>https://git.0x4200.cafe/pardes.git/atom?h=main</id>
<link rel='self' href='https://git.0x4200.cafe/pardes.git/atom?h=main'/>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/'/>
<updated>2026-10-01T03:12:17Z</updated>
<entry>
<title>The PDF benches share their clock, fatal exit, hash, count parser and effect drain, and lspprobe is lspbench's probe subcommand</title>
<updated>2026-10-01T03:12:17Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-30T01:58:53Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=b1485c97b493f7eaf65c6afdfb82e3065306b8fe'/>
<id>urn:sha1:b1485c97b493f7eaf65c6afdfb82e3065306b8fe</id>
<content type='text'>
B4: test/bench_util.zig holds what pdf_bench, pdf_pointer_bench, pdf_scroll_bench and pdf_sections_bench each copied (nowNs x4, fatal x3 named per bench, mix x3, parsePositive/parseCount x3, drainEffects x2). They stay four entry points: pdf_bench links its own mupdf module (with its C source and c_heap) where the others link the core's, which one executable cannot import under one name, and their reports and identities are each bench's own. pdf_sections_bench had rotted since the pane's cursor and selections moved to its body and the render revision became next_raster_revision; it builds and runs again. C6: tools/lspprobe.zig is lspbench's `probe` subcommand (zig build lspbench -- probe &lt;kind&gt; &lt;file&gt; &lt;line&gt;:&lt;col&gt;), and the lspprobe build step goes; docs/lsp.md names the new command.

Co-Authored-By: Claude Opus 5.5 &lt;noreply@anthropic.com&gt;
</content>
</entry>
<entry>
<title>Repaint PDF highlights by row, send rasters by shared memory, and animate messages</title>
<updated>2026-10-01T03:12:14Z</updated>
<author>
<name>Gabriel Schneider</name>
<email>gbrls@0x4200.cafe</email>
</author>
<published>2026-09-22T20:43:57Z</published>
<link rel='alternate' type='text/html' href='https://git.0x4200.cafe/pardes.git/commit/?id=9695cb098c784792af79c22d46a17f7bc7247d33'/>
<id>urn:sha1:9695cb098c784792af79c22d46a17f7bc7247d33</id>
<content type='text'>
PDF highlights (hover preview, search, selection) are baked into page rasters,
and any change re-rendered the whole page with MuPDF; the TTY then re-sent it
as base64 (4.7 MB a page), the GUI as a new texture. Worse, a pointer motion
over a PDF invalidated the page even when no preview was shown, so every
motion paid that. Now:

- A raster whose baked highlight set equals the wanted one is left alone.
- A highlighted page keeps its clean rows (before highlights and tint); a
  change repaints only the rows of quads that differ, running MuPDF's
  highlight pass (pardes_pdf_paint_highlights) over those clean rows and
  tinting them: the operations a full render performs, so the pixels are
  identical. MuPDF band renders are NOT bit-identical to a whole page (edge
  rows, resampled images), so they are never used to patch; the comment
  claiming otherwise is corrected.
- ImagePlace.patch hands shells the changed rows; the GUI uploads just those
  rows into the texture it holds.
- The TTY probes kitty shared memory (t=s) with an id vaxis never reaches and
  sends rasters as a /dev/shm name when the terminal reads it; direct base64
  otherwise (ssh).
- Shells that take row patches (GUI, TTY with shm) repaint a selection while
  it is dragged instead of only on release.

Latency elsewhere:
- TTY: an animating frame no longer sleeps 16 ms blind; a tick thread posts
  into the input queue, so input inside the frame is handled at once.
- TTY and GUI: queued pointer motions coalesce to the last.
- GUI: a skipped swapchain image re-arms the frame (3 retries); animations
  still tick while nothing presents.
- Editing: the line index is carried across an edit instead of rebuilt from
  a scan of the whole file per keystroke.

Messages fall into their row (ease-in; the GUI slides the band out from under
the tagline, a terminal fades it), stay until the next input as before, linger
MessageLinger ms (default 800), and dissolve (ease-out). MessageAnimation
toggles it; both are settings, in Config and startup files. The snapshot
harness pins the old behaviour. The detached server now ticks animations.

A restored terminal comes back live: the old screen and scrollback (dumped
as clean VT by ghostty's formatter, replayed at the new size; older dumps
fall back to their rendered text), a dim
"restored history" marker, then a new shell in the directory it was in.

Right-click on a line number in a file pane looks at that line (a sticky
context header's number included).

Measured with an external pty driver (TTY), an in-process fence trace
(GUI, PARDES_TEST_LATENCY), and test/pdf_pointer_bench.zig (pixel identity
against the baseline and a whole-page oracle); balanced A/A/B rounds, paired
per-round statistics.

Messages stack: each event gets its own row and its own fall, linger and
dissolve; a line keeps its row until it leaves and a new one fills the first
free row. Announcements and statuses are replaced in place, not stacked.
MessageFall, MessageDissolve and DumpDir are settings Config reports.

Co-Authored-By: Claude Opus 5.5 (1M context) &lt;noreply@anthropic.com&gt;
</content>
</entry>
</feed>
