Korean IME preedit/candidate window anchored to wrong position on Windows (regression)
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
When using Korean IME (Microsoft default) on Windows 11, the IME preedit text and candidate window are anchored to the wrong position (bottom-left / last real cursor position) instead of the actual caret position in Claude Code's TUI input line.
This is the same root cause as #16372 — Claude Code renders a "fake cursor" in the TUI but does not move the real terminal cursor to the caret position. The IME overlay anchors to the real cursor, so it stays at the wrong location.
This was previously fixed by PR #17127 but has regressed. Multiple users have reported the same regression:
- #21660 — Korean IME composition text appears below cursor position
- #22498 — Korean language input delay bug came back
- #22732 — Korean IME characters invisible during composition (macOS)
- #25186 — Korean IME composition window at wrong position
What Should Happen?
IME preedit text and candidate window should follow the caret position inside the Claude Code input line.
Steps to Reproduce
- Launch Claude Code in Windows Terminal on Windows 11
- Focus the input line
- Switch to Korean IME (Microsoft default)
- Type Korean characters (e.g. "안녕하세요")
- Observe that the IME preedit/candidate window appears at the wrong position (bottom-left of terminal), not at the input caret
Claude Model
Opus
Is this a regression?
Yes — this was fixed by #17127 (IME cursor positioning via declared cursor system) but the fix no longer works.
Claude Code Version
2.1.77
Platform
Anthropic API
Operating System
Windows 11 Home (10.0.26200)
Terminal/Shell
Windows Terminal / bash
Additional Information
The original issue author (#16372) identified the root cause: after each render, the real terminal cursor needs to be moved to the TUI caret position (CUP), preserving/restoring SGR state. The fix in #17127 addressed this but appears to have regressed in a later version.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗