claude-code - 💡(How to fix) Fix [BUG] Korean/CJK IME preedit composes at parked cursor (bottom-left) in `claude agents` view; CLAUDE_CODE_NATIVE_CURSOR=1 is silently negated

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

In the background agents view (claude agents), Korean (Hangul) IME composition is broken: the in-progress composition syllable (preedit) is rendered at the terminal's parked cursor location (bottom-left of the screen) instead of at the input caret. The regular interactive REPL on the same machine/terminal composes Korean correctly inline.

Setting CLAUDE_CODE_NATIVE_CURSOR=1 does not fix the agents view (see root-cause analysis below).

Root Cause

In the background agents view (claude agents), Korean (Hangul) IME composition is broken: the in-progress composition syllable (preedit) is rendered at the terminal's parked cursor location (bottom-left of the screen) instead of at the input caret. The regular interactive REPL on the same machine/terminal composes Korean correctly inline.

Setting CLAUDE_CODE_NATIVE_CURSOR=1 does not fix the agents view (see root-cause analysis below).

Fix Action

Fix / Workaround

The fullscreen/alt-screen renderer parks the native cursor at a fixed location (altScreenParkPatch) and draws its own cursor block. macOS IME attaches the preedit to the real (parked) cursor, hence the bottom-left composition.

Workarounds tried

Code Example

function nativeCursorDefault() {
  if (cached !== undefined) return cached;
  if (parseBool(process.env.CLAUDE_CODE_ACCESSIBILITY)) return cached = true;
  if (parseBool(process.env.CLAUDE_CODE_NATIVE_CURSOR)) return cached = !usesParkedCursor();
  return cached = false;
}

function usesParkedCursor() {
  if (cached2 !== undefined) return cached2;
  if (!process.stdout.isTTY) return cached2 = false;
  if (/* ... */) return cached2 = false;
  if (parseBool(process.env.CLAUDE_CODE_DECSTBM)) return cached2 = true;
  return cached2 = featureFlag("tengu_marlin_porch", false);
}
RAW_BUFFERClick to expand / collapse

Summary

In the background agents view (claude agents), Korean (Hangul) IME composition is broken: the in-progress composition syllable (preedit) is rendered at the terminal's parked cursor location (bottom-left of the screen) instead of at the input caret. The regular interactive REPL on the same machine/terminal composes Korean correctly inline.

Setting CLAUDE_CODE_NATIVE_CURSOR=1 does not fix the agents view (see root-cause analysis below).

Environment

  • Claude Code: 2.1.157
  • OS: macOS (Darwin 25.5.0)
  • Terminal: Ghostty
  • Shell: fish / zsh
  • IME: macOS 2-set Korean (두벌식)

Steps to reproduce

  1. Launch the background agents view: claude agents
  2. Switch the system input source to Korean.
  3. In the "type a prompt to create an agent" input, type 안녕.

Expected

안녕 composes inline inside the input box, at the caret — same as the regular claude REPL.

Actual

  • The committed syllable () appears in the input box with a drawn cursor block.
  • The still-composing syllable () appears outside the input box, at the bottom-left of the screen, where the terminal's real native cursor is parked.

So the drawn cursor block (input box) and the real native cursor (where macOS attaches the IME preedit) are in two different places. The preedit follows the real cursor, which is parked.

Root-cause analysis (from the minified 2.1.157 bundle)

The fullscreen/alt-screen renderer parks the native cursor at a fixed location (altScreenParkPatch) and draws its own cursor block. macOS IME attaches the preedit to the real (parked) cursor, hence the bottom-left composition.

The renderer can position the real native cursor at the caret when options.nativeCursor is true, but in the agents view it resolves to false. The default is computed by (deobfuscated names):

function nativeCursorDefault() {
  if (cached !== undefined) return cached;
  if (parseBool(process.env.CLAUDE_CODE_ACCESSIBILITY)) return cached = true;
  if (parseBool(process.env.CLAUDE_CODE_NATIVE_CURSOR)) return cached = !usesParkedCursor();
  return cached = false;
}

function usesParkedCursor() {
  if (cached2 !== undefined) return cached2;
  if (!process.stdout.isTTY) return cached2 = false;
  if (/* ... */) return cached2 = false;
  if (parseBool(process.env.CLAUDE_CODE_DECSTBM)) return cached2 = true;
  return cached2 = featureFlag("tengu_marlin_porch", false);
}

So even when the user sets CLAUDE_CODE_NATIVE_CURSOR=1, the value becomes !usesParkedCursor(). On setups where usesParkedCursor() is true (the tengu_marlin_porch flag, or CLAUDE_CODE_DECSTBM), native cursor stays off and the manual override is silently negated. This is why CLAUDE_CODE_NATIVE_CURSOR=1 has no effect in the agents view.

Net effect: in the agents view there is no user-facing way to make the native cursor track the input caret, so CJK IME preedit can't compose inline.

Workarounds tried

  • CLAUDE_CODE_NATIVE_CURSOR=1 claude agentsno effect (negated as above).
  • Switching the renderer to the classic main-screen mode (/tui default / CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1) avoids the parked cursor, but loses the flicker-free fullscreen scrollback — and it's unclear whether the agents view honors the tui setting at all.

Suggested fix

In the agents view (and any alt-screen TUI with a focused text input), emit the real cursor-position escape to the input caret so the terminal's IME composes there — i.e. treat the focused input like the REPL does — rather than parking the native cursor. At minimum, let CLAUDE_CODE_NATIVE_CURSOR=1 actually force native cursor on without being negated by usesParkedCursor().

Related

  • #63091 — IME candidate window at corner instead of caret (Windows CMD): same class (preedit not at caret).
  • #47962 — IME pre-edit buffer cleared by UI redraws (macOS, iTerm2).
  • #39112 — docs gap on native terminal IME composition / caret tracking.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

claude-code - 💡(How to fix) Fix [BUG] Korean/CJK IME preedit composes at parked cursor (bottom-left) in `claude agents` view; CLAUDE_CODE_NATIVE_CURSOR=1 is silently negated