Skip to content

fix(client): show IME and dictation composition at the cursor - #45

Merged
jesse23 merged 1 commit into
mainfrom
fix/ime-composition-at-cursor
Oct 9, 2026
Merged

jesse23 merged 1 commit into
mainfrom
fix/ime-composition-at-cursor

Conversation

@jesse23

@jesse23 jesse23 commented Oct 9, 2026

Copy link
Copy Markdown
Owner

Description

macOS dictation (and IME input) showed its in-progress text as a new line under the terminal, in the browser's default colours, pushing the whole UI up until the composition ended.

ghostty-web makes the terminal container contenteditable. When the container holds focus (a click in the padding or edge strip, tab focus, term.focus()), the browser writes the composition into it as a text node after the canvas. When ghostty-web's hidden textarea holds focus, the composition is invisible and the OS panels anchor to the textarea's spot at the top-left corner.

This PR adds src/client/compose.ts, which:

  • Keeps focus on the textarea. It redirects focus from the container on focusin, and on window focus when the container still holds it.
  • Anchors the textarea at the cursor cell every frame, so the dictation microphone and IME candidate window follow the cursor.
  • Draws the composition over the cursor cell in the terminal font, foreground on background, underlined. It hides on compositionend or blur.

Committed text still reaches the PTY through ghostty-web's own compositionend path. The upstream issue is coder/ghostty-web#97, and coder/ghostty-web#190 fixes the same causes. Once a ghostty-web release includes that fix, this layer can be removed.

Verification

  • bun run build && bun run webtty stop
  • bun test (434 passed, including the new compose.test.ts)
  • bun run lint
  • In Chrome, with simulated composition events: a click in the edge strip moves focus to the textarea, typing still works, and the preview appears at the cursor in the theme colours with no stray text nodes. On compositionend the text reaches the shell and the overlay hides.
  • Not yet checked: real macOS dictation and CJK input methods in Chrome and Safari.

ADRs

Keep focus on ghostty-web's input textarea, anchor it at the cursor cell,
and draw the composition over the cursor in the theme's font and colours,
instead of as a stray line under the canvas. See ADR 038.
@jesse23
jesse23 merged commit f21e1c2 into main Oct 9, 2026
3 checks passed
@jesse23
jesse23 deleted the fix/ime-composition-at-cursor branch October 9, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant