probably wrong fix
This commit is contained in:
@@ -100,9 +100,6 @@ public final class TerminalCanvasView {
|
||||
}
|
||||
|
||||
// GhosttyRenderStateDirty values (stable C ABI; see ghostty/vt/render.h).
|
||||
private static final int DIRTY_PARTIAL = 1;
|
||||
private static final int DIRTY_FULL = 2;
|
||||
|
||||
// Thin tab strip shown at the top when more than one tab is open.
|
||||
private static final double TAB_BAR_HEIGHT = 22.0;
|
||||
|
||||
@@ -188,50 +185,20 @@ public final class TerminalCanvasView {
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
// Repaint one pane whose content changed, then restore the (opaque) panes stacked above
|
||||
// it wherever they overlap the repainted region, so the z-order stays correct.
|
||||
// Repaint one pane whose content changed (a full, reliable repaint of the pane), then
|
||||
// restore the (opaque) panes stacked above it where they overlap, keeping z-order.
|
||||
private void repaintPaneContent(GraphicsContext gc, List<TerminalPane> panes, int index, Font font, FontMetrics metrics) {
|
||||
TerminalPane pane = panes.get(index);
|
||||
double px = Math.round(pane.x());
|
||||
double py = Math.round(pane.y());
|
||||
double pw = pane.width();
|
||||
double ph = pane.height();
|
||||
boolean kitty = config.kittyGraphics() && paneHasKittyGraphics(pane);
|
||||
|
||||
// A pane just resized (e.g. from a split) can't be trusted to report its dirty rows
|
||||
// for the app's post-SIGWINCH redraw, so force a full snapshot once.
|
||||
boolean forceFull = pane.consumeFullRender();
|
||||
|
||||
double regionY0;
|
||||
double regionY1;
|
||||
gc.save();
|
||||
clipRect(gc, px, py, pw, ph);
|
||||
if (kitty || forceFull) {
|
||||
drawPaneContent(gc, pane, font, metrics, pane.renderSnapshotFull(), px, py, pw, ph, kitty);
|
||||
regionY0 = py;
|
||||
regionY1 = py + ph;
|
||||
} else {
|
||||
RenderStateSnapshot snapshot = pane.renderSnapshot();
|
||||
int dirty = snapshot == null ? DIRTY_FULL : snapshot.dirty();
|
||||
if (dirty == DIRTY_FULL) {
|
||||
drawPaneContent(gc, pane, font, metrics, snapshot, px, py, pw, ph, false);
|
||||
regionY0 = py;
|
||||
regionY1 = py + ph;
|
||||
} else if (dirty == DIRTY_PARTIAL) {
|
||||
double[] band = drawDirtyRows(gc, pane, font, metrics, snapshot, px, py, pw, ph);
|
||||
gc.restore();
|
||||
if (band == null) {
|
||||
return;
|
||||
}
|
||||
restoreStackedAbove(gc, panes, index, font, metrics, px, band[0], pw, band[1] - band[0]);
|
||||
return;
|
||||
} else {
|
||||
gc.restore();
|
||||
return; // dirty == FALSE: nothing visible changed.
|
||||
}
|
||||
}
|
||||
drawPaneContent(gc, pane, font, metrics, pane.renderSnapshot(), px, py, pw, ph,
|
||||
config.kittyGraphics() && paneHasKittyGraphics(pane));
|
||||
gc.restore();
|
||||
restoreStackedAbove(gc, panes, index, font, metrics, px, regionY0, pw, regionY1 - regionY0);
|
||||
restoreStackedAbove(gc, panes, index, font, metrics, px, py, pw, ph);
|
||||
}
|
||||
|
||||
// Redraw any panes above `index` in z-order that intersect the given screen rect, so a
|
||||
@@ -251,7 +218,7 @@ public final class TerminalCanvasView {
|
||||
}
|
||||
gc.save();
|
||||
clipRect(gc, ox0, oy0, ox1 - ox0, oy1 - oy0);
|
||||
drawPaneContent(gc, above, font, metrics, above.renderSnapshotFull(), ax, ay, above.width(), above.height(),
|
||||
drawPaneContent(gc, above, font, metrics, above.renderSnapshot(), ax, ay, above.width(), above.height(),
|
||||
config.kittyGraphics() && paneHasKittyGraphics(above));
|
||||
gc.restore();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import dev.jlibghostty.MouseAction;
|
||||
import dev.jlibghostty.MouseEncoder;
|
||||
import dev.jlibghostty.MouseEncoderSize;
|
||||
import dev.jlibghostty.MouseInput;
|
||||
import dev.jlibghostty.RenderState;
|
||||
import dev.jlibghostty.RenderStateSnapshot;
|
||||
import dev.jlibghostty.ScrollViewport;
|
||||
import dev.jlibghostty.Terminal;
|
||||
@@ -27,9 +26,6 @@ public final class TerminalPane implements AutoCloseable {
|
||||
|
||||
private final Terminal terminal;
|
||||
private final MouseEncoder mouseEncoder = new MouseEncoder();
|
||||
// A persistent render state (reused across frames) is what makes ghostty's per-row
|
||||
// dirty tracking meaningful: update() accumulates dirty since the last resetDirty().
|
||||
private RenderState renderState = new RenderState();
|
||||
private RenderStateSnapshot cachedSnapshot;
|
||||
private ShellSession session;
|
||||
private boolean floating;
|
||||
@@ -47,7 +43,6 @@ public final class TerminalPane implements AutoCloseable {
|
||||
private volatile long renderVersion;
|
||||
private long snapshotVersion = -1;
|
||||
private volatile boolean closed;
|
||||
private boolean needsFullRender;
|
||||
|
||||
private TerminalPane(Terminal terminal, int columns, int rows) {
|
||||
this.terminal = terminal;
|
||||
@@ -135,34 +130,15 @@ public final class TerminalPane implements AutoCloseable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Incremental snapshot: cells are marshalled only for rows that changed since the last
|
||||
* frame (global dirty == PARTIAL), reused across calls for the same content version.
|
||||
* Snapshotting is deferred here rather than done in refresh(), so a burst of writes
|
||||
* between two frames collapses into a single snapshot.
|
||||
* Full render snapshot of the current screen, memoised per content version (so a burst
|
||||
* of writes between two frames yields one snapshot). Uses a throwaway render state per
|
||||
* snapshot, which always returns the complete, correct screen — a persistent render
|
||||
* state's per-row dirty tracking proved unreliable across resizes and screen clears.
|
||||
*/
|
||||
public RenderStateSnapshot renderSnapshot() {
|
||||
return snapshot(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Full snapshot with every row's cells populated. Used where the whole pane is redrawn
|
||||
* regardless of dirty state (the kitty-graphics path).
|
||||
*/
|
||||
public RenderStateSnapshot renderSnapshotFull() {
|
||||
return snapshot(true);
|
||||
}
|
||||
|
||||
private RenderStateSnapshot snapshot(boolean full) {
|
||||
synchronized (terminal) {
|
||||
if (full) {
|
||||
renderState.update(terminal);
|
||||
cachedSnapshot = renderState.snapshot();
|
||||
renderState.resetDirty();
|
||||
snapshotVersion = renderVersion;
|
||||
} else if (snapshotVersion != renderVersion) {
|
||||
renderState.update(terminal);
|
||||
cachedSnapshot = renderState.snapshotIncremental();
|
||||
renderState.resetDirty();
|
||||
if (snapshotVersion != renderVersion) {
|
||||
cachedSnapshot = terminal.renderSnapshot();
|
||||
snapshotVersion = renderVersion;
|
||||
}
|
||||
return cachedSnapshot;
|
||||
@@ -241,27 +217,10 @@ public final class TerminalPane implements AutoCloseable {
|
||||
this.rows = rows;
|
||||
this.pixelWidth = pixelWidth;
|
||||
this.pixelHeight = pixelHeight;
|
||||
// A persistent render state gets corrupted by a terminal resize: its next snapshot
|
||||
// comes back blank (a throwaway render state, as ghostty's API was originally used,
|
||||
// never had this). Recreate it so the next snapshot is a clean full render of the
|
||||
// resized grid, even for an idle pane that won't redraw on its own.
|
||||
renderState.close();
|
||||
renderState = new RenderState();
|
||||
snapshotVersion = -1;
|
||||
// The app (e.g. a TUI) also redraws a moment later via SIGWINCH; force the next
|
||||
// content repaint to use a full snapshot so we don't rely on dirty across the resize.
|
||||
needsFullRender = true;
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns and clears the "force a full repaint" flag set by {@link #resize}. */
|
||||
public boolean consumeFullRender() {
|
||||
boolean pending = needsFullRender;
|
||||
needsFullRender = false;
|
||||
return pending;
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
// Only mark the pane dirty; the snapshot itself is computed lazily in
|
||||
// renderSnapshot() so a burst of writes collapses into a single snapshot per frame.
|
||||
@@ -281,7 +240,6 @@ public final class TerminalPane implements AutoCloseable {
|
||||
session = null;
|
||||
}
|
||||
mouseEncoder.close();
|
||||
renderState.close();
|
||||
synchronized (terminal) {
|
||||
terminal.close();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user