fix(desktop): commit IME-composed text on compositionend - #40200
Closed
chajinheon wants to merge 1 commit into
Closed
fix(desktop): commit IME-composed text on compositionend#40200chajinheon wants to merge 1 commit into
chajinheon wants to merge 1 commit into
Conversation
Korean/CJK input was truncated and could stall in the chat composer. In Chromium the final `input` event of an IME commit carries isComposing=true, so handleEditorInput skips the state write, and no input event follows compositionend. onCompositionEnd only flipped the composing flag, so the last composed cluster (e.g. a Korean syllable) stayed in the DOM but never reached draft state — lost on submit, and a source of DOM/state divergence that froze further input. Extract the input commit into commitEditorState and run it from compositionend so the finalized text is written to draft state. ASCII typing is unaffected (isComposing is always false). Adds a regression test driving the real Chromium IME event order. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Author
|
Verified in a packaged build on macOS (arm64, ad-hoc signed Typed long Korean sentences with rapid input, e.g.
For contrast, the current released desktop build (without this change) still drops the trailing syllable on the same input — which is the originally reported symptom. |
tonydwb
approved these changes
Jun 6, 2026
tonydwb
left a comment
There was a problem hiding this comment.
Approved. Fixes IME composition commit on compositionend in desktop composer. Shared commitEditorState helper, regression test included. Clean.
Author
This was referenced Jul 14, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Korean/CJK input in the desktop chat composer is broken: while typing, the last syllable is dropped on send ("글자가 짤려나감"), and input can stall after a few words. This is widely reported across CJK languages but had no merged fix.
Root cause
In Chromium (Electron), the final
inputevent of an IME commit carriesisComposing=true.handleEditorInputcorrectly skips state writes during composition — but noinputevent followscompositionend. The existingonCompositionEndhandler only flippedcomposingRef.current = falseand never committed the finalized DOM text into draft state.Result: the committed cluster lives in the contentEditable DOM but never reaches
draftRef/the composer store. On submit,submitDraft()reads the stale draft → the trailing syllable is lost. The same stale-draft divergence is why the send button can stay as the voice button (it derives fromhasComposerPayload, i.e.draft). ASCII typing is unaffected becauseisComposingis always false there — which is likely why this survived: contributors typing ASCII never see it.The existing guards covered "don't submit on Enter mid-composition" but missed "commit the text when composition ends" — the fix completes the other half.
Fix
Extract the input-commit logic into a shared
commitEditorState(editor)and invoke it fromonCompositionEndafter clearing the composing flag, so IME-finalized text is written to draft state exactly once. No behavior change for non-IME input.Surgical: two handlers in
apps/desktop/src/app/chat/composer/index.tsx, plus a regression test driving the real Chromium IME event order (compositionstart→input{isComposing:true}→compositionend).Related issues
Desktop composer CJK truncation / stale-draft cluster this addresses:
Likely resolved as a side effect (send button stuck on voice/hidden stems from the same empty
draft): #39231, #38883, #40146.Not covered here (different code path): #38117 is the TUI/CLI (prompt_toolkit) analog, not the desktop composer.
Verification
npm run type-check— cleaneslinton changed files — cleanvitestcomposer suite — 12 passed (10 existing + 2 new)The regression test reproduces the exact Chromium IME event order. Runtime verification in a packaged build is in progress.
🤖 Generated with Claude Code