fix(desktop): guard IME composition Enter key on macOS Chromium edge case - #59319
fix(desktop): guard IME composition Enter key on macOS Chromium edge case#59319aotian16 wants to merge 1 commit into
Conversation
…onend edge case On macOS, some Chinese IMEs trigger a Chromium bug where the Enter keydown event is dispatched *after* compositionend without setting nativeEvent.isComposing=true. The existing composingRef + isComposing guards both miss this window, so pressing Enter to confirm an IME candidate fires submitDraft() instead. Fix: introduce recentCompositionRef, set true on compositionend and cleared after 100ms. The keydown handler checks this flag as a third guard alongside composingRef and isComposing, covering all known IME timing scenarios.
Related: #37483 (canonical issue — Enter sends message during IME composition). Competing/alternate fix to #37487 (adds |
teknium1
left a comment
There was a problem hiding this comment.
Thanks for targeting the post-compositionend Chromium sequence; current main still lacks that guard at apps/desktop/src/app/chat/composer/index.tsx:370.
Problems
apps/desktop/src/app/chat/composer/index.tsx:736schedules an independent clear on every composition end. If two compositions finish within 100 ms, the first callback can clearrecentCompositionRefbefore the second window expires, re-opening the reported submit path.- Commit
c4751749d0ba13cb3deaa1c94404f2900899cb7fadds no regression test. The existingapps/desktop/src/app/chat/composer/ime-composition-dom-repro.test.tsx:61covers draft synchronization, not an Enter dispatched after compositionend withisComposing=false.
Suggested changes
- Cancel or supersede the prior timer so only the latest composition-end window can clear the guard, and clean it up on unmount.
- Add a fake-timer regression test for the stated event ordering, including consecutive compositions and a normal Enter after expiration.
Automated hermes-sweeper review.
|
|
||
| // Chromium on macOS sometimes dispatches the Enter keydown event | ||
| // *after* compositionend, without setting isComposing=true on the | ||
| // native event. The brief guard window prevents that Enter from |
There was a problem hiding this comment.
Each composition end creates an independent timer. If another composition ends before this callback runs, this older callback can clear the shared ref during the newer composition's 100 ms window. Store and cancel the prior timer (or use a generation token) before scheduling this callback.
Problem
When using a Chinese IME on macOS (e.g. macOS Pinyin), pressing Enter to confirm an IME candidate sometimes submits the draft message instead of committing the composed text.
Root Cause
The existing IME guards check
composingRef.current(set by compositionstart/compositionend) andevent.nativeEvent.isComposing. However, macOS Chinese IMEs trigger a known Chromium edge case where the Enter keydown event is dispatched after compositionend withoutisComposing=true. Both guards miss this window, so Enter reachessubmitDraft().Fix
Introduce
recentCompositionRef, set totrueon compositionend and cleared after a 100ms timeout. The keydown handler now checkscomposingRef.current || event.nativeEvent.isComposing || recentCompositionRef.current, which covers all IME timing scenarios.Testing