fix: guard auto-scroll against Offset.infinite in _ScrollableSelectionContainerDelegate#183079
Conversation
When a SelectionArea contains a TwoDimensionalScrollable and the user drags past the scrollable boundary, _inferPositionRelatedToOrigin returns Offset.infinite. This infinite offset was being passed to startAutoScrollIfNecessary, causing NaN dimensions after matrix transforms and assertion failures. Added an event.globalPosition.isFinite guard before calling startAutoScrollIfNecessary, matching the existing pattern in selectable_region.dart. Fixes flutter#181169
|
It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group. |
There was a problem hiding this comment.
Code Review
This pull request addresses a crash that occurs during auto-scrolling in a SelectionArea when a selection is dragged past the boundary of a nested scrollable, such as a TableView. The issue is caused by an Offset.infinite value being passed to layout logic, leading to an assertion failure. The fix introduces a guard, event.globalPosition.isFinite, to prevent startAutoScrollIfNecessary from being called with an infinite offset. This change is consistent with similar checks elsewhere in the codebase and resolves the reported crash.
When a
SelectionAreacontains aTableView(or anyTwoDimensionalScrollable) and the user drags a selection past the bottom of the table,_inferPositionRelatedToOriginreturnsOffset.infiniteto signal "beyond the scrollable boundary". This infinite offset then gets passed into_autoScroller.startAutoScrollIfNecessaryvia_dragTargetFromEvent(event), which constructsRect.fromCenter(center: Offset.infinite, ...). That rect hasNaNdimensions after the matrix transform inEdgeDraggingAutoScroller._scroll, and the subsequentassertfires becauseNaN >= NaNis always false in IEEE 754.The fix adds an
event.globalPosition.isFiniteguard before callingstartAutoScrollIfNecessary, which matches the existing pattern used inselectable_region.dart(lines 2660 and 2684) for the same purpose. When the position isOffset.infinite, the selection-to-boundary semantics have already been handled by the inner delegates, so triggering auto-scroll is neither necessary nor geometrically valid.Fixes #181169
Pre-launch Checklist
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.
Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the
gemini-code-assistbot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.