-
Notifications
You must be signed in to change notification settings - Fork 58
fix: Korean/CJK IME composition events not captured #120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
IME composition events (compositionstart, compositionupdate, compositionend) fire on the focused element. When using a hidden textarea for input, the textarea receives focus, but composition event listeners were attached to the container element, causing the events to be missed. Changes: - input-handler.ts: Attach composition events to inputElement (textarea) if available, otherwise fall back to container - terminal.ts: Focus textarea instead of container in focus() method - selection-manager.ts: Skip wide character continuation cells when extracting selection text (fixes spaces between CJK characters) This fixes Korean, Chinese, Japanese and other IME input methods. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f572fa14f7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Focus the textarea for keyboard/IME input. | ||
| // The textarea is the actual input element that receives keyboard events | ||
| // and IME composition events. Focusing the container doesn't work for IME | ||
| // because composition events fire on the focused element. | ||
| const target = this.textarea || this.element; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keep blur behavior aligned with textarea focus
The new focus path now targets the hidden textarea when it exists, but blur() still calls this.element.blur(). When the terminal is open (default case creates the textarea), calling terminal.blur() will leave the textarea focused, so keyboard/IME input continues to be captured even though callers expect blur to release focus. This is a regression introduced by switching focus to the textarea. Consider blurring the same target (this.textarea || this.element) or explicitly blurring the textarea when present.
Useful? React with 👍 / 👎.
Display a small "조합중: X" indicator in the top-right corner during IME composition. This helps users see what character is being composed before it's finalized. Korean is a compositional writing system where characters are built step-by-step (e.g., ㅅ → 세 → 셰). This visual feedback makes the composition process clearer. Closes #2 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When pressing space or period to end Korean IME composition, the keydown event fires before compositionend. This caused the triggering character to be output before the composed text (e.g., "세요" becomes "세 요"). Added compositionJustEnded flag that blocks the first keydown after composition ends, preventing the character order reversal. Fixes #1 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove contenteditable from container (causes IME to insert text as DOM nodes) - Set container tabindex="-1" so it's not focusable - Add focus redirection from container to textarea - Queue composition-ending key (space, period) to process after compositionend - This ensures correct character order: "세요 " instead of "세 요" Key changes: 1. input-handler.ts: Add pendingKeyAfterComposition to queue the terminating key 2. terminal.ts: Remove contenteditable, set tabindex="-1", add focus redirection Fixes Korean, Chinese, and Japanese IME input. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

Summary
Fixes #119
Problem
IME composition events (
compositionstart,compositionupdate,compositionend) fire on the focused element. When using a hidden textarea for keyboard input (as ghostty-web does), the textarea receives focus, but composition event listeners were attached to the container element. This caused all IME events to be missed.Additionally, when copying CJK text from the terminal, spaces appeared between characters because the continuation cells (width=0) for wide characters were being treated as empty spaces.
Changes
inputElement(textarea) if availablefocus()methodTest Plan
Known Limitation
Fast Korean typing may occasionally insert extra spaces due to composition event timing. This is tracked as a separate issue.
🤖 Generated with Claude Code