Fix PlatformMenuItems with onSelectedIntent are never enabled (#121885)
Fix PlatformMenuItems with onSelectedIntent are never enabled
This commit is contained in:
@@ -738,7 +738,8 @@ class PlatformMenuItem with Diagnosticable {
|
||||
/// An optional callback that is called when this [PlatformMenuItem] is
|
||||
/// selected.
|
||||
///
|
||||
/// If unset, this menu item will be disabled.
|
||||
/// At most one of [onSelected] and [onSelectedIntent] may be set. If neither
|
||||
/// field is set, this menu item will be disabled.
|
||||
final VoidCallback? onSelected;
|
||||
|
||||
/// Returns a callback, if any, to be invoked if the platform menu receives a
|
||||
@@ -760,7 +761,8 @@ class PlatformMenuItem with Diagnosticable {
|
||||
/// An optional intent that is invoked when this [PlatformMenuItem] is
|
||||
/// selected.
|
||||
///
|
||||
/// If unset, this menu item will be disabled.
|
||||
/// At most one of [onSelected] and [onSelectedIntent] may be set. If neither
|
||||
/// field is set, this menu item will be disabled.
|
||||
final Intent? onSelectedIntent;
|
||||
|
||||
/// Returns all descendant [PlatformMenuItem]s of this item.
|
||||
@@ -805,7 +807,7 @@ class PlatformMenuItem with Diagnosticable {
|
||||
return <String, Object?>{
|
||||
_kIdKey: getId(item),
|
||||
_kLabelKey: item.label,
|
||||
_kEnabledKey: item.onSelected != null,
|
||||
_kEnabledKey: item.onSelected != null || item.onSelectedIntent != null,
|
||||
if (shortcut != null)...shortcut.serializeForMenu().toChannelRepresentation(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,12 +15,12 @@ void main() {
|
||||
late FakeMenuChannel fakeMenuChannel;
|
||||
late PlatformMenuDelegate originalDelegate;
|
||||
late DefaultPlatformMenuDelegate delegate;
|
||||
final List<String> activated = <String>[];
|
||||
final List<String> selected = <String>[];
|
||||
final List<String> opened = <String>[];
|
||||
final List<String> closed = <String>[];
|
||||
|
||||
void onActivate(String item) {
|
||||
activated.add(item);
|
||||
void onSelected(String item) {
|
||||
selected.add(item);
|
||||
}
|
||||
|
||||
void onOpen(String item) {
|
||||
@@ -36,7 +36,7 @@ void main() {
|
||||
delegate = DefaultPlatformMenuDelegate(channel: fakeMenuChannel);
|
||||
originalDelegate = WidgetsBinding.instance.platformMenuDelegate;
|
||||
WidgetsBinding.instance.platformMenuDelegate = delegate;
|
||||
activated.clear();
|
||||
selected.clear();
|
||||
opened.clear();
|
||||
closed.clear();
|
||||
});
|
||||
@@ -46,117 +46,69 @@ void main() {
|
||||
});
|
||||
|
||||
group('PlatformMenuBar', () {
|
||||
testWidgets('basic menu structure is transmitted to platform', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: PlatformMenuBar(
|
||||
menus: createTestMenus(
|
||||
onActivate: onActivate,
|
||||
onOpen: onOpen,
|
||||
onClose: onClose,
|
||||
shortcuts: <String, MenuSerializableShortcut>{
|
||||
subSubMenu10[0]: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
|
||||
subSubMenu10[1]: const SingleActivator(LogicalKeyboardKey.keyB, shift: true),
|
||||
subSubMenu10[2]: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
|
||||
subSubMenu10[3]: const SingleActivator(LogicalKeyboardKey.keyD, meta: true),
|
||||
},
|
||||
group('basic menu structure is transmitted to platform', () {
|
||||
testWidgets('using onSelected', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: PlatformMenuBar(
|
||||
menus: createTestMenus(
|
||||
onSelected: onSelected,
|
||||
onOpen: onOpen,
|
||||
onClose: onClose,
|
||||
shortcuts: <String, MenuSerializableShortcut>{
|
||||
subSubMenu10[0]: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
|
||||
subSubMenu10[1]: const SingleActivator(LogicalKeyboardKey.keyB, shift: true),
|
||||
subSubMenu10[2]: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
|
||||
subSubMenu10[3]: const SingleActivator(LogicalKeyboardKey.keyD, meta: true),
|
||||
},
|
||||
),
|
||||
child: const Center(child: Text('Body')),
|
||||
),
|
||||
child: const Center(child: Text('Body')),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
);
|
||||
|
||||
expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenus'));
|
||||
expect(
|
||||
fakeMenuChannel.outgoingCalls.last.arguments,
|
||||
equals(<String, Object?>{
|
||||
'0': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 2,
|
||||
'label': 'Menu 0',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 1,
|
||||
'label': 'Sub Menu 00',
|
||||
'enabled': true,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 18,
|
||||
'label': 'Menu 1',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 4,
|
||||
'label': 'Sub Menu 10',
|
||||
'enabled': true,
|
||||
},
|
||||
<String, Object?>{'id': 5, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 16,
|
||||
'label': 'Sub Menu 11',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 7,
|
||||
'label': 'Sub Sub Menu 110',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 97,
|
||||
'shortcutModifiers': 8,
|
||||
},
|
||||
<String, Object?>{'id': 8, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 10,
|
||||
'label': 'Sub Sub Menu 111',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 98,
|
||||
'shortcutModifiers': 2,
|
||||
},
|
||||
<String, Object?>{'id': 11, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 12,
|
||||
'label': 'Sub Sub Menu 112',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 99,
|
||||
'shortcutModifiers': 4,
|
||||
},
|
||||
<String, Object?>{'id': 13, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 14,
|
||||
'label': 'Sub Sub Menu 113',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 100,
|
||||
'shortcutModifiers': 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 17,
|
||||
'label': 'Sub Menu 12',
|
||||
'enabled': true,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 20,
|
||||
'label': 'Menu 2',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 19,
|
||||
'label': 'Sub Menu 20',
|
||||
'enabled': false,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{'id': 21, 'label': 'Menu 3', 'enabled': false, 'children': <Map<String, Object?>>[]},
|
||||
],
|
||||
}),
|
||||
);
|
||||
expect(
|
||||
fakeMenuChannel.outgoingCalls.last.method,
|
||||
equals('Menu.setMenus'),
|
||||
);
|
||||
expect(
|
||||
fakeMenuChannel.outgoingCalls.last.arguments,
|
||||
equals(expectedStructure),
|
||||
);
|
||||
});
|
||||
testWidgets('using onSelectedIntent', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Material(
|
||||
child: PlatformMenuBar(
|
||||
menus: createTestMenus(
|
||||
onSelectedIntent: const DoNothingIntent(),
|
||||
onOpen: onOpen,
|
||||
onClose: onClose,
|
||||
shortcuts: <String, MenuSerializableShortcut>{
|
||||
subSubMenu10[0]: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
|
||||
subSubMenu10[1]: const SingleActivator(LogicalKeyboardKey.keyB, shift: true),
|
||||
subSubMenu10[2]: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
|
||||
subSubMenu10[3]: const SingleActivator(LogicalKeyboardKey.keyD, meta: true),
|
||||
},
|
||||
),
|
||||
child: const Center(child: Text('Body')),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
expect(
|
||||
fakeMenuChannel.outgoingCalls.last.method,
|
||||
equals('Menu.setMenus'),
|
||||
);
|
||||
expect(
|
||||
fakeMenuChannel.outgoingCalls.last.arguments,
|
||||
equals(expectedStructure),
|
||||
);
|
||||
});
|
||||
});
|
||||
testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
@@ -287,7 +239,8 @@ const List<String> subMenu2 = <String>[
|
||||
];
|
||||
|
||||
List<PlatformMenuItem> createTestMenus({
|
||||
void Function(String)? onActivate,
|
||||
void Function(String)? onSelected,
|
||||
Intent? onSelectedIntent,
|
||||
void Function(String)? onOpen,
|
||||
void Function(String)? onClose,
|
||||
Map<String, MenuSerializableShortcut> shortcuts = const <String, MenuSerializableShortcut>{},
|
||||
@@ -301,7 +254,8 @@ List<PlatformMenuItem> createTestMenus({
|
||||
menus: <PlatformMenuItem>[
|
||||
PlatformMenuItem(
|
||||
label: subMenu0[0],
|
||||
onSelected: onActivate != null ? () => onActivate(subMenu0[0]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subMenu0[0]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subMenu0[0]],
|
||||
),
|
||||
],
|
||||
@@ -315,7 +269,8 @@ List<PlatformMenuItem> createTestMenus({
|
||||
members: <PlatformMenuItem>[
|
||||
PlatformMenuItem(
|
||||
label: subMenu1[0],
|
||||
onSelected: onActivate != null ? () => onActivate(subMenu1[0]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subMenu0[0]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subMenu1[0]],
|
||||
),
|
||||
],
|
||||
@@ -329,7 +284,8 @@ List<PlatformMenuItem> createTestMenus({
|
||||
members: <PlatformMenuItem>[
|
||||
PlatformMenuItem(
|
||||
label: subSubMenu10[0],
|
||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[0]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subSubMenu10[0]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subSubMenu10[0]],
|
||||
),
|
||||
],
|
||||
@@ -338,21 +294,24 @@ List<PlatformMenuItem> createTestMenus({
|
||||
members: <PlatformMenuItem>[
|
||||
PlatformMenuItem(
|
||||
label: subSubMenu10[1],
|
||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subSubMenu10[1]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subSubMenu10[1]],
|
||||
),
|
||||
],
|
||||
),
|
||||
PlatformMenuItem(
|
||||
label: subSubMenu10[2],
|
||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[2]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subSubMenu10[2]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subSubMenu10[2]],
|
||||
),
|
||||
PlatformMenuItemGroup(
|
||||
members: <PlatformMenuItem>[
|
||||
PlatformMenuItem(
|
||||
label: subSubMenu10[3],
|
||||
onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subSubMenu10[3]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subSubMenu10[3]],
|
||||
),
|
||||
],
|
||||
@@ -361,7 +320,8 @@ List<PlatformMenuItem> createTestMenus({
|
||||
),
|
||||
PlatformMenuItem(
|
||||
label: subMenu1[2],
|
||||
onSelected: onActivate != null ? () => onActivate(subMenu1[2]) : null,
|
||||
onSelected: onSelected != null ? () => onSelected(subMenu1[2]) : null,
|
||||
onSelectedIntent: onSelectedIntent,
|
||||
shortcut: shortcuts[subMenu1[2]],
|
||||
),
|
||||
],
|
||||
@@ -389,6 +349,92 @@ List<PlatformMenuItem> createTestMenus({
|
||||
return result;
|
||||
}
|
||||
|
||||
const Map<String, Object?> expectedStructure = <String, Object?>{
|
||||
'0': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 2,
|
||||
'label': 'Menu 0',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 1,
|
||||
'label': 'Sub Menu 00',
|
||||
'enabled': true,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 18,
|
||||
'label': 'Menu 1',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 4,
|
||||
'label': 'Sub Menu 10',
|
||||
'enabled': true,
|
||||
},
|
||||
<String, Object?>{'id': 5, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 16,
|
||||
'label': 'Sub Menu 11',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 7,
|
||||
'label': 'Sub Sub Menu 110',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 97,
|
||||
'shortcutModifiers': 8,
|
||||
},
|
||||
<String, Object?>{'id': 8, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 10,
|
||||
'label': 'Sub Sub Menu 111',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 98,
|
||||
'shortcutModifiers': 2,
|
||||
},
|
||||
<String, Object?>{'id': 11, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 12,
|
||||
'label': 'Sub Sub Menu 112',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 99,
|
||||
'shortcutModifiers': 4,
|
||||
},
|
||||
<String, Object?>{'id': 13, 'isDivider': true},
|
||||
<String, Object?>{
|
||||
'id': 14,
|
||||
'label': 'Sub Sub Menu 113',
|
||||
'enabled': true,
|
||||
'shortcutTrigger': 100,
|
||||
'shortcutModifiers': 1,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 17,
|
||||
'label': 'Sub Menu 12',
|
||||
'enabled': true,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{
|
||||
'id': 20,
|
||||
'label': 'Menu 2',
|
||||
'enabled': true,
|
||||
'children': <Map<String, Object?>>[
|
||||
<String, Object?>{
|
||||
'id': 19,
|
||||
'label': 'Sub Menu 20',
|
||||
'enabled': false,
|
||||
},
|
||||
],
|
||||
},
|
||||
<String, Object?>{'id': 21, 'label': 'Menu 3', 'enabled': false, 'children': <Map<String, Object?>>[]},
|
||||
],
|
||||
};
|
||||
|
||||
class FakeMenuChannel implements MethodChannel {
|
||||
FakeMenuChannel(this.outgoing);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user