Summary
cmux-windows does not properly handle CJK (Chinese, Japanese, Korean) characters. There are two distinct issues:
1. Display: CJK characters rendered incorrectly (character width)
CJK characters occupy 2 terminal cells, but TerminalCell.Width is always set to 1 in WriteChar() and SetChar(). This causes overlapping and garbled output for all CJK text.
Root cause: No Unicode East Asian Width (UAX #11) implementation.
Affected files:
TerminalBuffer.cs: WriteChar() and SetChar() hardcode Width = 1
TerminalControl.cs: Rendering assumes x = col * _cellWidth without width compensation
FlushTextRun(): runWidth = _textRunBuffer.Length * _cellWidth (assumes 1 cell per char)
- Mouse position, selection, URL detection all assume uniform 1-cell width
Fix needed: Implement wcwidth() equivalent, set Width = 2 for wide characters, mark next cell as continuation (Width = 0), and adjust rendering/mouse/selection accordingly.
2. Input: Korean IME composition fails — jamo appear decomposed
When typing Korean, individual jamo (ㅋ, ㅡ, ㄹ) appear instead of composed syllables (클). The final consonant (batchim) consistently separates: "전" appears as "저" + "ㄴ".
Root cause: TerminalControl extends FrameworkElement, which lacks TSF (Text Services Framework) integration. Without TSF, the Windows IME cannot maintain composition state — it falls back to committing each consonant+vowel pair immediately without waiting for a possible final consonant.
Approaches tried (all insufficient):
Key.ImeProcessed check in OnKeyDown — partial improvement
InputMethod.SetIsInputMethodEnabled — no effect
- Win32 IMM32 API hooks (
ImmGetContext, WM_IME_COMPOSITION) — WPF uses TSF, not IMM32
- Hidden
TextBox as IME proxy with TextChanged — fires during composition, not just on commit
- Hidden
TextBox with TextCompositionManager.TextInput — focus routing breaks
Fix needed: Either rebase TerminalControl on a control with TSF support (e.g., wrap a TextBox), or implement custom TSF integration for proper IME composition handling.
Environment
- Windows 11 Pro
- cmux-windows v1.0.6
- Korean (두벌식) keyboard layout
- .NET 10 SDK
Screenshots
Korean output garbled (before any fix):
- Characters overlap and mix due to width=1 for all characters
Korean input decomposed:
- Typing "클로드코드" produces "클르ㄴㄷ—ㅋㄴㄷ" (batchim separated)
Related
This is a common challenge for Windows terminal emulators. References:
Summary
cmux-windows does not properly handle CJK (Chinese, Japanese, Korean) characters. There are two distinct issues:
1. Display: CJK characters rendered incorrectly (character width)
CJK characters occupy 2 terminal cells, but
TerminalCell.Widthis always set to1inWriteChar()andSetChar(). This causes overlapping and garbled output for all CJK text.Root cause: No Unicode East Asian Width (UAX #11) implementation.
Affected files:
TerminalBuffer.cs:WriteChar()andSetChar()hardcodeWidth = 1TerminalControl.cs: Rendering assumesx = col * _cellWidthwithout width compensationFlushTextRun():runWidth = _textRunBuffer.Length * _cellWidth(assumes 1 cell per char)Fix needed: Implement
wcwidth()equivalent, setWidth = 2for wide characters, mark next cell as continuation (Width = 0), and adjust rendering/mouse/selection accordingly.2. Input: Korean IME composition fails — jamo appear decomposed
When typing Korean, individual jamo (ㅋ, ㅡ, ㄹ) appear instead of composed syllables (클). The final consonant (batchim) consistently separates: "전" appears as "저" + "ㄴ".
Root cause:
TerminalControlextendsFrameworkElement, which lacks TSF (Text Services Framework) integration. Without TSF, the Windows IME cannot maintain composition state — it falls back to committing each consonant+vowel pair immediately without waiting for a possible final consonant.Approaches tried (all insufficient):
Key.ImeProcessedcheck inOnKeyDown— partial improvementInputMethod.SetIsInputMethodEnabled— no effectImmGetContext,WM_IME_COMPOSITION) — WPF uses TSF, not IMM32TextBoxas IME proxy withTextChanged— fires during composition, not just on commitTextBoxwithTextCompositionManager.TextInput— focus routing breaksFix needed: Either rebase
TerminalControlon a control with TSF support (e.g., wrap aTextBox), or implement custom TSF integration for proper IME composition handling.Environment
Screenshots
Korean output garbled (before any fix):
Korean input decomposed:
Related
This is a common challenge for Windows terminal emulators. References: