ApplyIMECommitToModel computed the caret pushed to the IME right after a commit as Range.End + len(text). That is correct for a plain insertion (Start == End) but wrong for a replacement — the case a swipe/autocorrect over a selection produces: the inserted text starts at Range.Start, so the caret is Range.Start + len(text). A 4-rune replacement (the 'samet' autocorrect on the phone) pushed the caret 4 runes past the inserted text, desynchronizing the IME's caret from ours at exactly the moment its local model was being updated; the persistent 4-rune drift that followed (every commit 4 runes ahead, then the empty-fix-up loop) matches this. The logic side (applyIMECommitBytes) already computed the correct caret; this aligns the renderer's immediate push with it. Also log every IME push (snippet restarts, selection updates, commit pushes) from the renderer: the phone incident's logcat rotated before it could be re-analyzed, so the next occurrence must be reconstructable from what we actually pushed to the IME. |
||
|---|---|---|
| .. | ||
| icons | ||
| caret_point_test.go | ||
| element.go | ||
| layout.go | ||
| pinch_test.go | ||
| pinch_tracker.go | ||
| real_draw_probe_test.go | ||
| render.go | ||
| reveal_focus_drain_test.go | ||
| tag_identity_test.go | ||
| unit.go | ||