Skip to content

Fix: text selection context menu should reappear after a non-fling scroll on Android and iOS#185054

Merged
auto-submit[bot] merged 3 commits into
flutter:masterfrom
Renzo-Olivares:handle-context-menu-on-scroll-fix
Apr 18, 2026
Merged

Fix: text selection context menu should reappear after a non-fling scroll on Android and iOS#185054
auto-submit[bot] merged 3 commits into
flutter:masterfrom
Renzo-Olivares:handle-context-menu-on-scroll-fix

Conversation

@Renzo-Olivares

@Renzo-Olivares Renzo-Olivares commented Apr 14, 2026

Copy link
Copy Markdown
Contributor

Fixes #185052

This change fixes an issue where the context menu would not reappear on the end of a non-fling scroll (a short scroll that does not create any ballistic simulation). This was due to no frames being scheduled after a non-fling scroll so the scheduled addPostFrameCallback could not run.

This issue was not caught by any of our tests because in testWidgets semantics is enabled by default. When semantics is enabled we hit a special case where a semantics update schedules an additional frame at the end of a scroll. The added regression test simulates this by running with semantics disabled.

setIgnorePointer is called at the end of a scroll

void setIgnorePointer(bool value) {
if (_shouldIgnorePointer == value) {
return;
}
_shouldIgnorePointer = value;
if (_ignorePointerKey.currentContext != null) {
final renderBox =
_ignorePointerKey.currentContext!.findRenderObject()! as RenderIgnorePointer;
renderBox.ignoring = _shouldIgnorePointer;
}
}

and setIgnorePointer trigers a semantics update

set ignoring(bool value) {
if (value == _ignoring) {
return;
}
_ignoring = value;
if (ignoringSemantics == null) {
markNeedsSemanticsUpdate();
}
}

and RenderObject.markNeedsSemanticsUpdate short-circuits if semantics/screenreader is disabled resulting in no additional frames scheduled.

/// Mark this node as needing an update to its semantics description.
///
/// This must be called whenever the semantics configuration of this
/// [RenderObject] as annotated by [describeSemanticsConfiguration] changes in
/// any way to update the semantics tree.
void markNeedsSemanticsUpdate() {
assert(!_debugDisposed);
assert(!attached || !owner!._debugDoingSemantics);
if (!attached || owner!._semanticsOwner == null) {
return;
}
_semantics.markNeedsUpdate();
}

Screen.Recording.2026-04-14.at.3.46.01.PM.mov

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools.
  • I read the [Tree Hygiene] wiki page, which explains my responsibilities.
  • I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
  • I signed the [CLA].
  • I listed at least one issue that this PR fixes in the description above.
  • I updated/added relevant documentation (doc comments with ///).
  • I added new tests to check the change I am making, or this PR is [test-exempt].
  • I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
  • All existing and new tests are passing.

…e in same frame

  ScrollEndNotification (from a drag ending) and ScrollStartNotification
  (from the subsequent ballistic animation) can be dispatched in the same
  build phase. The previous addPostFrameCallback ran after both had been
  processed, showing the toolbar during an active ballistic scroll.

  Replaced addPostFrameCallback with scheduleFrameCallback so the
  toolbar-show logic runs at the beginning of the next frame, before any
  new scroll notifications are dispatched in that frame's build phase.
@github-actions github-actions Bot added a: text input Entering text in a text field or keyboard related problems framework flutter/packages/flutter repository. See also f: labels. labels Apr 14, 2026
@Renzo-Olivares Renzo-Olivares changed the title Fix: text selection context menu should reappear after a non-fling scroll Fix: text selection context menu should reappear after a non-fling scroll on Android and iOS Apr 14, 2026
@Renzo-Olivares Renzo-Olivares added the CICD Run CI/CD label Apr 14, 2026
@Renzo-Olivares Renzo-Olivares marked this pull request as ready for review April 14, 2026 23:16

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request modifies EditableText to use scheduleFrameCallback instead of addPostFrameCallback for toolbar scheduling and adds a regression test for context menu visibility during scrolls when semantics are disabled. Review feedback suggests reverting to addPostFrameCallback to ensure accurate positioning after layout, using ensureVisualUpdate() to guarantee the callback executes, and restoring the debugLabel for improved debuggability.

}
_showToolbarOnScreenScheduled = true;
SchedulerBinding.instance.addPostFrameCallback((Duration _) {
SchedulerBinding.instance.scheduleFrameCallback((Duration _) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Using scheduleFrameCallback changes the execution timing to the transient phase of the frame (before layout and paint). For a context menu that needs to be positioned accurately relative to the text, it is generally safer to use addPostFrameCallback to ensure that any layout changes (such as those from the scroll) have been applied. To address the issue where no frame is scheduled after a non-fling scroll, you can call SchedulerBinding.instance.ensureVisualUpdate() after registering the callback.

      SchedulerBinding.instance.addPostFrameCallback((Duration _) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any precedent for using ensureVisualUpdate outside of binding.dart. I've updated the implementation to call addPostFrameCallback when the scheduler phase is within an active frame, scheduling a post frame callback here ensures the callback will run after that frame. If we are in the idle phase or postFrameCallback phase we cannot guarantee that there is another frame after so we have to call scheduleFrameCallback in that scenario.

_dataWhenToolbarShowScheduled = null;
}
}, debugLabel: 'EditableText.scheduleToolbar');
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Restoring the debugLabel for better debuggability and ensuring a frame is scheduled so that the post-frame callback can execute even when no other UI updates are pending.

      }, debugLabel: 'EditableText.scheduleToolbar');
      SchedulerBinding.instance.ensureVisualUpdate();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any precedent for using ensureVisualUpdate outside of binding.dart so i'm not sure if that's the direction we want to go in.

@github-actions github-actions Bot removed the CICD Run CI/CD label Apr 15, 2026
@Renzo-Olivares Renzo-Olivares added the CICD Run CI/CD label Apr 15, 2026

@loic-sharma loic-sharma left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@Renzo-Olivares Renzo-Olivares added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 18, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Apr 18, 2026
@Renzo-Olivares Renzo-Olivares removed this pull request from the merge queue due to a manual request Apr 18, 2026
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Apr 18, 2026
@Renzo-Olivares

Copy link
Copy Markdown
Contributor Author

Opened up #185230 , the behavior before/after this PR is the same with system context menus.

@Renzo-Olivares Renzo-Olivares added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 18, 2026
@auto-submit auto-submit Bot added this pull request to the merge queue Apr 18, 2026
Merged via the queue into flutter:master with commit beb2ad1 Apr 18, 2026
93 checks passed
@flutter-dashboard flutter-dashboard Bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Apr 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 18, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 19, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 19, 2026
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Apr 20, 2026
flutter/flutter@8e8a194...2844af6

2026-04-19 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from bWoigpGIb60B6C7hD... to aDbXQm6WA0wFCAUp-... (flutter/flutter#185253)
2026-04-18 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from di3JdYrdE9OFu8Iyl... to bWoigpGIb60B6C7hD... (flutter/flutter#185231)
2026-04-18 rmolivares@renzo-olivares.dev Fix: text selection context menu should reappear after a non-fling scroll on Android and iOS (flutter/flutter#185054)
2026-04-18 flar@google.com Rect constructors for circle bounds (MakeCircle/EllipseBounds) (flutter/flutter#185110)
2026-04-17 97480502+b-luk@users.noreply.github.com Change uber SDF to get pixel size (for AA) using euclidean distance rather than manhattan distance. (flutter/flutter#184984)
2026-04-17 engine-flutter-autoroll@skia.org Roll Dart SDK from 7c2564c18770 to 9648f446f131 (7 revisions) (flutter/flutter#185223)
2026-04-17 47866232+chunhtai@users.noreply.github.com Rewrites no-response workflow to work with pr as well (flutter/flutter#185163)
2026-04-17 15619084+vashworth@users.noreply.github.com Only use LLDB breakpoint in debug mode (flutter/flutter#185158)
2026-04-17 flar@google.com add playground to test SDF primitive rendering under transforms (flutter/flutter#185010)
2026-04-17 30870216+gaaclarke@users.noreply.github.com Adds sdf rrects (and fixes opacity + color source) (flutter/flutter#184999)
2026-04-17 matt.kosarek@canonical.com Implementation of popup windows for Win32 (flutter/flutter#184516)
2026-04-17 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from R2EllDf4DgBXVNuiN... to dQ4PjIJB5kZFU8Y32... (flutter/flutter#185207)
2026-04-17 chris@bracken.jp [iOS] Update previousCompositionOrder to return Obj-C type (flutter/flutter#185136)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
creatorpiyush pushed a commit to creatorpiyush/packages that referenced this pull request Jun 10, 2026
…r#11531)

flutter/flutter@8e8a194...2844af6

2026-04-19 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from bWoigpGIb60B6C7hD... to aDbXQm6WA0wFCAUp-... (flutter/flutter#185253)
2026-04-18 engine-flutter-autoroll@skia.org Roll Fuchsia Linux SDK from di3JdYrdE9OFu8Iyl... to bWoigpGIb60B6C7hD... (flutter/flutter#185231)
2026-04-18 rmolivares@renzo-olivares.dev Fix: text selection context menu should reappear after a non-fling scroll on Android and iOS (flutter/flutter#185054)
2026-04-18 flar@google.com Rect constructors for circle bounds (MakeCircle/EllipseBounds) (flutter/flutter#185110)
2026-04-17 97480502+b-luk@users.noreply.github.com Change uber SDF to get pixel size (for AA) using euclidean distance rather than manhattan distance. (flutter/flutter#184984)
2026-04-17 engine-flutter-autoroll@skia.org Roll Dart SDK from 7c2564c18770 to 9648f446f131 (7 revisions) (flutter/flutter#185223)
2026-04-17 47866232+chunhtai@users.noreply.github.com Rewrites no-response workflow to work with pr as well (flutter/flutter#185163)
2026-04-17 15619084+vashworth@users.noreply.github.com Only use LLDB breakpoint in debug mode (flutter/flutter#185158)
2026-04-17 flar@google.com add playground to test SDF primitive rendering under transforms (flutter/flutter#185010)
2026-04-17 30870216+gaaclarke@users.noreply.github.com Adds sdf rrects (and fixes opacity + color source) (flutter/flutter#184999)
2026-04-17 matt.kosarek@canonical.com Implementation of popup windows for Win32 (flutter/flutter#184516)
2026-04-17 engine-flutter-autoroll@skia.org Roll Fuchsia Test Scripts from R2EllDf4DgBXVNuiN... to dQ4PjIJB5kZFU8Y32... (flutter/flutter#185207)
2026-04-17 chris@bracken.jp [iOS] Update previousCompositionOrder to return Obj-C type (flutter/flutter#185136)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-packages
Please CC boetger@google.com,stuartmorgan@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

a: text input Entering text in a text field or keyboard related problems CICD Run CI/CD framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Text selection context menu does not reappear on non-fling scroll end

2 participants