diff --git a/app/e2e/terminal-keys.spec.ts b/app/e2e/terminal-keys.spec.ts index 174ac60f..322ae526 100644 --- a/app/e2e/terminal-keys.spec.ts +++ b/app/e2e/terminal-keys.spec.ts @@ -48,3 +48,20 @@ for (const renderer of ["ghostty", "xterm"] as const) { await expect.poll(() => sent(page)).toBe("\x1b[13;2u\x1bb\x1bf\x01\x05\x15\r"); }); } + +// ghostty-web makes the terminal's host contenteditable and focuses it, so +// without caret-color the browser blinks its own caret, the canvas's height, +// at the left edge beside the terminal's cursor. +test("ghostty: a focused terminal shows no browser caret", async ({ app }) => { + mockOnly("the shell is on the mock's gpu box"); + await app.open({ prefs: { terminal: { renderer: "ghostty" } } }); + const page = app.page; + await openShell(page); + const caret = () => + page.evaluate(() => { + const a = document.activeElement as HTMLElement | null; + const host = a?.closest("[contenteditable=true]"); + return host ? getComputedStyle(host).caretColor : "no editable host"; + }); + await expect.poll(caret).toBe("rgba(0, 0, 0, 0)"); +}); diff --git a/app/src/lib/terminal.ts b/app/src/lib/terminal.ts index 0cfac1d5..56c009c4 100644 --- a/app/src/lib/terminal.ts +++ b/app/src/lib/terminal.ts @@ -523,6 +523,10 @@ async function createGhostty(host: HTMLElement, colors: TerminalColors, prefs: T hung.stop(); delete (t as { focus?: unknown }).focus; } + // open() makes the host contenteditable and focus() focuses the host, so + // the browser blinked its own text caret there, as tall as the canvas, at + // the terminal's left edge. The terminal draws its own cursor. + host.style.caretColor = "transparent"; keepLastColumn(t); oneReadPerFrame(t); const frames = drawOnDemand(t, host, prefs.cursorBlink); diff --git a/docs/changelog.mdx b/docs/changelog.mdx index 7f0fb8b5..e09f7f74 100644 --- a/docs/changelog.mdx +++ b/docs/changelog.mdx @@ -10,7 +10,10 @@ upgrades with `berth upgrade BOX`, or by running the again. ## Unreleased - +- **No more tall blinking bar at a terminal's left edge.** With the Ghostty + renderer, a focused terminal showed the browser's own text cursor down its + whole height, next to the terminal's real cursor. Only the real one shows + now. - **A box newer than the app is no longer called outdated.** An older Shipyard used to offer to update a box that already ran a newer release, and *Update all* (or updating boxes automatically) would put its older @@ -18,6 +21,7 @@ again. to downgrade one unless you pass `--force`. This works once both the app and the box are on this release or later. + ## v0.3.22 - **Mac terminal keys work in terminals.** ⇧↵ starts a new line in Claude