Compare commits
8 Commits
test-new-j
...
cc9ac43ffa
| Author | SHA1 | Date | |
|---|---|---|---|
| cc9ac43ffa | |||
| 93d53fcef6 | |||
| b0ec6c7014 | |||
| 3c913fefd3 | |||
| 263bcf36b7 | |||
| 8e060b27ca | |||
| 6613f1f746 | |||
| 5728733f5f |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ build
|
||||
build
|
||||
.gradle
|
||||
bin
|
||||
.worktrees
|
||||
|
||||
19
README.md
19
README.md
@@ -132,3 +132,22 @@ open_scrollback = "ALT+S"
|
||||
Each tab has its own stack of tiled and floating panes; only the active tab is rendered. A
|
||||
thin tab bar appears at the top when more than one tab is open. Closing the last tiled pane
|
||||
while floating panes exist promotes the most recently active floating pane to a tiled pane.
|
||||
|
||||
## Diagnostics
|
||||
|
||||
Two render-debugging flags are off by default and add no overhead unless enabled. Pass them
|
||||
as JVM system properties (each also has an environment-variable equivalent). With the
|
||||
packaged binary the JVM picks them up from `JDK_JAVA_OPTIONS`:
|
||||
|
||||
```sh
|
||||
JDK_JAVA_OPTIONS="-Djprototerm.profile=true" ./result/bin/jprototerm
|
||||
```
|
||||
|
||||
- `-Djprototerm.profile=true` (or `JPROTOTERM_PROFILE=1`): print a `[render-profile]` line to
|
||||
stderr every N renders with the per-frame cost of each render stage — `snapshot` (terminal
|
||||
state marshalling), `fingerprint` (change detection), `draw` (canvas painting), and the
|
||||
`frame-total`. Set `-Djprototerm.profile.frames=<N>` to change the dump interval (default
|
||||
120).
|
||||
- `-Djprototerm.debugRepaint=true` (or `JPROTOTERM_DEBUG_REPAINT=1`): paint each per-column
|
||||
repaint run's cleared span red instead of clearing it. Repainted regions flash red, so you
|
||||
can see exactly which cells are being redrawn each frame.
|
||||
|
||||
8
flake.lock
generated
8
flake.lock
generated
@@ -70,11 +70,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1780256181,
|
||||
"narHash": "sha256-/saXdnYMbAMfP7u6USSqtNkBIgqZhU+CPr3F8tUQhHU=",
|
||||
"lastModified": 1780258814,
|
||||
"narHash": "sha256-8rxL7xaZ/loYg3zdt0w5+hfNyHFVknDZN360NzrtCsQ=",
|
||||
"ref": "refs/heads/main",
|
||||
"rev": "db5ee5d20daf8855de3a3b2fa9349eced70946f0",
|
||||
"revCount": 21,
|
||||
"rev": "6a3d5aa0b0b1f738c958e2a2f0249574c07d9c4d",
|
||||
"revCount": 23,
|
||||
"type": "git",
|
||||
"url": "https://gitea.gregorlohaus.com/gregor/jlibghostty.git"
|
||||
},
|
||||
|
||||
@@ -26,7 +26,7 @@ final class KeyEncoder {
|
||||
return switch (code) {
|
||||
case ENTER -> "\r";
|
||||
case BACK_SPACE -> "\u007f";
|
||||
case TAB -> "\t";
|
||||
case TAB -> event.isShiftDown() ? "\u001b[Z" : "\t";
|
||||
case ESCAPE -> "\u001b";
|
||||
case UP -> "\u001b[A";
|
||||
case DOWN -> "\u001b[B";
|
||||
|
||||
@@ -44,11 +44,12 @@ final class TerminalPaneNode extends Region {
|
||||
private static final int DIRTY_PARTIAL = 1;
|
||||
private static final int DIRTY_FULL = 2;
|
||||
|
||||
// Debug toggle: when set, skip the per-column repaint and always repaint the whole row.
|
||||
// Used to bisect partial-repaint artifacts (stale black bars near the cursor).
|
||||
private static final boolean FULL_ROW_REPAINT =
|
||||
Boolean.getBoolean("jprototerm.fullRowRepaint")
|
||||
|| "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 SELECTED_BACKGROUND = Color.rgb(52, 92, 140);
|
||||
@@ -740,10 +741,6 @@ final class TerminalPaneNode extends Region {
|
||||
}
|
||||
|
||||
private void renderChanged(RenderRow row) {
|
||||
if (FULL_ROW_REPAINT) {
|
||||
render(row);
|
||||
return;
|
||||
}
|
||||
double oldWidth = canvas.getWidth();
|
||||
double oldHeight = canvas.getHeight();
|
||||
prepareCanvas(row);
|
||||
@@ -839,7 +836,15 @@ final class TerminalPaneNode extends Region {
|
||||
double x = TerminalMetrics.PADDING + startColumn * 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) {
|
||||
gc.setFill(rowEdgeBackground(row, true));
|
||||
gc.fillRect(0.0, 0.0, TerminalMetrics.PADDING, canvas.getHeight());
|
||||
|
||||
Reference in New Issue
Block a user