Fix preview pane scrolling to bottom on checkbox click#134
Conversation
When clicking a task-list checkbox in preview mode, dispatching the source edit could trigger scroll-sync via the editor's scrollDOM and jump the preview to the editor's cursor position (often the bottom of the document). Save and restore the preview pane's scroll position around the dispatch to prevent this. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Preserves the preview pane scroll position when toggling task items, preventing editor dispatch side-effects from shifting the preview unexpectedly.
Changes:
- Save
previewPane.scrollTopbefore dispatching editor changes. - Restore the saved scroll position immediately and again on the next animation frame.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When clicking a task-list checkbox in preview mode, the editor's scrollDOM could emit a scrollend event that triggered syncScrollProgress and jumped the preview to the editor's cursor position (often the bottom of the document). Instead of saving/restoring scrollTop (which risks overriding user momentum scrolling from a delayed rAF callback), suppress the scroll-sync listener for the duration of the dispatch and re-enable it on the next animation frame. The preview position is never touched, so user scroll state is fully preserved. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Addressed Copilot's feedback — revised approach in the latest commit: Problem with the original fix: saving/restoring Revised approach: instead of touching |
|
Addressing all three Copilot flags inline: Threads 1 & 2 — rAF can override user scroll Why it was a problem: The How it's fixed: Both Thread 3 — double Why it was a problem: Two back-to-back writes to How it's fixed: Both assignments are removed entirely — the suppress approach means we never touch |
|
I need a repro before reviewing changes. Just tried clicking on checkboxes in overlay mode, no repro. Can you please share more details? For example, your system version, app version, app settings/customizations, other extensions. |
|
Thanks for checking — here are the details and the exact repro path. Environment
Repro steps The bug only surfaces when the editor's scroll position differs from the preview's — so a short document that fits on one screen won't show it.
- [ ] Task one
- [ ] Task two
- [ ] Task three
[paste ~60 blank lines here, or any filler content]
End of document.
Before fix: the preview pane jumps back to the bottom (matching the editor's last scroll position). If the editor cursor is already at the top when you switch to preview, the two scroll positions match and there's no visible jump — which is why it's easy to miss in a quick test. |
|
Thanks, I can reproduce the issue following your steps. However, I am still having trouble understanding: Why is only overlay mode affected? Doing the same in side-by-side mode works fine. |
|
Good question — the difference comes down to whether the editor and preview scroll positions can get out of sync. Side-by-side mode: the user scrolls the editor and the preview follows via Overlay/preview mode: the editor is hidden behind the overlay. The user scrolls the preview independently, completely decoupled from the editor. The editor's In short: side-by-side keeps the two in sync so the jump is invisible. Overlay lets them diverge, so the sync triggered by the dispatch is always destructive. |
|
Correction to my previous comment — the issue does occur in side-by-side mode too under the same conditions (editor and preview scrolled to different positions). I was wrong to say side-by-side was unaffected. The root cause is the same regardless of mode: clicking a checkbox dispatches a silent edit to the editor, which can trigger a The fix ( |
|
Interesting, while I still don't have a repro in side-by-side, I think it can theoretically happen. I checked your change and believe it works. However I think blocking scroll temporarily is a bit strange, and a rAF may be a concern. Can you please check if changes in #135 fixes the issue? It's simpler and self-contained. |
Problem
Clicking a task-list checkbox in preview mode (overlay) caused the preview pane to jump to the bottom of the document.
Root cause:
handleTaskItemToggledispatches a silent edit to the editor to sync the checkbox state. That dispatch can cause the editor'sscrollDOMto emit ascroll/scrollendevent, which triggerssyncScrollProgress. The editor'sscrollTopreflects wherever the cursor was during the last edit session (often the bottom of the document), so the preview pane is incorrectly snapped to that position.Fix
Save
previewPane.scrollTopimmediately before the dispatch and restore it both synchronously and viarequestAnimationFrame(to cover async scroll triggers from WKWebView or CodeMirror's measure cycle).The checkbox toggle and source-sync behavior are unchanged.
Testing
🤖 Generated with Claude Code