fix(app): stabilize native terminal rendering

Scale custom glyph paths in measured cell coordinates so box-drawing runs fill their cells on Android. Debounce daemon resize claims at the terminal pane boundary so keyboard layout animation sends only the settled dimensions.
This commit is contained in:
Mohamed Boudra
2026-08-04 18:43:46 +02:00
parent dac255cb99
commit adf508a1c8
6 changed files with 212 additions and 45 deletions
@@ -1,12 +1,23 @@
import { describe, expect, it } from "vitest";
import {
resolveTerminalCustomGlyphCellTransform,
resolveTerminalGridMetricsMeasurement,
resolveMeasuredTerminalCellMetrics,
resolveTerminalCursorOffset,
} from "./terminal-grid-metrics";
describe("native terminal grid metrics", () => {
it("places each normalized custom glyph in run viewport coordinates", () => {
expect(
resolveTerminalCustomGlyphCellTransform({
cellOffset: 57,
cellWidth: 7.4,
cellHeight: 16.2,
}),
).toBe("matrix(7.4 0 0 16.2 421.8 0)");
});
it("preserves fractional measured cell width for horizontal layout", () => {
expect(
resolveMeasuredTerminalCellMetrics({
@@ -21,6 +21,19 @@ export interface TerminalCursorOffset {
y: number;
}
export interface TerminalCustomGlyphCellTransformInput {
cellOffset: number;
cellWidth: number;
cellHeight: number;
}
export function resolveTerminalCustomGlyphCellTransform(
input: TerminalCustomGlyphCellTransformInput,
): string {
const translateX = input.cellOffset * input.cellWidth;
return `matrix(${input.cellWidth} 0 0 ${input.cellHeight} ${translateX} 0)`;
}
export function resolveMeasuredTerminalCellMetrics(
input: TerminalGridCellMetricsInput,
): TerminalGridCellMetrics {
@@ -22,6 +22,7 @@ import { resolveNativeTerminalFontFamily } from "./font.native";
import type { TerminalViewportState } from "./headless-terminal-state";
import {
resolveMeasuredTerminalCellMetrics,
resolveTerminalCustomGlyphCellTransform,
resolveTerminalGridMetricsMeasurement,
resolveTerminalCursorOffset,
type TerminalGridCellMetrics,
@@ -192,7 +193,7 @@ function TerminalGridCustomGlyphRun({
pointerEvents="none"
preserveAspectRatio="none"
style={styles.customGlyphSvg}
viewBox={`0 0 ${run.cellCount} 1`}
viewBox={`0 0 ${run.cellCount * cellWidth} ${cellHeight}`}
width={run.cellCount * cellWidth}
>
<G fill="none" stroke={run.foregroundColor}>
@@ -204,7 +205,11 @@ function TerminalGridCustomGlyphRun({
strokeLinecap="butt"
strokeLinejoin="miter"
strokeWidth={cell.glyph.strokeWidth}
transform={`translate(${cell.offset} 0)`}
transform={resolveTerminalCustomGlyphCellTransform({
cellOffset: cell.offset,
cellWidth,
cellHeight,
})}
vectorEffect="non-scaling-stroke"
/>
) : null,