Unverified Commit 255f967c authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Add isActivatedBy to ShortcutActivator (#100167)

parent 032205ea
......@@ -211,6 +211,16 @@ abstract class ShortcutActivator {
/// modifier key is pressed when the side variation is not important.
bool accepts(RawKeyEvent event, RawKeyboard state);
/// Returns true if the event and keyboard state would cause this
/// [ShortcutActivator] to be activated.
///
/// If the keyboard `state` isn't supplied, then it defaults to using
/// [RawKeyboard.instance].
static bool isActivatedBy(ShortcutActivator activator, RawKeyEvent event) {
return (activator.triggers?.contains(event.logicalKey) ?? true)
&& activator.accepts(event, RawKeyboard.instance);
}
/// Returns a description of the key set that is short and readable.
///
/// Intended to be used in debug mode for logging purposes.
......@@ -1016,11 +1026,9 @@ class CallbackShortcuts extends StatelessWidget {
// throws, by providing the activator and event as arguments that will appear
// in the stack trace.
bool _applyKeyBinding(ShortcutActivator activator, RawKeyEvent event) {
if (activator.triggers?.contains(event.logicalKey) ?? true) {
if (activator.accepts(event, RawKeyboard.instance)) {
bindings[activator]!.call();
return true;
}
if (ShortcutActivator.isActivatedBy(activator, event)) {
bindings[activator]!.call();
return true;
}
return false;
}
......
......@@ -103,8 +103,8 @@ Widget activatorTester(
if (hasSecond)
TestIntent2: TestAction(onInvoke: (Intent intent) {
onInvoke2(intent);
return null;
}),
return null;
}),
},
child: Shortcuts(
shortcuts: <ShortcutActivator, Intent>{
......@@ -321,6 +321,30 @@ void main() {
);
});
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget(
Focus(
autofocus: true,
onKey: (FocusNode node, RawKeyEvent event) {
events.add(event);
return KeyEventResult.ignored;
},
child: const SizedBox(),
),
);
final LogicalKeySet set = LogicalKeySet(LogicalKeyboardKey.keyA, LogicalKeyboardKey.control);
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
await tester.sendKeyDownEvent(LogicalKeyboardKey.keyA);
expect(ShortcutActivator.isActivatedBy(set, events[0]), isTrue);
await tester.sendKeyUpEvent(LogicalKeyboardKey.keyA);
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
expect(ShortcutActivator.isActivatedBy(set, events[0]), isFalse);
});
test('LogicalKeySet diagnostics work.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
......@@ -541,6 +565,30 @@ void main() {
expect(RawKeyboard.instance.keysPressed, isEmpty);
});
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget(
Focus(
autofocus: true,
onKey: (FocusNode node, RawKeyEvent event) {
events.add(event);
return KeyEventResult.ignored;
},
child: const SizedBox(),
),
);
const SingleActivator singleActivator = SingleActivator(LogicalKeyboardKey.keyA, control: true);
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
await tester.sendKeyDownEvent(LogicalKeyboardKey.keyA);
await tester.sendKeyUpEvent(LogicalKeyboardKey.keyA);
expect(ShortcutActivator.isActivatedBy(singleActivator, events[1]), isTrue);
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
expect(ShortcutActivator.isActivatedBy(singleActivator, events[1]), isFalse);
});
group('diagnostics.', () {
test('single key', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
......@@ -1167,6 +1215,28 @@ void main() {
expect(invoked, 2);
invoked = 0;
}, variant: KeySimulatorTransitModeVariant.all());
testWidgets('isActivatedBy works as expected', (WidgetTester tester) async {
// Collect some key events to use for testing.
final List<RawKeyEvent> events = <RawKeyEvent>[];
await tester.pumpWidget(
Focus(
autofocus: true,
onKey: (FocusNode node, RawKeyEvent event) {
events.add(event);
return KeyEventResult.ignored;
},
child: const SizedBox(),
),
);
const CharacterActivator characterActivator = CharacterActivator('a');
await tester.sendKeyDownEvent(LogicalKeyboardKey.keyA);
await tester.sendKeyUpEvent(LogicalKeyboardKey.keyA);
expect(ShortcutActivator.isActivatedBy(characterActivator, events[0]), isTrue);
});
});
group('CallbackShortcuts', () {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment