Skip to content

fix: prevent mobile auto-scroll feedback loops - #1216

Open
ContextFound wants to merge 4 commits into
AppFlowy-IO:mainfrom
ContextFound:fix/mobile-auto-scroll-feedback-loop
Open

fix: prevent mobile auto-scroll feedback loops#1216
ContextFound wants to merge 4 commits into
AppFlowy-IO:mainfrom
ContextFound:fix/mobile-auto-scroll-feedback-loop

Conversation

@ContextFound

Copy link
Copy Markdown

Summary

Fixes #1215.

This fixes a mobile editor auto-scroll feedback loop that remained after the table row-height relayout fix in #1214. On a physical Android device, table focus/defocus could still ANR the app; after moving repeat work off microtasks, the remaining issue surfaced as visible content vibration during table selection.

Root cause

EdgeDraggingAutoScroller._scroll recursively awaited itself while _scrolling was true. ScrollPosition.moveTo can complete synchronously when the scroll position cannot make meaningful progress, so the recursion can become a tight microtask chain that starves frames/input.

Separately, mobile selection changes were starting repeating auto-scroll for ordinary caret/table focus updates. Those updates need at most a one-shot keep-visible nudge; continuous repeat should be reserved for active drag selection.

Fix

  • Schedule repeated auto-scroll ticks with SchedulerBinding.scheduleFrameCallback instead of recursive await _scroll().
  • Preserve the no-progress guard so auto-scroll stops if the scroll offset does not advance.
  • Add a repeat flag to the auto-scroll service.
  • Use repeat: true only for mobile drag modes (leftSelectionHandle, rightSelectionHandle, cursor); ordinary selection/caret updates use one-shot auto-scroll.
  • Update the auto-scroller test helper override for the new optional parameter.

Verification

  • dart format --set-exit-if-changed on touched Dart files
  • flutter analyze
  • Manual release-APK verification on Galaxy S23+ / Android 16: the table tap-out/tap-in interaction no longer ANRs, no new Android Dropbox ANR was written, post-focus screenshots were stable, and manual drag-select around the table looked stable.

Made with Cursor

ContextFound and others added 3 commits June 30, 2026 14:52
EdgeDraggingAutoScroller._scroll re-invokes itself via `await _scroll()`
while `_scrolling` is true. position.moveTo can complete synchronously when
the scrollable cannot advance (already at an extent, zero scroll range, or
pinned), turning the self-recursion into a tight microtask loop that pins
the platform/UI thread with no frames — an ANR on mobile when leaving a
table cell (symbolicated: _microtaskLoop -> Future completion ->
EdgeDraggingAutoScroller._scroll). Stop when moveTo makes no forward
progress, which bounds the loop.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@CLAassistant

CLAassistant commented Jun 30, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mobile selection auto-scroll can enter feedback loop / ANR when table focus changes

2 participants