Conversation
When an input method finishes a composition, it can commit the text via -insertText:replacementRange: and then hand the original keystroke back to the client as a command selector. iTerm2 performed the first half and dropped the second. With the built-in Korean 2-Set IME this is visible as a stray jamo: type 가가, press Backspace twice, and the second press commits the remaining ㄱ via -insertText: and then delivers deleteBackward:. The delete was dropped, so the jamo stayed and a third Backspace was needed to remove it. Return during composition had the same shape with insertNewline:. -doCommandBySelector: could not act on it because its body is gated behind two advanced settings that default to NO, and because its inner condition excludes _hadMarkedTextBeforeHandlingKeypressEvent. That flag is true both when the IME consumed the key to edit its composition (nothing to do) and when the IME committed and handed the key back (ours to handle). The class already distinguishes the two: _keyPressHandled is set only when -insertText:replacementRange: committed text during this keypress. The post-Cocoa fallback in -handleEventWithCocoa: cannot recover the event either, since it is gated on the same flag and on _keyPressHandled. Verified against a debug log of both repros. Issue 13030, and the same symptom in issue 10817. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.
Fixes gnachman/iterm2#13030 on the GitLab tracker. Same symptom as the older #10817 there.
The bug
An input method can finish a composition by committing the text with
-insertText:replacementRange:and then handing the original keystroke back to the clientas a command selector. iTerm2 performed the first half and dropped the second.
With the built-in Korean 2-Set IME: type
가가, press Backspace twice. On the second pressthe IME commits the remaining
ㄱand then deliversdeleteBackward:. The delete wasdropped, so the jamo stayed and a third Backspace was needed. Return during composition had
the identical shape with
insertNewline:.Debug log for the second Backspace, trimmed:
No
0x7fis written for that keypress. The next one belongs to the third Backspace.Why it could not be handled
-doCommandBySelector:could not act on it for two reasons: its body is behindexperimentalKeyHandling/enableCharacterAccentMenu, both defaulting to NO, and itsinner condition excludes
_hadMarkedTextBeforeHandlingKeypressEvent.That flag is true in two different situations:
Only the first should suppress.
_keyPressHandledalready separates them: it is reset in-handleKeyDownEvent:...and set only when-insertText:replacementRange:committednon-empty text during this keypress. Note the ordering in the log - the marked text is
cleared before the selector arrives, so
-hasMarkedTextis already NO by then.The post-Cocoa fallback in
-handleEventWithCocoa:cannot recover the event either: it isgated on the same flag and on
_keyPressHandled.About
insertNewline:The comment at the existing condition says Return during composition is deliberately not
passed to the delegate, so I want to flag that this PR changes it knowingly rather than by
accident.
The argument for including it: the IME uses one mechanism for both keys. It commits and
hands the key back, identically, whether that key is Backspace or Return. Honouring one and
dropping the other splits a single rule by selector name. WezTerm honours both; Terminal.app
honours the delete and drops the Return, so both behaviours have precedent.
If you would rather keep Return as it is, dropping the
insertNewline:line from thecondition is the whole change - the Backspace fix stands on its own.
Testing
Built from
masterand verified by hand with the built-in Korean 2-Set IME on macOS 26.6.2.Before the patch, on
master, both symptoms reproduce.After:
가가+ Backspace x2 leaves no jamo나+ Return commits and submits in one pressNot tested: IME reconversion that uses a real
replacementRange(Japanese/Chinese). Worthnoting because
-insertText:replacementRange:calls-doCommandBySelector:itself for thatpath. Reading it, the new branch should not fire there - the marked text has not been
cleared yet at that point, so
![self hasMarkedText]is false; and for reconversion ofalready-committed text
_hadMarkedTextBeforeHandlingKeypressEventis false. But I have notexercised it, so it deserves a look.