fix(desktop): prevent IME submit in inline edit composer - #40557
Conversation
alpindiay
left a comment
There was a problem hiding this comment.
Code Review: fix(desktop): prevent IME submit in inline edit composer
Summary
Prevents IME (Input Method Editor) composition events from leaking into draft state or triggering premature submission in the inline message edit composer. Mirrors the same IME composition guards already present in the main composer.
Issues Found
None. This is a clean, well-contained fix.
What Looks Good
composingReftracks IME state identically to the main composer patternhandleInputis gated on!composingRef.current— prevents preedit text from syncing to draftsubmitEditis gated on!composingRef.current— prevents Enter-during-composition from submittinghandleKeyDownchecks bothcomposingRef.currentandevent.nativeEvent.isComposingas a belt-and-suspenders guardonCompositionEndresets the ref and flushes the final composed text to draft- The
flushEditorToDrafthelper extracts the shared logic (empty BR cleanup + sync + trigger refresh), reducing duplication - Test reproduces the exact CJK IME scenario: compositionStart → type → Enter (isComposing=true) → no submit → compositionEnd → Enter → submit with correct text
- No security concerns, no regression risk for non-IME users
Minor Suggestion (cosmetic)
The test file uses vi from vitest but vi.fn() only — consider import { vi } from "vitest" explicitly for clarity, though the current destructured describe, expect, it, vi pattern is consistent with the rest of the test suite.
teknium1
left a comment
There was a problem hiding this comment.
Thanks for isolating the inline-edit IME path. The underlying issue is still present on current main: apps/desktop/src/components/assistant-ui/thread/user-edit-composer.tsx:573-576 submits Enter without checking composition state, and its editor wiring at :627-653 has no composition handlers.
Problems
- The patch targets the former
thread.tsx; commit7ff6908a5moved this component tothread/user-edit-composer.tsx. Port the guard and composition-end flush there instead. user-edit-ime-repro.test.tsxtests a copiedHarness, not the production editor. Current main's runtime-backed edit harness isthread/user-message-edit.test.tsx:80-115; extend that path so the regression remains coupled to actualUserEditComposerwiring.
Suggested changes
- Apply the main-composer pattern from
app/chat/composer/index.tsx:364-372and:727-741tothread/user-edit-composer.tsx. - Exercise composition start, IME Enter, composition end, and a subsequent submit against the real edit composer.
Automated hermes-sweeper review.
cc42cb7 to
68b3b19
Compare
|
Addressed in 68b3b196. Ported the IME composition guard and composition-end draft flush to the current thread/user-edit-composer.tsx implementation, using both the composition ref and nativeEvent.isComposing to prevent candidate-confirmation Enter events from submitting an inline edit. Preedit input is excluded from draft synchronization, while committed text is flushed on compositionend. |
|
Independent verification from an affected user (not the author) — this patch fixes a variant of #40544 that the issue doesn't currently describe, and I can confirm the bug is still live on today's The variant#40544 describes pressing Enter to confirm an IME candidate. There's a second, arguably more common way Chinese full-pinyin users hit this: to type literal ASCII without leaving the IME, you type the letters and press Enter instead of Space, which dismisses the candidate list and commits the raw buffer verbatim. So That Enter is consumed by the IME, but the inline edit composer reads it as "save the edit" — the edit submits mid-word. For a bilingual user this fires constantly while editing an already-sent message, because mixing English tokens into Chinese text is routine. ResultTested against
So the |
|
Thanks for this fix! It was salvaged into #86760 (cherry-picked onto current main with your authorship preserved in the commit history) and is now merged. Closing since the work has landed. |
What does this PR do?
Extends the Desktop IME handling work from #40210 to the separate inline-edit composer used for editing already-sent user messages.
#40210fixed the main chat composer path, but the inline editor inapps/desktop/src/components/assistant-ui/thread.tsxstill had its own Enter-to-submit path without the same composition guards oronCompositionEnddraft flush. As a result, pressing Enter to confirm a CJK IME candidate while editing an already-sent message could immediately submit the edit.This PR brings that inline-edit path into parity with the main composer by tracking composition state, skipping preedit draft sync, ignoring submit-on-Enter while composing, and flushing committed text on
compositionend.Related Issue
Fixes #40544
Type of Change
Changes Made
apps/desktop/src/components/assistant-ui/thread.tsxisComposing/ composition is activeonCompositionEndso the inline edit path matches the#40210main-composer behaviorapps/desktop/src/components/assistant-ui/user-edit-ime-repro.test.tsxto lock the regression with a focused DOM reproHow to Test
Automated checks run locally:
cd apps/desktop && npx vitest run --environment jsdom src/components/assistant-ui/user-edit-ime-repro.test.tsxcd apps/desktop && npx vitest run --environment jsdom src/app/chat/composer/ime-composition-dom-repro.test.tsxcd apps/desktop && npm run type-checkcd apps/desktop && npx eslint src/components/assistant-ui/thread.tsx src/components/assistant-ui/user-edit-ime-repro.test.tsxChecklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests passDocumentation & Housekeeping
docs/, docstrings) — or N/Acli-config.yaml.exampleif I added/changed config keys — or N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — or N/AScreenshots / Logs
Regression is covered by a focused DOM test for the inline edit composer path, plus the existing main-composer IME repro test from #40210.