Skip to content

Conversation

@rkishan516
Copy link
Contributor

@rkishan516 rkishan516 commented Mar 2, 2025

Fix: Remove attach target on deactivation of widget from overlay portal controller
fixes: #164376

Pre-launch Checklist

  • I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
  • 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.

@flutter-dashboard
Copy link

It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!).

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

@github-actions github-actions bot added the framework flutter/packages/flutter repository. See also f: labels. label Mar 2, 2025
Copy link
Contributor

@Piinks Piinks left a comment

Choose a reason for hiding this comment

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

Hi @rkishan516 thank you for sending a PR!
It looks like this is failing many tests, and lacks tests itself. Can you take a look?
Thanks!

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch from ccc208a to a1b0390 Compare March 12, 2025 03:32
@rkishan516 rkishan516 requested a review from Piinks March 12, 2025 03:37
@rkishan516
Copy link
Contributor Author

@Piinks I have made required changes.

@Piinks Piinks requested a review from LongCatIsLooong March 17, 2025 14:56
@override
void dispose() {
assert(widget.controller._attachTarget == this);
void deactivate() {
Copy link
Contributor

Choose a reason for hiding this comment

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

If the OverlayPortal is reparented, the _attachTarget has to be restored right? Also could you add a test for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have pushed the required change.

Copy link
Contributor

Choose a reason for hiding this comment

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

It should probably happen in activate instead of didUpdateWidget.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yaa, that will be correct. Let me do the change.

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch 2 times, most recently from 4c7cdd2 to 1781190 Compare March 18, 2025 01:23
Copy link
Contributor

@LongCatIsLooong LongCatIsLooong left a comment

Choose a reason for hiding this comment

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

Detaching the controller from the state when it's deactivated makes sense to me.

However this would create a new corner case: when the state is deactivated, we don't want the developer to call show or hide on the associated controller because the state the controller attaches to may not rebuild. I think that can happen if you cache the OverlayPortal and gives it a global key.

assert(widget.controller._attachTarget == this);
void deactivate() {
super.deactivate();
assert(widget.controller._attachTarget == null || widget.controller._attachTarget == this);
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the assert here should be assert(widget.controller._attachTarget == this)?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, that should be the case but when reattaching with global key, it was causing failures.
But i think since we are moving reattach in activate method, this can be removed.

@rkishan516
Copy link
Contributor Author

Detaching the controller from the state when it's deactivated makes sense to me.

However this would create a new corner case: when the state is deactivated, we don't want the developer to call show or hide on the associated controller because the state the controller attaches to may not rebuild. I think that can happen if you cache the OverlayPortal and gives it a global key.

I will write a test for this and check.

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch 4 times, most recently from db30016 to 58584ed Compare March 20, 2025 02:21
@rkishan516
Copy link
Contributor Author

Detaching the controller from the state when it's deactivated makes sense to me.
However this would create a new corner case: when the state is deactivated, we don't want the developer to call show or hide on the associated controller because the state the controller attaches to may not rebuild. I think that can happen if you cache the OverlayPortal and gives it a global key.

I will write a test for this and check.

I have added the test, we don't need to call show method again after reactivation.

@LongCatIsLooong
Copy link
Contributor

It seems there's a leak in one of the new tests. Maybe one of the OverlayEntries were not disposed at the end of the test?

@LongCatIsLooong
Copy link
Contributor

I think setting _attatchTarget to null when the Element is deactivated could change the behavior in some corner cases, and what we want to fix is just the assert in _setupController. Can fix the asserts by:

  • In the _setupController assert, if the attached state is not Element.debugIsActive, then we could allow the re-attach,
  • assert in State.activate that _attachTarget == this

@rkishan516
Copy link
Contributor Author

I think setting _attatchTarget to null when the Element is deactivated could change the behavior in some corner cases, and what we want to fix is just the assert in _setupController. Can fix the asserts by:

  • In the _setupController assert, if the attached state is not Element.debugIsActive, then we could allow the re-attach,
  • assert in State.activate that _attachTarget == this

Element.debugIsActive
Returns true if the Element is active.
This getter always returns false in profile and release builds.

I think this will not solve the issue because in release it will always reattach to newer element.

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch 2 times, most recently from 23c1126 to df3f365 Compare March 21, 2025 01:58
@rkishan516
Copy link
Contributor Author

It seems there's a leak in one of the new tests. Maybe one of the OverlayEntries were not disposed at the end of the test?

Even after disposing overlay entries, its showing leak.

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch from df3f365 to e3304ec Compare March 21, 2025 02:38
@LongCatIsLooong
Copy link
Contributor

in release

The issue won't happen in release builds. The crash is caused by an assert.

@LongCatIsLooong
Copy link
Contributor

It seems there's a leak in one of the new tests. Maybe one of the OverlayEntries were not disposed at the end of the test?

Even after disposing overlay entries, its showing leak.

The relevant error messages were:

     Actual: <Instance of 'Leaks'>
     Which: contains leaks:
            # The text is generated by leak_tracker.
            # For leak troubleshooting tips open:
            # https://github.com/flutter/flutter/blob/main/docs/contributing/testing/Leak-tracking.md
            notDisposed:
              total: 4
              objects:
                ValueNotifier<_OverlayEntryWidgetState?>:
                  test: attachTarget is restored after reparenting
                  identityHashCode: 933371839
                OverlayEntry:
                  test: attachTarget is restored after reparenting
                  identityHashCode: 947575411
                ValueNotifier<_OverlayEntryWidgetState?>:
                  test: attachTarget is restored after reparenting
                  identityHashCode: 51179505
                OverlayEntry:
                  test: attachTarget is restored after reparenting
                  identityHashCode: 662836894

@rkishan516
Copy link
Contributor Author

in release

The issue won't happen in release builds. The crash is caused by an assert.

Okay, then I will do the change in _setupController.

late OverlayEntry overlayEntry1, overlayEntry2;
addTearDown(() {
overlayEntry1.dispose();
return overlayEntry2.dispose();
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: remove the return

);

// Move to second overlay
setState(() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect when the StatefulBuilder rebuilds, the builder callback will be called a second time, creating new OverlayEntries so in the test 4 OverlayEntries were created but only 2 were disposed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yaa, I need to give GlobalKey to Overlay widgets such that they also maintain themself until test is completed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even after adding global key, tests are failing

Copy link
Contributor

Choose a reason for hiding this comment

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

Global keys don't prevent rebuilds. Can you try creating the OverlayEntries at the start of the test, (and make them final), to make sure only two OverlayEntries are created in the test?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, and yaa even i was doing it wrongly with global keys. But yaa let me do the change.

@rkishan516 rkishan516 force-pushed the portal-controller-deactivate branch 2 times, most recently from d6c5f3d to cef835f Compare March 21, 2025 04:15
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 27, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 28, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 29, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 30, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 30, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Mar 31, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Apr 1, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 20, 2025
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request May 21, 2025
zhangyuang pushed a commit to zhangyuang/flutter-fork that referenced this pull request Jun 9, 2025
…al controller (flutter#164439)

Fix: Remove attach target on deactivation of widget from overlay portal
controller
fixes: flutter#164376 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
romanejaquez pushed a commit to romanejaquez/flutter that referenced this pull request Aug 14, 2025
…al controller (flutter#164439)

Fix: Remove attach target on deactivation of widget from overlay portal
controller
fixes: flutter#164376 

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OverlayPortal: Failed to attach OverlayPortalController to _OverlayPortalState on page resize

4 participants