Skip to content

[Bug]: No cursor is visible while a CJK syllable composes in a terminal pane #16949

Closed

Description

@norinus

What happens

While a CJK syllable is composing in a terminal pane, there is no cursor anywhere. It comes back only when the syllable commits, or when the pane loses focus and the composition overlay closes.

Reported as "the cursor is not visible until I press space", and "it appears when focus leaves" — the second half is the tell.

Why

xterm renders an in-flight preedit into .composition-view, an opaque DOM overlay positioned over the cell the renderer draws the cursor in. The cursor itself is painted on the WebGL/canvas layer, so it cannot show through the overlay. Nothing is broken — the cursor is simply covered for the whole composition.

This does not happen with Latin input: a plain keypress goes straight to the pty, there is no preedit and no overlay, and the cursor stays on the cell the pty knows about.

Two smaller things found alongside

  • The Cursor Agent IME anchor scan repeats per jamo. resolveCursorAgentImeAnchor walks visible rows bottom-up reading up to cols cells per row. A Hangul IME fires compositionupdate per jamo, so that O(rows×cols) walk ran two to three times per typed character. Measured 45–96µs per jamo — real, but small enough that it is a cleanup, not a fix for anything a user feels.
  • setActivePane re-focuses a pane that already has focus. It computes changed but uses it only to gate onActivePaneChange; terminal.focus() runs unconditionally. React effects re-activate the already-active pane on unrelated renders — 21 calls observed over 30s of typing. Calling .focus() on the already-focused element is a no-op in a single-pane layout, so this is waste rather than a live defect, but it is a live hazard the moment focus can actually move mid-composition (split panes, chat↔terminal).

Environment

Orca dev build from main, Windows 11. The overlay behavior is xterm's, so macOS and Linux should show the same missing cursor.

Related

Not to be confused with #15550 and #15192, which are terminal output rendering bugs (Korean glyphs drawn twice, content lost on scroll). This is input-side and has no effect on what the terminal prints.

Activity

  1. nwparker commented on Aug 30, 2026

    @nwparker
    Contributor

    Status update: the missing terminal IME caret and candidate-anchor drift are fixed in #17170 at xterm's existing CompositionHelper lifecycle. The fix renders a themed caret, preserves covered committed cells, and uses one derived anchor for both the visible preedit and native textarea. Focused xterm/rendered Electron tests and host checks passed; graphical native candidate-window observation remains explicitly unverifiable on the supplied headless or non-CJK-input hosts. The durable acceptance contract is documented in #17172.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions