Skip to content

[two_dimensional_scrollables] Fix mouse event loop when calling setState in TableSpan.onEnter - #11606

Merged
auto-submit[bot] merged 3 commits into
flutter:mainfrom
Piinks:fix-issue-147614
Apr 29, 2026
Merged

[two_dimensional_scrollables] Fix mouse event loop when calling setState in TableSpan.onEnter#11606
auto-submit[bot] merged 3 commits into
flutter:mainfrom
Piinks:fix-issue-147614

Conversation

@Piinks

Copy link
Copy Markdown
Contributor

This PR addresses a bug in TableView where calling setState (or any action that triggers a delegate rebuild) inside a TableSpan.onEnter callback would cause an infinite loop of onExit and onEnter events.

The RenderTableViewport was clearing its cached _columnMetrics and _rowMetrics (_Span objects) on every delegate rebuild. Since _Span implements MouseTrackerAnnotation, and the MouseTracker identifies regions by object identity, re-creating these objects every frame caused the MouseTracker to:

  1. Trigger onExit for the old _Span object.
  2. Trigger onEnter for the new _Span object.

If onEnter contained a setState call, this cycle would repeat indefinitely.

Fixesflutter/flutter#147614

Fix:

  • Refactored _updateRowMetrics and _updateColumnMetrics to reuse existing _Span objects when
    available.
  • Updated _Span.update to only refresh the internal configuration and layout metrics while
    maintaining the same object instance.
  • Modified layoutChildSequence to avoid clearing the metrics maps, instead allowing the update
    methods to handle stale entries.
  • Added logic to properly dispose and remove spans when the row or column count is reduced.

Pre-Review 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-assist bot 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.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

@flutter-dashboardflutter-dashboardBot added the CICD Run CI/CD label Apr 29, 2026
@github-actionsgithub-actionsBot added p: two_dimensional_scrollables Issues pertaining to the two_dimensional_scrollables package triage-framework Should be looked at in framework triage labels Apr 29, 2026

@gemini-code-assistgemini-code-assistBot 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 addresses a bug where calling setState within onEnter in a TableSpan caused an infinite loop of onExit/onEnter events. The implementation optimizes RenderTableViewport by selectively disposing and removing column and row metrics when the count is reduced, rather than clearing all metrics during a layout rebuild. A regression test has been added to ensure the fix works as expected. The review feedback suggests refactoring the duplicated logic for disposing and removing trailing spans into private helper methods to improve code maintainability.

Comment threadpackages/two_dimensional_scrollables/lib/src/table_view/table.dart Outdated
Comment threadpackages/two_dimensional_scrollables/lib/src/table_view/table.dart Outdated
@github-actionsgithub-actionsBot removed the CICD Run CI/CD label Apr 29, 2026

@AbdeMohlbiAbdeMohlbi 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.

SGTM, with some nits

@@ -1,3 +1,7 @@
## 0.4.3

* Fixes a loop of onExit/onEnter events when setState is called within onEnter in a TableSpan.

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.

Fixes an infinite loop

});

testWidgets(
'Calling setState within onEnter does not cause a loop of onExit/onEnter - Regression test for https://github.com/flutter/flutter/issues/147614',

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.

I don't think that we usually name the test as regression test for issue #1234 but rather add a comment at the start of it.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Good catch thank you! I will update

@flutter-dashboardflutter-dashboardBot added the CICD Run CI/CD label Apr 29, 2026
@PiinksPiinks added the autosubmit Merge PR when tree becomes green via auto submit App label Apr 29, 2026
@auto-submit
auto-submitBot merged commit c3360ac into flutter:mainApr 29, 2026
83 checks passed
pullBot pushed a commit to Klomgor/flutter that referenced this pull request May 1, 2026
…r#185897)
flutter/packages@cde5b36...daf30f8
2026-04-30 mdebbar@google.com [url_launcher_web] Re-enable flaky test
(not flaky anymore) (flutter/packages#11478)
2026-04-30 stuartmorgan@google.com [in_app_purchase] Switch to Kotlin
Pigeon (flutter/packages#11608)
2026-04-29 katelovett@google.com [two_dimensional_scrollables] Fix mouse
event loop when calling setState in TableSpan.onEnter
(flutter/packages#11606)
2026-04-29 katelovett@google.com [two_dimensional_scrollables] trailing
pinned row/col for TableView (flutter/packages#11519)
2026-04-29 10687576+bparrishMines@users.noreply.github.com
[webview_flutter_wkwebview] Tear down ProxyAPIRegistrar in
`applicationWillTerminate` (flutter/packages#11567)
2026-04-29 stuartmorgan@google.com [google_maps_flutter] Replace use of
zIndex in examples and tests (flutter/packages#11572)
2026-04-29 stuartmorgan@google.com [tool] Remove --against-pub flag
(flutter/packages#11550)
2026-04-29 47866232+chunhtai@users.noreply.github.com [ci] Update branch
management for batch release (flutter/packages#11575)
2026-04-29 spkhalad@gmail.com [webview_flutter] Platform implementations
for getCookies flutter#11037 (flutter/packages#11386)
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-flutter-autoroll
Please CC flutter-ecosystem@google.com on the revert to ensure that a
human
is aware of the problem.
To file a bug in Flutter:
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
…ate in TableSpan.onEnter (flutter#11606)
This PR addresses a bug in TableView where calling setState (or any action that triggers a delegate rebuild) inside a TableSpan.onEnter callback would cause an infinite loop of onExit and onEnter events.
The RenderTableViewport was clearing its cached _columnMetrics and _rowMetrics (_Span objects) on every delegate rebuild. Since _Span implements MouseTrackerAnnotation, and the MouseTracker identifies regions by object identity, re-creating these objects every frame caused the MouseTracker to:
1. Trigger onExit for the old _Span object.
2. Trigger onEnter for the new _Span object.
If onEnter contained a setState call, this cycle would repeat indefinitely.
Fixesflutter/flutter#147614
Fix:
- Refactored _updateRowMetrics and _updateColumnMetrics to reuse existing _Span objects when
available.
- Updated _Span.update to only refresh the internal configuration and layout metrics while
maintaining the same object instance.
- Modified layoutChildSequence to avoid clearing the metrics maps, instead allowing the update
methods to handle stale entries.
- Added logic to properly dispose and remove spans when the row or column count is reduced.
## Pre-Review Checklist
**Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot 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.
[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmitMerge PR when tree becomes green via auto submit AppCICDRun CI/CDp: two_dimensional_scrollablesIssues pertaining to the two_dimensional_scrollables packagetriage-frameworkShould be looked at in framework triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calling setState within onEnter causes onExit then onEnter to be called again even though pointer is stationary

2 participants

@Piinks@AbdeMohlbi