Skip to content

Conversation

@davidhicks980
Copy link
Contributor

@davidhicks980 davidhicks980 commented Jun 3, 2024

_MenuAnchorState now removes itself from its parent regardless of whether _MenuAnchorState._isOpen is true.

Before, _MenuAnchorState would only detach itself when _MenuAnchorState._isOpen == true. This led to _MenuAnchorState being retained until an anchor's parent was disposed.

Before:

Screen.Recording.2024-06-03.at.6.28.24.AM.mov

After:

Screen.Recording.2024-06-03.at.6.45.56.AM.mov

Fixes #149584

I was a bit unsure what the best way of testing this change would be, and wanted feedback from the Flutter team. Is there a way for us to view at the instance count of _MenuAnchorState, or expose _MenuAnchorState._anchorChildren.length for testing?

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Removed self from parent regardless of whether menu is open.
@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 to this rule, contact "@test-exemption-reviewer" in the #hackers channel in Chat (don't just cc them here, they won't see it! Use Discord!).

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.

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. f: material design flutter/packages/flutter/material repository. labels Jun 3, 2024
@Piinks
Copy link
Contributor

Piinks commented Jun 5, 2024

@davidhicks980 thanks for sending the PR! Would you mind adding a test?

@Piinks
Copy link
Contributor

Piinks commented Jun 6, 2024

@polina-c I am surprised the leak tracker did not already catch this. Do you know how we might be able to capture it in a test?

@polina-c
Copy link
Contributor

polina-c commented Jun 6, 2024

@polina-c I am surprised the leak tracker did not already catch this. Do you know how we might be able to capture it in a test?

LeakTracker is scoped to catch not disposed leaks at the moment. It does not catch not GCed ones.
It is separate big effort to clean up Flutter Framework from notGCed leaks. And it is not part of leak tracker MVP.
This PR fixes notGCed leak.

Does it help?

@Piinks
Copy link
Contributor

Piinks commented Jun 6, 2024

Ah ok, thank you for calrifying.

@Piinks
Copy link
Contributor

Piinks commented Jun 6, 2024

I was looking at the original issue,

Expected results

There should only be one _MenuAnchorState for each menu anchor

Actual results

Detached _MenuAnchorStates are being retained

Maybe to test @davidhicks980 we could just access currentState without needing to expose _MenuAnchorState and just check it is not the same state after opening/closing/opening the menu?

@davidhicks980
Copy link
Contributor Author

davidhicks980 commented Jun 7, 2024

@Piinks So I may be wrong about this, but I think the currentState would still correctly report that it has changed since the state attached to the visible MenuAnchor is changing, but the parent _MenuAnchorState would still be holding on to previous instances of the state as well.

To verify, I wrote this test with the unfixed menu and it did pass, but my test could also be flawed:

testWidgets('Nested anchor state should dispose after a menu is closed', (WidgetTester tester) async {
      State? oldState;
      GlobalKey stateKey = GlobalKey();
      await tester.pumpWidget(MaterialApp(
        home: Material(
          child: Center(
            child: MenuAnchor(
               controller: controller,
                builder: (context, controller, child) {
                  return TextButton(
                      onPressed: () {
                        if (controller.isOpen) {
                          controller.close();
                        } else {
                          controller.open();
                        }
                      },
                      child: const Text('Toggle Menu'));
                },
                menuChildren: [
                  SubmenuButton(
                    key: stateKey,
                    menuChildren: [
                      MenuItemButton(
                        onPressed: () {},
                        child: const Text('Item 1'),
                      ),
                      MenuItemButton(
                        onPressed: () {},
                        child: const Text('Item 2'),
                      ),
                    ],
                    child: const Text('Item 2'),
                  ),
                  SubmenuButton(
                    menuChildren: [
                      MenuItemButton(
                        onPressed: () {},
                        child: const Text('Item 1'),
                      ),
                      MenuItemButton(
                        onPressed: () {},
                        child: const Text('Item 2'),
                      ),
                    ],
                    child: const Text('Item 2'),
                  ),
                ]),
          ),
        ),
      ));
      controller.open();
      await tester.pump();
      oldState = stateKey.currentState;
      controller.close();
      await tester.pump();
      controller.open();
      await tester.pump();
      expect(stateKey.currentState, isNot(oldState));
    });

Added a test that pairs forces garbage collection on a weakly-referenced _MenuAnchorState to check whether it has been dereferenced when its parent is closed.
@davidhicks980
Copy link
Contributor Author

davidhicks980 commented Jun 16, 2024

Okay, assuming checks pass, and forceGC works on CI, this should be good-to-go. I added a test that forces garbage collection on a weakly-referenced _MenuAnchorState, and it appears to correctly identify if a child state is retained by its parent.

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.

Thanks for adding a test - this LGTM with just a few nits

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

Thank you for fixing this! Good catch. LGTM 👍

FYI @gspencergoog because MenuAnchor.

});

testWidgets('Garbage collector destroys child _MenuAnchorState after parent is closed', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/pull/149586
Copy link
Contributor

Choose a reason for hiding this comment

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

Should you link to the issue? #149584

@Piinks Piinks added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 20, 2024
@auto-submit auto-submit bot merged commit c2c1833 into flutter:master Jun 20, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 21, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 21, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 22, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 22, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 23, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 23, 2024
hello-coder-xu added a commit to hello-coder-xu/flutter that referenced this pull request Jun 24, 2024
* master: (213 commits)
  Fix: Memory leak in UndoHistory widget because it never de-registered itself as global UndoManager client (Resolves flutter#148291) (flutter#150661)
  [CupertinoActionSheet] Fix the layout (part 1) (flutter#149636)
  Remove discontinued `device_info` and `connectivity` plugins from `flutter_gallery`, roll pub packages (flutter#150585)
  [a11y] Update semantics in bottom_navigation_bar.dart (flutter#150576)
  Roll Flutter Engine from dda82d905f37 to 33415c6ee7c2 (7 revisions) (flutter#150637)
  Reland 4: [CupertinoActionSheet] Match colors to native (flutter#150442)
  Enable SelectionArea double tap/triple tap gesture support for mobile platforms (flutter#149295)
  made SelectionArea alignment consistent between web and other platform (flutter#150037)
  Fix link hook typo (flutter#150194)
  Stop looking for .packages when analyzing (flutter#150349)
  Update flutter.dev links from misc packages to more permanent destinations (flutter#150532)
  Roll Flutter Engine from dd37cefd4a94 to dda82d905f37 (9 revisions) (flutter#150582)
  Update Material token to the latest 4.1.0 (flutter#150382)
  Let the lockfile script generate lockfiles for kotlin gradle files as well (flutter#150471)
  Make popup menu hardcoded padding configurable (flutter#150506)
  [flutter_tools] un-hide the --dds flag (flutter#150280)
  [material/menu_anchor.dart] Remove _MenuAnchorState from parent when disposed. (flutter#149586)
  Add test for inherited_notifier.0.dart (flutter#150344)
  [CLI tool] in `flutter test`, consider `--flavor` when validating the cached asset bundle (flutter#150461)
  Test InputDecoration API examples (flutter#148560)
  ...
hello-coder-xu added a commit to hello-coder-xu/flutter that referenced this pull request Jun 24, 2024
…ileTheme

* master: (88 commits)
  Fix: Memory leak in UndoHistory widget because it never de-registered itself as global UndoManager client (Resolves flutter#148291) (flutter#150661)
  [CupertinoActionSheet] Fix the layout (part 1) (flutter#149636)
  Remove discontinued `device_info` and `connectivity` plugins from `flutter_gallery`, roll pub packages (flutter#150585)
  [a11y] Update semantics in bottom_navigation_bar.dart (flutter#150576)
  Roll Flutter Engine from dda82d905f37 to 33415c6ee7c2 (7 revisions) (flutter#150637)
  Reland 4: [CupertinoActionSheet] Match colors to native (flutter#150442)
  Enable SelectionArea double tap/triple tap gesture support for mobile platforms (flutter#149295)
  made SelectionArea alignment consistent between web and other platform (flutter#150037)
  Fix link hook typo (flutter#150194)
  Stop looking for .packages when analyzing (flutter#150349)
  Update flutter.dev links from misc packages to more permanent destinations (flutter#150532)
  Roll Flutter Engine from dd37cefd4a94 to dda82d905f37 (9 revisions) (flutter#150582)
  Update Material token to the latest 4.1.0 (flutter#150382)
  Let the lockfile script generate lockfiles for kotlin gradle files as well (flutter#150471)
  Make popup menu hardcoded padding configurable (flutter#150506)
  [flutter_tools] un-hide the --dds flag (flutter#150280)
  [material/menu_anchor.dart] Remove _MenuAnchorState from parent when disposed. (flutter#149586)
  Add test for inherited_notifier.0.dart (flutter#150344)
  [CLI tool] in `flutter test`, consider `--flavor` when validating the cached asset bundle (flutter#150461)
  Test InputDecoration API examples (flutter#148560)
  ...
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 24, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 24, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 25, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 25, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jun 25, 2024
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jun 25, 2024
Roll Flutter from 6c06abb to e726eb4 (51 revisions)

flutter/flutter@6c06abb...e726eb4

2024-06-25 [email protected] Roll Packages from 711b4ac to 03f5f6d (21 revisions) (flutter/flutter#150779)
2024-06-25 [email protected] Roll Flutter Engine from afa7ce19bca8 to fbd92055f3a6 (1 revision) (flutter/flutter#150777)
2024-06-25 [email protected] Reland Add tests for form_text_field.1.dart (#150481) (#150696) (flutter/flutter#150750)
2024-06-25 [email protected] Add an example for CupertinoPopupSurface (flutter/flutter#150357)
2024-06-25 [email protected] [flutter_tools/dap] Handle app.stop errors when launching/attaching (flutter/flutter#149734)
2024-06-25 [email protected] Roll Flutter Engine from be7db94196fe to afa7ce19bca8 (18 revisions) (flutter/flutter#150762)
2024-06-25 [email protected] Remove dubious comment (flutter/flutter#150608)
2024-06-25 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Manual engine roll to 6884e83 (#150733)" (flutter/flutter#150746)
2024-06-25 [email protected] Manual engine roll to 6884e83 (flutter/flutter#150733)
2024-06-24 [email protected] Linkify 'see also' sections (flutter/flutter#150734)
2024-06-24 [email protected] Roll pub packages (flutter/flutter#150712)
2024-06-24 [email protected] Update flutter.dev links from framework to more permanent destinations (flutter/flutter#150531)
2024-06-24 [email protected] Manual engine roll to be7db94196fe (flutter/flutter#150714)
2024-06-24 [email protected] allow adb to set canfail then use canFail=true for clearing logs (flutter/flutter#150517)
2024-06-24 [email protected] Update android_device.dart to have clearLogs not print to standard error (flutter/flutter#150197)
2024-06-24 [email protected] Update issue link in analysis_options.yaml (flutter/flutter#150395)
2024-06-24 [email protected] Fix a number of broken doc comment references (flutter/flutter#150540)
2024-06-24 [email protected] Fix flaky sliver tree test (flutter/flutter#150707)
2024-06-24 98614782+auto-submit[bot]@users.noreply.github.com Reverts "Add tests for form_text_field.1.dart (#150481)" (flutter/flutter#150696)
2024-06-24 [email protected] Add tests for form_text_field.1.dart (flutter/flutter#150481)
2024-06-22 [email protected] Fix: Memory leak in UndoHistory widget because it never de-registered itself as global UndoManager client (Resolves #148291) (flutter/flutter#150661)
2024-06-22 [email protected] [CupertinoActionSheet] Fix the layout (part 1) (flutter/flutter#149636)
2024-06-21 [email protected] Remove discontinued `device_info` and `connectivity` plugins from `flutter_gallery`, roll pub packages (flutter/flutter#150585)
2024-06-21 [email protected] [a11y] Update semantics in bottom_navigation_bar.dart (flutter/flutter#150576)
2024-06-21 [email protected] Roll Flutter Engine from dda82d905f37 to 33415c6ee7c2 (7 revisions) (flutter/flutter#150637)
2024-06-21 [email protected] Reland 4: [CupertinoActionSheet] Match colors to native (flutter/flutter#150442)
2024-06-21 [email protected] Enable SelectionArea double tap/triple tap gesture support for mobile platforms (flutter/flutter#149295)
2024-06-21 [email protected] made SelectionArea alignment consistent between web and other platform (flutter/flutter#150037)
2024-06-21 [email protected] Fix link hook typo (flutter/flutter#150194)
2024-06-21 [email protected] Stop looking for .packages when analyzing (flutter/flutter#150349)
2024-06-20 [email protected] Update flutter.dev links from misc packages to more permanent destinations (flutter/flutter#150532)
2024-06-20 [email protected] Roll Flutter Engine from dd37cefd4a94 to dda82d905f37 (9 revisions) (flutter/flutter#150582)
2024-06-20 [email protected] Update Material token to the latest 4.1.0 (flutter/flutter#150382)
2024-06-20 [email protected] Let the lockfile script generate lockfiles for kotlin gradle files as well (flutter/flutter#150471)
2024-06-20 [email protected] Make popup menu hardcoded padding configurable (flutter/flutter#150506)
2024-06-20 [email protected] [flutter_tools] un-hide the --dds flag (flutter/flutter#150280)
2024-06-20 [email protected] [material/menu_anchor.dart] Remove _MenuAnchorState from parent when disposed. (flutter/flutter#149586)
2024-06-20 [email protected] Add test for inherited_notifier.0.dart (flutter/flutter#150344)
2024-06-20 [email protected] [CLI tool] in `flutter test`, consider `--flavor` when validating the cached asset bundle (flutter/flutter#150461)
2024-06-20 [email protected] Test InputDecoration API examples (flutter/flutter#148560)
2024-06-20 [email protected] Clean leaky tests. (flutter/flutter#150335)
2024-06-20 [email protected] Roll Flutter Engine from f9c497f178d3 to dd37cefd4a94 (2 revisions) (flutter/flutter#150537)
2024-06-20 [email protected] Roll Flutter Engine from a31279381b40 to f9c497f178d3 (9 revisions) (flutter/flutter#150528)
2024-06-19 [email protected] Add tests for about_list_tile.0.dart (flutter/flutter#150181)
2024-06-19 [email protected] Roll Flutter Engine from 0ad18fe4c0b5 to a31279381b40 (7 revisions) (flutter/flutter#150473)
2024-06-18 [email protected] Revert "[a11y] Add semantics: button to bottom navigation bar items and dropdown menu items" (flutter/flutter#150445)
...
sigurdm pushed a commit to sigurdm/flutter that referenced this pull request Jun 26, 2024
…disposed. (flutter#149586)

`_MenuAnchorState` now removes itself from its parent regardless of whether `_MenuAnchorState._isOpen` is true.

Before, _MenuAnchorState would only detach itself when `_MenuAnchorState._isOpen == true`. This led to _MenuAnchorState being retained until an anchor's parent was disposed.

Before:

https://github.com/flutter/flutter/assets/59215665/48f1617a-a3d0-49ab-a767-f41e3a30ea41

After:

https://github.com/flutter/flutter/assets/59215665/31312bb6-49ec-4083-b8de-e9ae2a42a8b3

Fixes flutter#149584

I was a bit unsure what the best way of testing this change would be, and wanted feedback from the Flutter team. Is there a way for us to view at the instance count of `_MenuAnchorState`, or expose `_MenuAnchorState._anchorChildren.length` for testing?

- [] I added new tests to check the change I am making, or this PR is [test-exempt].
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Aug 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autosubmit Merge PR when tree becomes green via auto submit App f: material design flutter/packages/flutter/material repository. framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[material/menu_anchor.dart] _MenuAnchorState is not always GC'd

4 participants