fix(flterm): recover text input when a delta desyncs from the sentinel - #145
Open
jacobaraujo7 wants to merge 2 commits into
Open
fix(flterm): recover text input when a delta desyncs from the sentinel#145jacobaraujo7 wants to merge 2 commits into
jacobaraujo7 wants to merge 2 commits into
Conversation
The session keeps a one-space sentinel and pushes it back via setEditingState after every commit. Some platforms -- notably iOS -- keep their own marked-text buffer and ignore that reset, so a later delta references offsets past our sentinel value. Applying it throws (RangeError), and because that happens inside updateEditingValueWithDeltas the exception tears down the text-input channel: typing freezes completely. It reproduces on iOS right after composing an accent (dead key + vowel), which commits an IME-like character and resets the buffer the platform then ignores. Guard each delta.apply; on failure, resync the platform back to the sentinel and drop the batch instead of letting the exception kill the connection. A regression test drives a delta whose range exceeds the sentinel and asserts the session recovers, stays attached, and keeps accepting input. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Owner
|
The tests pass with and without the fix. I'm also not able to reproduce this on my phone; have you? What are the steps? |
When a delta could not be applied to the sentinel, the previous recovery only pushed the sentinel back via setEditingState. iOS ignores that and keeps its own marked-text buffer, so every following delta re-desyncs and input is dropped indefinitely (typing freezes after composing a dead-key accent with a physical keyboard). Reopen the text-input connection so iOS discards the marked text and re-anchors on a fresh sentinel. The reopen is deferred to a microtask because closing/reopening synchronously inside the delta callback lands mid-delivery and does not re-engage key input until the view is refocused; the fresh connection is re-shown so key delivery resumes without a manual refocus. The composed character carried by the failing delta is salvaged and committed before the batch is dropped so the accent is not lost. Co-Authored-By: Claude Opus 4.8 <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.
Summary
On iOS, composing an accent (dead key + vowel) freezes the terminal: after the
accent commits, no further typing registers. Plain keys are fine until the first
accent.
Root cause
TextInputSessionkeeps a one-space sentinel and pushes it back viasetEditingStateafter every commit, translating deltas relative to it. iOS,however, keeps its own marked-text buffer and ignores that reset right after
a composition. An accent commits an IME-like character (
> 0x7f), the buffer isreset on our side but not on iOS's, and the next delta iOS sends references
offsets past our sentinel value.
delta.apply(_value)then throws aRangeError. Because that happens insideupdateEditingValueWithDeltas, the exception tears down the platform text-inputchannel — every subsequent keystroke is dropped, so typing freezes entirely.
Desktop platforms honor the reset, so they never hit it.
Fix
Guard each
delta.apply; on failure, resync the platform back to the sentineland drop that batch instead of letting the exception kill the connection. The
channel stays alive and input keeps working.
Test
Adds a regression test that drives a delta whose range exceeds the sentinel
(which throws today) and asserts the session recovers, stays attached, and keeps
committing subsequent input.
flutter analyzeis clean; the fullfltermsuitepasses.