A simple, high performance text editor.
On device (Pixel 9 Pro) the relaunch landed further UP than the saved position: while the restore scroll is still armed (scale + size + content can take ~600 ms), the top-of-file window is what gets rendered, and its shaping feedback — real wrap counts for lines ABOVE the restored line — lands before or just after the offset is applied. The counts are correct data, but they change V(line), so the line-derived offset (synthesized for the all-estimate index) maps to a shallower line and the viewport drifts up; the save then persists the drifted line and every subsequent relaunch lands there. Fix: the restore pins the logical line. Until the restored window's own shaping arrives (or a 2 s timeout, or the user scrolls / a search jumps), every accepted wrap correction re-derives the offset as VisualsBefore(line)*lh + sub under the corrected index. The pin refresh does not clamp to MaxScroll: the correction just grew the index, so the pre-layout clamp value is stale and would under-clamp the re-derived offset (the layout of the emitted frame clamps to the fresh value). Also: the apply-time offset is mapped through VisualsBefore under the current index (identical to line*lh while the index is all estimates), so pre-apply corrections are absorbed instead of gated away. Verified on device: saved line 420 -> restored 420 (was 333); saved 573 (near EOF, clamp territory) -> restored 573. New e2e regression TestRestore_LinePinHoldsAcrossLateWrapFeedback replays the late top-window feedback and fails pre-fix (window drifts 200 -> 66). |
||
|---|---|---|
| .qwen | ||
| cmd/pad | ||
| doc | ||
| internal | ||
| scripts | ||
| .DS_Store | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||