Skip to content

Commit 730ae54

Browse files
committed
fix(cursor): address PR review follow-up issues
1 parent 2f93efd commit 730ae54

File tree

7 files changed

+39
-55
lines changed

7 files changed

+39
-55
lines changed

docs/guide/lifecycle-and-updates.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ type State = { count: number };
1414

1515
const app = createNodeApp<State>({
1616
initialState: { count: 0 },
17-
config: { fpsCap: 60, maxEventBytes: 1 << 20 },
17+
config: { fpsCap: 30, maxEventBytes: 1 << 20 },
1818
});
1919

2020
app.view((state) => ui.text(`Count: ${state.count}`));

docs/protocol/versioning.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ Both the builder and the engine perform version checks:
122122

123123
1. The builder writes the correct magic and version into the header at build time.
124124
2. The version is determined by the selected builder version.
125-
3. `createApp()` validates backend drawlist version markers and requires version `>= 2`.
125+
3. `createApp()` validates the backend `drawlistVersion` and requires version `>= 2`.
126126

127127
**Engine side (C):**
128128

packages/core/src/app/rawRenderer.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export class RawRenderer {
5757
opts: Readonly<{
5858
backend: RuntimeBackend;
5959
builder?: DrawlistBuilderV1;
60-
drawlistVersion?: 1 | 2 | 3 | 4 | 5;
60+
drawlistVersion?: 2 | 3 | 4 | 5;
6161
maxDrawlistBytes?: number;
6262
drawlistValidateParams?: boolean;
6363
drawlistReuseOutputBuffer?: boolean;
@@ -82,6 +82,18 @@ export class RawRenderer {
8282
return;
8383
}
8484
const drawlistVersion = opts.drawlistVersion ?? 2;
85+
if (
86+
drawlistVersion !== 2 &&
87+
drawlistVersion !== 3 &&
88+
drawlistVersion !== 4 &&
89+
drawlistVersion !== 5
90+
) {
91+
throw new Error(
92+
`drawlistVersion ${String(
93+
drawlistVersion,
94+
)} is no longer supported; use drawlistVersion 2, 3, 4, or 5.`,
95+
);
96+
}
8597
if (drawlistVersion >= 3) {
8698
this.builder = createDrawlistBuilderV3({
8799
...builderOpts,

packages/core/src/app/widgetRenderer.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,7 @@ export class WidgetRenderer<S> {
825825
opts: Readonly<{
826826
backend: RuntimeBackend;
827827
builder?: DrawlistBuilderV1 | DrawlistBuilderV2 | DrawlistBuilderV3;
828-
drawlistVersion?: 1 | 2 | 3 | 4 | 5;
828+
drawlistVersion?: 2 | 3 | 4 | 5;
829829
maxDrawlistBytes?: number;
830830
drawlistValidateParams?: boolean;
831831
drawlistReuseOutputBuffer?: boolean;
@@ -882,6 +882,18 @@ export class WidgetRenderer<S> {
882882
return;
883883
}
884884
const drawlistVersion = opts.drawlistVersion ?? 2;
885+
if (
886+
drawlistVersion !== 2 &&
887+
drawlistVersion !== 3 &&
888+
drawlistVersion !== 4 &&
889+
drawlistVersion !== 5
890+
) {
891+
throw new Error(
892+
`drawlistVersion ${String(
893+
drawlistVersion,
894+
)} is no longer supported; use drawlistVersion 2, 3, 4, or 5.`,
895+
);
896+
}
885897
if (drawlistVersion >= 3) {
886898
this.builder = createDrawlistBuilderV3({
887899
...builderOpts,

packages/core/src/app/widgetRenderer/cursorBreadcrumbs.ts

Lines changed: 10 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -277,64 +277,26 @@ export function emitIncrementalCursor(
277277
cursorInfo,
278278
);
279279

280-
if (!cursorInfo || !isCursorBuilder(ctx.builder)) {
281-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
282-
}
283-
284-
const focusedId = ctx.focusedId;
285-
if (!focusedId) {
286-
ctx.builder.hideCursor();
287-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
288-
}
280+
const summary = resolveSummary();
289281

290-
const input = ctx.inputById.get(focusedId);
291-
if (!input || input.disabled) {
292-
ctx.builder.hideCursor();
293-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
282+
if (!cursorInfo || !isCursorBuilder(ctx.builder)) {
283+
return ctx.collectRuntimeBreadcrumbs ? summary : null;
294284
}
295285

296-
const rect = ctx.pooledRectByInstanceId.get(input.instanceId);
297-
if (!rect || rect.w <= 1 || rect.h <= 0) {
286+
if (!summary || !summary.visible) {
298287
ctx.builder.hideCursor();
299-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
300-
}
301-
302-
const graphemeOffset = ctx.inputCursorByInstanceId.get(input.instanceId) ?? input.value.length;
303-
let cursorX = 0;
304-
let cursorY = rect.y;
305-
if (input.multiline) {
306-
const contentW = Math.max(1, rect.w - 2);
307-
const resolved = resolveInputMultilineCursor(
308-
input.value,
309-
graphemeOffset,
310-
contentW,
311-
input.wordWrap,
312-
);
313-
const maxStartVisual = Math.max(0, resolved.totalVisualLines - rect.h);
314-
const startVisual = Math.max(0, Math.min(maxStartVisual, resolved.visualLine - rect.h + 1));
315-
const localY = resolved.visualLine - startVisual;
316-
if (localY < 0 || localY >= rect.h) {
317-
ctx.builder.hideCursor();
318-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
319-
}
320-
cursorX = Math.max(0, Math.min(Math.max(0, rect.w - 2), resolved.visualX));
321-
cursorY = rect.y + localY;
322-
} else {
323-
cursorX = Math.max(
324-
0,
325-
Math.min(Math.max(0, rect.w - 2), measureTextCells(input.value.slice(0, graphemeOffset))),
326-
);
288+
return ctx.collectRuntimeBreadcrumbs ? summary : null;
327289
}
328290

329291
ctx.builder.setCursor({
330-
x: rect.x + 1 + cursorX,
331-
y: cursorY,
332-
shape: cursorInfo.shape,
292+
x: summary.x,
293+
y: summary.y,
294+
shape: summary.shape,
333295
visible: true,
334-
blink: cursorInfo.blink,
296+
blink: summary.blink,
335297
});
336298

337-
return ctx.collectRuntimeBreadcrumbs ? resolveSummary() : null;
299+
return ctx.collectRuntimeBreadcrumbs ? summary : null;
338300
}
339301

340302
export function updateRuntimeBreadcrumbSnapshot(

packages/core/src/terminalCaps.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,7 @@ export const DEFAULT_TERMINAL_CAPS: TerminalCaps = Object.freeze({
9292
* @param caps - Terminal capabilities
9393
* @returns true if SET_CURSOR commands will work
9494
*/
95-
export function supportsCursorProtocol(caps: TerminalCaps): boolean {
96-
// The engine may support cursor visibility even without shape support
95+
export function supportsCursorProtocol(_caps: TerminalCaps): boolean {
9796
return true;
9897
}
9998

packages/node/src/repro/recorder.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ export type ReproRecorderBounds = Readonly<{
3838
export type ReproRecorderBackendCapsOverrides = Readonly<{
3939
maxEventBytes?: number;
4040
fpsCap?: number;
41-
cursorProtocolVersion?: 2;
4241
}>;
4342

4443
export type CreateReproRecorderOptions = Readonly<{

0 commit comments

Comments
 (0)