Skip to content

Fix SelectableRegion crash when the selection starts in a scrollable child but does not select anything initially#184164

Draft
Renzo-Olivares wants to merge 4 commits intoflutter:masterfrom
Renzo-Olivares:selection-starts-in-scrollable-fix
Draft

Fix SelectableRegion crash when the selection starts in a scrollable child but does not select anything initially#184164
Renzo-Olivares wants to merge 4 commits intoflutter:masterfrom
Renzo-Olivares:selection-starts-in-scrollable-fix

Conversation

@Renzo-Olivares
Copy link
Contributor

@Renzo-Olivares Renzo-Olivares commented Mar 25, 2026

Fixes #115787

Before this change sometimes when starting a selection gesture such as a long press drag or a double tap drag directly on the empty padding of a Scrollable the selection may not be set initially because there was nothing to select in the empty padding. This caused a crash when receiving subsequent edge update events because we believe the selection starts in the scrollable but we do not have any selection edges set.

To fix this I made _selectionStartsInScrollable nullable, this way a subsequent selection edge will not try to set _selectionStartsInScrollable again if it has already been set removing the need for the assert. handleSelectionEdgeUpdate previously assumed that if the cached edges were not set then we should set _selectionStartsInScrollable, the assert was used to verify that _selectionStartsInScrollable was false i.e. had not been set/changed from its initial value. By making _selectionStartsInScrollable nullable we can ensure a subsequent edge update event does not re-set the value if it has already been set previously.

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.

…he scrollable but nothing is selected initially
@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: scrolling Viewports, list views, slivers, etc. labels Mar 25, 2026
@Renzo-Olivares Renzo-Olivares added the CICD Run CI/CD label Mar 25, 2026
@github-actions github-actions bot removed the CICD Run CI/CD label Mar 26, 2026
…use they are possible, previously we were checking _selectionStartsInScrollable and it could only be true or false and false represented both set and uninitialized states, but after becoming nullable null represents uninitialized and false represents set, we should handle this new state the same as if it were false and fail gracefully

@override
SelectionResult handleSelectAll(SelectAllSelectionEvent event) {
assert(!_selectionStartsInScrollable);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a little unclear what this assert was checking before.

It could be verifying that we only call handleSelectAll when we have not initialized the selection yet inside the scrollable. This is because _selectionStartsInScrollable could be a signal to whether the selection has ever reached this container. This also doesn't make sense to me since it seems reasonable for select all to reach a selectable who was not reached yet.

It could also be verifying that we only call handleSelectAll when the selection starts outside of the scrollable. I think we don't want to do this since it seems reasonable for a user to select some text in a scrollable (_selectionStartsInScrollable will be true), and then proceed with ctrl + a to send a select all event to the scrollable. The reason this crash has not been reported is that SelectableRegionState.selectAll prevents this by calling clearSelection before selecting everything. This is also the reason it does not crash with the new assert _selectionStartsInScrollable == null. Another option here could just to remove the assert.

@Renzo-Olivares Renzo-Olivares added the CICD Run CI/CD label Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD f: scrolling Viewports, list views, slivers, etc. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Selection] How To Avoid '!_selectionStartsInScrollable': is not true. assertion when using SelectionArea with scrollable widget.

1 participant