6 Commits

Author SHA1 Message Date
b0ec6c7014 update jlibghostty 2026-05-31 22:20:56 +02:00
3c913fefd3 fix black seam bars: opaque base fill instead of clearRect
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>
2026-05-31 22:08:57 +02:00
263bcf36b7 add debugRepaint toggle that fills cleared spans red
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>
2026-05-31 22:02:41 +02:00
8e060b27ca Revert "snap repaint clear/fill to integer pixels to kill seam bars"
This reverts commit 6613f1f746.
2026-05-31 21:58:15 +02:00
6613f1f746 snap repaint clear/fill to integer pixels to kill seam bars
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>
2026-05-31 21:56:01 +02:00
5728733f5f worktrees ignores 2026-05-31 21:52:39 +02:00
3 changed files with 21 additions and 5 deletions

1
.gitignore vendored
View File

@@ -14,3 +14,4 @@ build
build build
.gradle .gradle
bin bin
.worktrees

8
flake.lock generated
View File

@@ -70,11 +70,11 @@
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
}, },
"locked": { "locked": {
"lastModified": 1780256181, "lastModified": 1780258814,
"narHash": "sha256-/saXdnYMbAMfP7u6USSqtNkBIgqZhU+CPr3F8tUQhHU=", "narHash": "sha256-8rxL7xaZ/loYg3zdt0w5+hfNyHFVknDZN360NzrtCsQ=",
"ref": "refs/heads/main", "ref": "refs/heads/main",
"rev": "db5ee5d20daf8855de3a3b2fa9349eced70946f0", "rev": "6a3d5aa0b0b1f738c958e2a2f0249574c07d9c4d",
"revCount": 21, "revCount": 23,
"type": "git", "type": "git",
"url": "https://gitea.gregorlohaus.com/gregor/jlibghostty.git" "url": "https://gitea.gregorlohaus.com/gregor/jlibghostty.git"
}, },

View File

@@ -50,6 +50,13 @@ final class TerminalPaneNode extends Region {
Boolean.getBoolean("jprototerm.fullRowRepaint") Boolean.getBoolean("jprototerm.fullRowRepaint")
|| "1".equals(System.getenv("JPROTOTERM_FULL_ROW_REPAINT")); || "1".equals(System.getenv("JPROTOTERM_FULL_ROW_REPAINT"));
// Debug toggle: paint each repaint run's cleared span red instead of clearing it to
// transparent. If the black bars turn red, they are spans repaintColumns clears but never
// refills; if they stay black, those pixels are never touched by repaintColumns at all.
private static final boolean DEBUG_REPAINT =
Boolean.getBoolean("jprototerm.debugRepaint")
|| "1".equals(System.getenv("JPROTOTERM_DEBUG_REPAINT"));
private static final Color DEFAULT_FOREGROUND = Color.rgb(225, 229, 235); private static final Color DEFAULT_FOREGROUND = Color.rgb(225, 229, 235);
private static final Color SELECTED_BACKGROUND = Color.rgb(52, 92, 140); private static final Color SELECTED_BACKGROUND = Color.rgb(52, 92, 140);
private static final Color PANE_BACKGROUND = Color.rgb(9, 10, 12); private static final Color PANE_BACKGROUND = Color.rgb(9, 10, 12);
@@ -839,7 +846,15 @@ final class TerminalPaneNode extends Region {
double x = TerminalMetrics.PADDING + startColumn * cellWidth; double x = TerminalMetrics.PADDING + startColumn * cellWidth;
double width = (endColumn - startColumn + 1) * cellWidth; double width = (endColumn - startColumn + 1) * cellWidth;
gc.clearRect(x, 0.0, width, canvas.getHeight()); // Opaque base fill rather than clearRect: a transparent clear leaves the run's
// fractional edge pixels transparent, which show the near-black pane background
// as a thin seam bar against the adjacent (un-repainted) line. Filling opaque
// removes every transparent pixel; per-cell backgrounds then paint on top, and
// default-background cells correctly show PANE_BACKGROUND. Safe because the
// per-column path never runs while kitty graphics (which need a transparent row
// canvas for below-text images) are present.
gc.setFill(DEBUG_REPAINT ? Color.RED : PANE_BACKGROUND);
gc.fillRect(x, 0.0, width, canvas.getHeight());
if (startColumn == 0) { if (startColumn == 0) {
gc.setFill(rowEdgeBackground(row, true)); gc.setFill(rowEdgeBackground(row, true));
gc.fillRect(0.0, 0.0, TerminalMetrics.PADDING, canvas.getHeight()); gc.fillRect(0.0, 0.0, TerminalMetrics.PADDING, canvas.getHeight());