fix(two-thumb): clear stale stroke buffer so re-typed words don't accumulate geometry (#7)#9
Open
SHAWNERZZ wants to merge 1 commit into
Open
fix(two-thumb): clear stale stroke buffer so re-typed words don't accumulate geometry (#7)#9SHAWNERZZ wants to merge 1 commit into
SHAWNERZZ wants to merge 1 commit into
Conversation
…umulate geometry (#7) When a multi-part word (tap a stem, then swipe the rest — e.g. "do" + swipe -> "doesn't") mis-recognizes and the user backspaces to retry, the previous stroke geometry stuck around and each retry built an ever-longer garbage word. Root cause: the merged stroke lives in WordComposer.mInputPointers, which is intentionally NOT cleared by reset()/backspace (so a gesture commit can re-feed it via setBatchInputWord), and ResizableIntArray.addAt(index) overwrites in place WITHOUT shrinking the length. So after a word is abandoned via backspace, the raw buffer keeps its length; re-typing the stem overwrites only the leading indices and the stale tail survives. The next swipe then snapshots the whole stale buffer as the merged-trail extend base, producing an ever-longer word that grows with each retry. PR AsafMah#61 cleared the extend-base flag and mLiveStroke, but not the mInputPointers buffer the base is re-armed from, so the leak persisted through that fix. Fix: reset mInputPointers when the FIRST tap of a fresh word lands (newIndex == 0 in WordComposer.applyProcessedEvent). This covers every abandonment path (whole-word / batch / per-char-to-empty / cursor move), never touches the gesture-commit flow (batch mode is guarded above), preserves multi-part composition (a tap EXTENDING a gesture has newIndex > 0), and can't disturb mid-word backspace coordinates for normal typing. Space remains the word-submission point. Test: WordComposerTest.testFreshWordResetsStaleInputPointers asserts a stale 5-point buffer surviving reset() is dropped to 1 point on the first fresh tap. Full :app:testOfflineDebugUnitTest shows zero new failures vs the main baseline (same 12 pre-existing/environment-dependent failures). Fixes #7. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3 tasks
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 #7.
Problem
Building a word from a tap stem + a swipe (e.g. tap
do, swipe the rest →doesn't) is the intended multi-part flow, and space stays the word-submission point. But when such a word mis-recognized and you backspaced to retry, the previous stroke geometry stuck around and each retry built an ever-longer garbage word.Root cause (traced end-to-end)
WordComposer.mInputPointers. It's intentionally not cleared byreset()/backspace (so a gesture commit can re-feed it viasetBatchInputWord), andResizableIntArray.addAt(index)overwrites in place without shrinking the length.mLiveStroke, but not themInputPointersbuffer the base is re-armed from — so the leak persisted through that fix.Fix
Reset
mInputPointerswhen the first tap of a fresh word lands (newIndex == 0inWordComposer.applyProcessedEvent). This:newIndex > 0),Testing
WordComposerTest.testFreshWordResetsStaleInputPointers: a stale 5-point buffer survivingreset()is dropped to 1 point on the first fresh tap (fails pre-fix).:app:testOfflineDebugUnitTest: 243 tests, 12 failed = main baseline (242) + this PR's 1 new test, with the identical 12 pre-existing/environment-dependent failures. Zero new failures; normal-typing/autocorrect/recorrection tests unaffected.technology/silo-style multi-part and normal typing still work.🤖 Generated with Claude Code