Skip to content

Fix PlatformMenuItems with onSelectedIntent are never enabled#121885

Merged
auto-submit[bot] merged 6 commits intoflutter:masterfrom
jmatth:fix-platform-menu-item-intent
Mar 7, 2023
Merged

Fix PlatformMenuItems with onSelectedIntent are never enabled#121885
auto-submit[bot] merged 6 commits intoflutter:masterfrom
jmatth:fix-platform-menu-item-intent

Conversation

@jmatth
Copy link
Contributor

@jmatth jmatth commented Mar 3, 2023

Fixes #121805.

The fix is pretty simple: the PlatformMenuItem serialization logic only considered whether onSelected was non-null when determining whether an item should be enabled. With this change it now checks whether onSelected or onSelectedIntent are non-null.

I'm less confident about my updates to the tests for this change. The existing tests have code in place to record menu item activations, but then that data isn't actually read anywhere. Based on that observation I didn't implement recording intents sent by activated menu items, since doing so would seemingly go against the style guide's advice to Avoid implementing features you don’t need.

Based on git blame, CC @gspencergoog

@flutter-dashboard flutter-dashboard bot added the framework flutter/packages/flutter repository. See also f: labels. label Mar 3, 2023
@loic-sharma
Copy link
Member

/cc @gspencergoog

Copy link
Contributor

@gspencergoog gspencergoog 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 fixing this!


List<PlatformMenuItem> createTestMenus({
void Function(String)? onActivate,
Intent Function(String)? onActivateIntent,
Copy link
Contributor

Choose a reason for hiding this comment

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

This can just pass a nullable Intent.

child: PlatformMenuBar(
menus: createTestMenus(
onActivate: onActivate,
onActivateIntent: (String item) => TestPlatformMenuBarIntent(item),
Copy link
Contributor

Choose a reason for hiding this comment

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

If you change the argument type in createTestMenus, this can just be:

Suggested change
onActivateIntent: (String item) => TestPlatformMenuBarIntent(item),
onActivateIntent: TestPlatformMenuBarIntent(subMenu1[0]),

PlatformMenuItem(
label: subMenu1[0],
onSelected: onActivate != null ? () => onActivate(subMenu1[0]) : null,
onSelectedIntent: onActivateIntent?.call(subMenu1[0]),
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little surprised this doesn't cause the existing test to fail, but maybe it ends up producing the same thing? I'm surprised, because this change prevents the test from ever testing the onActivate case, since it's never used.

Anyhow, I think there need to be two tests: one that tests onSelected, and one that tests onSelectedIntent. In this test menu creation function, you can just put back the line you deleted, and send in the nullable intent that came into the function.

While you're at it, can you rename the "onActivate*" arguments to this function to "onSelected*", since it should have been called that anyhow (it got missed in a name change).

Copy link
Contributor Author

@jmatth jmatth Mar 3, 2023

Choose a reason for hiding this comment

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

I'm a little surprised this doesn't cause the existing test to fail, but maybe it ends up producing the same thing?

My understanding is yes, it just produces the same result. Looking at the test, it only has two calls to expect:

  1. Expect that Menu.setMenus was called
  2. Expect that the serialized version of the menu structure matches a hardcoded expected value

The serialized version of the menu items doesn't contain any information about whether a callback or intent was provided, only whether the item is enabled or disabled, so specifying either one satisfies the test.

I'm surprised, because this change prevents the test from ever testing the onActivate case, since it's never used.

As far as I can tell, there are currently no tests that actually test activating menu items. There is code earlier in the test suite that records which items have their callback invoked, but none of the tests ever actually select a menu item or expect that any items were selected. All that onActivate recording is just dead code right now.

Anyhow, I think there need to be two tests: one that tests onSelected, and one that tests onSelectedIntent. In this test menu creation function, you can just put back the line you deleted, and send in the nullable intent that came into the function.
While you're at it, can you rename the "onActivate*" arguments to this function to "onSelected*", since it should have been called that anyhow (it got missed in a name change).

SGTM and SGTM

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for pointing that out. I'll have to add some more tests, I can tell.

child: PlatformMenuBar(
menus: createTestMenus(
onActivate: onActivate,
onActivateIntent: (String item) => TestPlatformMenuBarIntent(item),
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be split into two tests, one that tests onActivate, and one that tests onActivateIntent, since they can't both be specified at the same time.

@jmatth jmatth requested a review from gspencergoog March 4, 2023 02:12
Copy link
Contributor

@gspencergoog gspencergoog left a comment

Choose a reason for hiding this comment

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

32384589-a60f0e74-c078-11e7-9bc1-e5b5287aea9d

@gspencergoog
Copy link
Contributor

Looks like there is an analyzer failure.

@jmatth
Copy link
Contributor Author

jmatth commented Mar 6, 2023

Fixed, it should pass analysis now. Sorry about that.

@jmatth jmatth requested a review from gspencergoog March 6, 2023 18:27
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.

LGTM 👍

}));
'shortcutCharacter': '?',
'shortcutModifiers': 0,
}));
Copy link
Contributor

Choose a reason for hiding this comment

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

It's hard to tell on GitHub, but are these indentations intentional? I thought they looked correct beforehand.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I think VSCode's auto format went rogue. I'll see if I can configure it to match the previous formatting.

Copy link
Member

@loic-sharma loic-sharma left a comment

Choose a reason for hiding this comment

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

LGTM

@loic-sharma
Copy link
Member

Consider updating the docs for PlatformMenuItem.onSelected and PlatformMenuItem.onSelectedIntent to say something like:

If both [onSelected] and [onSelectedIntent] are unset, this menu item will be disabled.

I'd be fine with doing this in a subsequent pull request.

@jmatth
Copy link
Contributor Author

jmatth commented Mar 6, 2023

I'd be fine adding the docs change to this PR if you'd prefer. I was thinking it would be nice to add something to the effect of Only one of this and [onSelected]/[onSelectedIntent] may be non-null to the docstrings anyway. Currently nothing tells you that those two fields are mutually exclusive until you try setting both and trip an assertion.

@jmatth
Copy link
Contributor Author

jmatth commented Mar 6, 2023

@loic-sharma: thoughts on the following for the new docstring? I figure it might be easier to agree on wording in Github comments to cut down on unnecessary CI runs.

At most one of [onSelected] and [onSelectedIntent] may be set. If neither field is set, this menu item will be disabled.

@loic-sharma
Copy link
Member

loic-sharma commented Mar 7, 2023

@jmatth That looks perfect!

@gspencergoog
Copy link
Contributor

@jmatth Let me know when you're done, and I'll submit it. (seems like you're done, but I didn't want to submit it if you weren't).

@jmatth
Copy link
Contributor Author

jmatth commented Mar 7, 2023

@gspencergoog yeah, I'm done. I think I've addressed everyone's comments.

@gspencergoog gspencergoog added the autosubmit Merge PR when tree becomes green via auto submit App label Mar 7, 2023
@auto-submit auto-submit bot merged commit 8557ffa into flutter:master Mar 7, 2023
@jmatth jmatth deleted the fix-platform-menu-item-intent branch March 7, 2023 04:31
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 framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PlatformMenuItems with onSelectedIntent are never enabled

5 participants