The fullRowRepaint toggle existed only to bisect the black-bar repaint artifact,
which is now fixed, so drop it. Document the two remaining render-debug flags
(profile, debugRepaint) in the README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
KeyEncoder mapped TAB to a plain tab regardless of Shift, so Shift+Tab sent the
same byte as Tab. Apps that use backtab for reverse navigation (fish completion
menu, helix theme picker) never saw it. Emit CSI Z when Shift is held.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The persistent black bars in the partial-repaint path were clearRect leaving
the run's fractional edge pixels transparent, which showed the near-black pane
background as a seam against the adjacent un-repainted line. Confirmed with the
debugRepaint toggle: filling the span opaque removed the bars entirely.
Fill the repaint run with PANE_BACKGROUND (the default cell background) instead
of clearing to transparent; per-cell backgrounds paint over it as before. Safe
because the per-column path never runs while kitty graphics are present (those
force a full render), so no below-text image needs a transparent row canvas.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diagnostic for the persistent black bars: fills each repaint run's cleared span
red instead of clearing to transparent. If the bars turn red they are spans
repaintColumns clears but never refills; if they stay black those pixels are
never touched by the per-column repaint and the cause is elsewhere.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
cellWidth is fractional, so in repaintColumns the clearRect cleared a run's
edge pixel to full transparency while the background fillRect covered that same
pixel only partially (antialiased), leaving a ~1px part-transparent column that
showed the near-black pane background as a thin bar 1-2 cells before the cursor.
Full-row repaint hid it because the highlighted line is then one contiguous
fill with no internal junction.
Route the clear and the background fills through a shared columnX() that rounds
each column boundary to a whole device pixel, so run edges land on integer
pixels with full single coverage and adjacent runs tile seamlessly.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
repaintColumns cleared and redrew only [start,end], but a neighbouring cell's
glyph can overhang into that span. The clearRect erased the overhang and the
neighbour was never redrawn, leaving black notches through the line 1-2 cells
before the cursor that survived until a full rerender.
Redraw text for a couple of extra cells on each side, clipped to the cleared
span, so overhang from just-outside cells is restored without touching their
own cell areas. Keeps the per-column repaint efficiency (vs the full-row
repaint debug toggle, which fixed the bars but repainted every dirty cell).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>