Unverified Commit 0eaa83ad authored by Bruno Leroux's avatar Bruno Leroux Committed by GitHub

Fix some Focus related documentation typos (#118576)

* Fix focus area documentation typos

* Restore intentional spaces that illustrate bigger buttons
parent f989d551
...@@ -954,7 +954,7 @@ class Actions extends StatefulWidget { ...@@ -954,7 +954,7 @@ class Actions extends StatefulWidget {
final Action<T>? result = _castAction(actions, intent: intent); final Action<T>? result = _castAction(actions, intent: intent);
if (result != null && result.isEnabled(intent)) { if (result != null && result.isEnabled(intent)) {
// Invoke the action we found using the relevant dispatcher from the Actions // Invoke the action we found using the relevant dispatcher from the Actions
// Element we found. // element we found.
returnValue = _findDispatcher(element).invokeAction(result, intent, context); returnValue = _findDispatcher(element).invokeAction(result, intent, context);
} }
return result != null; return result != null;
...@@ -1478,7 +1478,8 @@ class ActivateIntent extends Intent { ...@@ -1478,7 +1478,8 @@ class ActivateIntent extends Intent {
/// * [WidgetsApp.shortcuts], which defines the shortcuts to use in an /// * [WidgetsApp.shortcuts], which defines the shortcuts to use in an
/// application (and defaults to [WidgetsApp.defaultShortcuts]). /// application (and defaults to [WidgetsApp.defaultShortcuts]).
class ButtonActivateIntent extends Intent { class ButtonActivateIntent extends Intent {
/// Creates an intent that the currently focused control, if it's a button. /// Creates an intent that activates the currently focused control,
/// if it's a button.
const ButtonActivateIntent(); const ButtonActivateIntent();
} }
...@@ -1581,7 +1582,7 @@ mixin _OverridableActionMixin<T extends Intent> on Action<T> { ...@@ -1581,7 +1582,7 @@ mixin _OverridableActionMixin<T extends Intent> on Action<T> {
bool debugAssertConsumeKeyMutuallyRecursive = false; bool debugAssertConsumeKeyMutuallyRecursive = false;
// The default action to invoke if an enabled override Action can't be found // The default action to invoke if an enabled override Action can't be found
// using [lookupContext]; // using [lookupContext].
Action<T> get defaultAction; Action<T> get defaultAction;
// The [BuildContext] used to find the override of this [Action]. // The [BuildContext] used to find the override of this [Action].
......
...@@ -110,7 +110,7 @@ class _Autofocus { ...@@ -110,7 +110,7 @@ class _Autofocus {
// The widget tree is responsible for calling reparent/detach on attached // The widget tree is responsible for calling reparent/detach on attached
// nodes to keep their parent/manager information up-to-date, so here we can // nodes to keep their parent/manager information up-to-date, so here we can
// safely check if the scope/node involved in each autofocus request is // safely check if the scope/node involved in each autofocus request is
// still attached, and discard the ones are no longer attached to the // still attached, and discard the ones which are no longer attached to the
// original manager. // original manager.
void applyIfValid(FocusManager manager) { void applyIfValid(FocusManager manager) {
final bool shouldApply = (scope.parent != null || identical(scope, manager.rootScope)) final bool shouldApply = (scope.parent != null || identical(scope, manager.rootScope))
...@@ -128,8 +128,8 @@ class _Autofocus { ...@@ -128,8 +128,8 @@ class _Autofocus {
/// An attachment point for a [FocusNode]. /// An attachment point for a [FocusNode].
/// ///
/// Using a [FocusAttachment] is rarely needed, unless you are building /// Using a [FocusAttachment] is rarely needed, unless building something
/// something akin to the [Focus] or [FocusScope] widgets from scratch. /// akin to the [Focus] or [FocusScope] widgets from scratch.
/// ///
/// Once created, a [FocusNode] must be attached to the widget tree by its /// Once created, a [FocusNode] must be attached to the widget tree by its
/// _host_ [StatefulWidget] via a [FocusAttachment] object. [FocusAttachment]s /// _host_ [StatefulWidget] via a [FocusAttachment] object. [FocusAttachment]s
...@@ -261,8 +261,8 @@ enum UnfocusDisposition { ...@@ -261,8 +261,8 @@ enum UnfocusDisposition {
/// ///
/// _Please see the [Focus] and [FocusScope] widgets, which are utility widgets /// _Please see the [Focus] and [FocusScope] widgets, which are utility widgets
/// that manage their own [FocusNode]s and [FocusScopeNode]s, respectively. If /// that manage their own [FocusNode]s and [FocusScopeNode]s, respectively. If
/// they aren't appropriate, [FocusNode]s can be managed directly, but doing /// they aren't appropriate, [FocusNode]s can be managed directly, but doing this
/// this yourself is rare._ /// is rare._
/// ///
/// [FocusNode]s are persistent objects that form a _focus tree_ that is a /// [FocusNode]s are persistent objects that form a _focus tree_ that is a
/// representation of the widgets in the hierarchy that are interested in focus. /// representation of the widgets in the hierarchy that are interested in focus.
...@@ -1405,8 +1405,8 @@ enum FocusHighlightStrategy { ...@@ -1405,8 +1405,8 @@ enum FocusHighlightStrategy {
/// The focus manager is responsible for tracking which [FocusNode] has the /// The focus manager is responsible for tracking which [FocusNode] has the
/// primary input focus (the [primaryFocus]), holding the [FocusScopeNode] that /// primary input focus (the [primaryFocus]), holding the [FocusScopeNode] that
/// is the root of the focus tree (the [rootScope]), and what the current /// is the root of the focus tree (the [rootScope]), and what the current
/// [highlightMode] is. It also distributes key events from [RawKeyboard] to the /// [highlightMode] is. It also distributes key events from [KeyEventManager]
/// nodes in the focus tree. /// to the nodes in the focus tree.
/// ///
/// The singleton [FocusManager] instance is held by the [WidgetsBinding] as /// The singleton [FocusManager] instance is held by the [WidgetsBinding] as
/// [WidgetsBinding.focusManager], and can be conveniently accessed using the /// [WidgetsBinding.focusManager], and can be conveniently accessed using the
......
...@@ -195,7 +195,7 @@ class Focus extends StatefulWidget { ...@@ -195,7 +195,7 @@ class Focus extends StatefulWidget {
/// {@endtemplate} /// {@endtemplate}
/// ///
/// A non-null [focusNode] must be supplied if using the /// A non-null [focusNode] must be supplied if using the
/// [Focus.withExternalFocusNode] constructor is used. /// [Focus.withExternalFocusNode] constructor.
final FocusNode? focusNode; final FocusNode? focusNode;
/// {@template flutter.widgets.Focus.autofocus} /// {@template flutter.widgets.Focus.autofocus}
......
...@@ -200,7 +200,7 @@ abstract class FocusTraversalPolicy with Diagnosticable { ...@@ -200,7 +200,7 @@ abstract class FocusTraversalPolicy with Diagnosticable {
/// ///
/// See also: /// See also:
/// ///
/// * [previous], the function that is called to move the focus to the next node. /// * [previous], the function that is called to move the focus to the previous node.
/// * [DirectionalFocusTraversalPolicyMixin.findFirstFocusInDirection], a /// * [DirectionalFocusTraversalPolicyMixin.findFirstFocusInDirection], a
/// function that finds the first focusable widget in a particular direction. /// function that finds the first focusable widget in a particular direction.
FocusNode findLastFocus(FocusNode currentNode, {bool ignoreCurrentFocus = false}) { FocusNode findLastFocus(FocusNode currentNode, {bool ignoreCurrentFocus = false}) {
...@@ -1139,7 +1139,7 @@ class ReadingOrderTraversalPolicy extends FocusTraversalPolicy with DirectionalF ...@@ -1139,7 +1139,7 @@ class ReadingOrderTraversalPolicy extends FocusTraversalPolicy with DirectionalF
// It has to have at least topmost in it if the topmost is not degenerate. // It has to have at least topmost in it if the topmost is not degenerate.
assert(topmost.rect.isEmpty || inBandOfTop.isNotEmpty); assert(topmost.rect.isEmpty || inBandOfTop.isNotEmpty);
// The topmost rect in is in a band by itself, so just return that one. // The topmost rect is in a band by itself, so just return that one.
if (inBandOfTop.length <= 1) { if (inBandOfTop.length <= 1) {
return topmost; return topmost;
} }
......
...@@ -90,7 +90,6 @@ class KeySet<T extends KeyboardKey> { ...@@ -90,7 +90,6 @@ class KeySet<T extends KeyboardKey> {
&& setEquals<T>(other._keys, _keys); && setEquals<T>(other._keys, _keys);
} }
// Cached hash code value. Improves [hashCode] performance by 27%-900%, // Cached hash code value. Improves [hashCode] performance by 27%-900%,
// depending on key set size and read/write ratio. // depending on key set size and read/write ratio.
@override @override
...@@ -334,8 +333,8 @@ class LogicalKeySet extends KeySet<LogicalKeyboardKey> with Diagnosticable ...@@ -334,8 +333,8 @@ class LogicalKeySet extends KeySet<LogicalKeyboardKey> with Diagnosticable
} }
} }
/// A [DiagnosticsProperty] which handles formatting a `Map<LogicalKeySet, /// A [DiagnosticsProperty] which handles formatting a `Map<LogicalKeySet, Intent>`
/// Intent>` (the same type as the [Shortcuts.shortcuts] property) so that its /// (the same type as the [Shortcuts.shortcuts] property) so that its
/// diagnostic output is human-readable. /// diagnostic output is human-readable.
class ShortcutMapProperty extends DiagnosticsProperty<Map<ShortcutActivator, Intent>> { class ShortcutMapProperty extends DiagnosticsProperty<Map<ShortcutActivator, Intent>> {
/// Create a diagnostics property for `Map<ShortcutActivator, Intent>` objects, /// Create a diagnostics property for `Map<ShortcutActivator, Intent>` objects,
...@@ -1183,7 +1182,7 @@ class ShortcutRegistryEntry { ...@@ -1183,7 +1182,7 @@ class ShortcutRegistryEntry {
/// ///
/// The registry may be listened to (with [addListener]/[removeListener]) for /// The registry may be listened to (with [addListener]/[removeListener]) for
/// change notifications when the registered shortcuts change. Change /// change notifications when the registered shortcuts change. Change
/// notifications take place after the the current frame is drawn, so that /// notifications take place after the current frame is drawn, so that
/// widgets that are not descendants of the registry can listen to it (e.g. in /// widgets that are not descendants of the registry can listen to it (e.g. in
/// overlays). /// overlays).
class ShortcutRegistry with ChangeNotifier { class ShortcutRegistry with ChangeNotifier {
......
...@@ -74,6 +74,7 @@ void main() { ...@@ -74,6 +74,7 @@ void main() {
expect(result, isTrue); expect(result, isTrue);
expect(invoked, isTrue); expect(invoked, isTrue);
}); });
testWidgets('Actions widget can invoke actions with default dispatcher and maybeInvoke', (WidgetTester tester) async { testWidgets('Actions widget can invoke actions with default dispatcher and maybeInvoke', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
bool invoked = false; bool invoked = false;
...@@ -1083,6 +1084,7 @@ void main() { ...@@ -1083,6 +1084,7 @@ void main() {
action._testInvoke(intent); action._testInvoke(intent);
expect(passedIntent, equals(intent)); expect(passedIntent, equals(intent));
}); });
testWidgets('VoidCallbackAction', (WidgetTester tester) async { testWidgets('VoidCallbackAction', (WidgetTester tester) async {
bool called = false; bool called = false;
void testCallback() { void testCallback() {
...@@ -1121,6 +1123,7 @@ void main() { ...@@ -1121,6 +1123,7 @@ void main() {
expect(description, isEmpty); expect(description, isEmpty);
}); });
testWidgets('default Actions debugFillProperties', (WidgetTester tester) async { testWidgets('default Actions debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
...@@ -1146,6 +1149,7 @@ void main() { ...@@ -1146,6 +1149,7 @@ void main() {
]), ]),
); );
}); });
testWidgets('Actions implements debugFillProperties', (WidgetTester tester) async { testWidgets('Actions implements debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
......
...@@ -420,7 +420,7 @@ void main() { ...@@ -420,7 +420,7 @@ void main() {
expect(find.text('b'), findsOneWidget); expect(find.text('b'), findsOneWidget);
}); });
testWidgets('Adding a new FocusScope attaches the child it to its parent.', (WidgetTester tester) async { testWidgets('Adding a new FocusScope attaches the child to its parent.', (WidgetTester tester) async {
final GlobalKey<TestFocusState> keyA = GlobalKey(); final GlobalKey<TestFocusState> keyA = GlobalKey();
final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope Node'); final FocusScopeNode parentFocusScope = FocusScopeNode(debugLabel: 'Parent Scope Node');
final FocusScopeNode childFocusScope = FocusScopeNode(debugLabel: 'Child Scope Node'); final FocusScopeNode childFocusScope = FocusScopeNode(debugLabel: 'Child Scope Node');
...@@ -1673,6 +1673,7 @@ void main() { ...@@ -1673,6 +1673,7 @@ void main() {
await pumpTest(traverseScope1: true); await pumpTest(traverseScope1: true);
expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, focus1, scope2])); expect(scope1.traversalDescendants, equals(<FocusNode>[focus2, focus1, scope2]));
}); });
testWidgets('descendantsAreFocusable works as expected.', (WidgetTester tester) async { testWidgets('descendantsAreFocusable works as expected.', (WidgetTester tester) async {
final GlobalKey key1 = GlobalKey(debugLabel: '1'); final GlobalKey key1 = GlobalKey(debugLabel: '1');
final GlobalKey key2 = GlobalKey(debugLabel: '2'); final GlobalKey key2 = GlobalKey(debugLabel: '2');
...@@ -1756,13 +1757,11 @@ void main() { ...@@ -1756,13 +1757,11 @@ void main() {
final GlobalKey key1 = GlobalKey(debugLabel: '1'); final GlobalKey key1 = GlobalKey(debugLabel: '1');
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
bool? keyEventHandled; bool? keyEventHandled;
// ignore: prefer_function_declarations_over_variables KeyEventResult handleCallback(FocusNode node, RawKeyEvent event) {
final FocusOnKeyCallback handleCallback = (FocusNode node, RawKeyEvent event) {
keyEventHandled = true; keyEventHandled = true;
return KeyEventResult.handled; return KeyEventResult.handled;
}; }
// ignore: prefer_function_declarations_over_variables KeyEventResult ignoreCallback(FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
final FocusOnKeyCallback ignoreCallback = (FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
Focus focusWidget = Focus( Focus focusWidget = Focus(
onKey: ignoreCallback, // This one does nothing. onKey: ignoreCallback, // This one does nothing.
focusNode: focusNode, focusNode: focusNode,
...@@ -1807,13 +1806,11 @@ void main() { ...@@ -1807,13 +1806,11 @@ void main() {
final GlobalKey key1 = GlobalKey(debugLabel: '1'); final GlobalKey key1 = GlobalKey(debugLabel: '1');
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
bool? keyEventHandled; bool? keyEventHandled;
// ignore: prefer_function_declarations_over_variables KeyEventResult handleEventCallback(FocusNode node, KeyEvent event) {
final FocusOnKeyEventCallback handleEventCallback = (FocusNode node, KeyEvent event) {
keyEventHandled = true; keyEventHandled = true;
return KeyEventResult.handled; return KeyEventResult.handled;
}; }
// ignore: prefer_function_declarations_over_variables KeyEventResult ignoreEventCallback(FocusNode node, KeyEvent event) => KeyEventResult.ignored;
final FocusOnKeyEventCallback ignoreEventCallback = (FocusNode node, KeyEvent event) => KeyEventResult.ignored;
Focus focusWidget = Focus( Focus focusWidget = Focus(
onKeyEvent: ignoreEventCallback, // This one does nothing. onKeyEvent: ignoreEventCallback, // This one does nothing.
focusNode: focusNode, focusNode: focusNode,
...@@ -1858,20 +1855,16 @@ void main() { ...@@ -1858,20 +1855,16 @@ void main() {
final GlobalKey key1 = GlobalKey(debugLabel: '1'); final GlobalKey key1 = GlobalKey(debugLabel: '1');
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
bool? keyEventHandled; bool? keyEventHandled;
// ignore: prefer_function_declarations_over_variables KeyEventResult handleCallback(FocusNode node, RawKeyEvent event) {
final FocusOnKeyCallback handleCallback = (FocusNode node, RawKeyEvent event) {
keyEventHandled = true; keyEventHandled = true;
return KeyEventResult.handled; return KeyEventResult.handled;
}; }
// ignore: prefer_function_declarations_over_variables KeyEventResult handleEventCallback(FocusNode node, KeyEvent event) {
final FocusOnKeyEventCallback handleEventCallback = (FocusNode node, KeyEvent event) {
keyEventHandled = true; keyEventHandled = true;
return KeyEventResult.handled; return KeyEventResult.handled;
}; }
// ignore: prefer_function_declarations_over_variables KeyEventResult ignoreCallback(FocusNode node, RawKeyEvent event) => KeyEventResult.ignored;
final FocusOnKeyCallback ignoreCallback = (FocusNode node, RawKeyEvent event) => KeyEventResult.ignored; KeyEventResult ignoreEventCallback(FocusNode node, KeyEvent event) => KeyEventResult.ignored;
// ignore: prefer_function_declarations_over_variables
final FocusOnKeyEventCallback ignoreEventCallback = (FocusNode node, KeyEvent event) => KeyEventResult.ignored;
focusNode.onKey = ignoreCallback; focusNode.onKey = ignoreCallback;
focusNode.onKeyEvent = ignoreEventCallback; focusNode.onKeyEvent = ignoreEventCallback;
focusNode.descendantsAreFocusable = false; focusNode.descendantsAreFocusable = false;
...@@ -1974,6 +1967,7 @@ void main() { ...@@ -1974,6 +1967,7 @@ void main() {
expect(containerNode.hasFocus, isFalse); expect(containerNode.hasFocus, isFalse);
expect(unfocusableNode.hasFocus, isFalse); expect(unfocusableNode.hasFocus, isFalse);
}); });
// Regression test for https://github.com/flutter/flutter/issues/61700 // Regression test for https://github.com/flutter/flutter/issues/61700
testWidgets("ExcludeFocus doesn't transfer focus to another descendant.", (WidgetTester tester) async { testWidgets("ExcludeFocus doesn't transfer focus to another descendant.", (WidgetTester tester) async {
final FocusNode parentFocusNode = FocusNode(debugLabel: 'group'); final FocusNode parentFocusNode = FocusNode(debugLabel: 'group');
......
...@@ -2153,6 +2153,7 @@ void main() { ...@@ -2153,6 +2153,7 @@ void main() {
expect(events.length, 2); expect(events.length, 2);
}, variant: KeySimulatorTransitModeVariant.all()); }, variant: KeySimulatorTransitModeVariant.all());
}); });
group(FocusTraversalGroup, () { group(FocusTraversalGroup, () {
testWidgets("Focus traversal group doesn't introduce a Semantics node", (WidgetTester tester) async { testWidgets("Focus traversal group doesn't introduce a Semantics node", (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
......
...@@ -72,6 +72,7 @@ void main() { ...@@ -72,6 +72,7 @@ void main() {
}), }),
); );
}); });
test('LogicalKeySet works as a map key.', () { test('LogicalKeySet works as a map key.', () {
final LogicalKeySet set1 = LogicalKeySet(LogicalKeyboardKey.keyA); final LogicalKeySet set1 = LogicalKeySet(LogicalKeyboardKey.keyA);
final LogicalKeySet set2 = LogicalKeySet( final LogicalKeySet set2 = LogicalKeySet(
...@@ -109,6 +110,7 @@ void main() { ...@@ -109,6 +110,7 @@ void main() {
})), })),
); );
}); });
testWidgets('handles two keys', (WidgetTester tester) async { testWidgets('handles two keys', (WidgetTester tester) async {
int invoked = 0; int invoked = 0;
await tester.pumpWidget(activatorTester( await tester.pumpWidget(activatorTester(
...@@ -537,6 +539,7 @@ void main() { ...@@ -537,6 +539,7 @@ void main() {
expect(shortcuts.shortcuts, isNotNull); expect(shortcuts.shortcuts, isNotNull);
expect(shortcuts.shortcuts, isEmpty); expect(shortcuts.shortcuts, isEmpty);
}); });
testWidgets('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async { testWidgets('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async {
final ShortcutManager manager = ShortcutManager(); final ShortcutManager manager = ShortcutManager();
expect(manager.shortcuts, isNotNull); expect(manager.shortcuts, isNotNull);
...@@ -546,6 +549,7 @@ void main() { ...@@ -546,6 +549,7 @@ void main() {
expect(shortcuts.shortcuts, isNotNull); expect(shortcuts.shortcuts, isNotNull);
expect(shortcuts.shortcuts, isEmpty); expect(shortcuts.shortcuts, isEmpty);
}); });
testWidgets('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async { testWidgets('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async {
final Map<LogicalKeySet, Intent> testShortcuts = <LogicalKeySet, Intent>{ final Map<LogicalKeySet, Intent> testShortcuts = <LogicalKeySet, Intent>{
LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(),
...@@ -558,6 +562,7 @@ void main() { ...@@ -558,6 +562,7 @@ void main() {
expect(shortcuts.shortcuts, isNotNull); expect(shortcuts.shortcuts, isNotNull);
expect(shortcuts.shortcuts, equals(testShortcuts)); expect(shortcuts.shortcuts, equals(testShortcuts));
}); });
testWidgets('ShortcutManager handles shortcuts', (WidgetTester tester) async { testWidgets('ShortcutManager handles shortcuts', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -592,6 +597,7 @@ void main() { ...@@ -592,6 +597,7 @@ void main() {
expect(invoked, isTrue); expect(invoked, isTrue);
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async { testWidgets('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -633,6 +639,7 @@ void main() { ...@@ -633,6 +639,7 @@ void main() {
expect(shortcutsSet, isFalse); expect(shortcutsSet, isFalse);
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async { testWidgets('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -665,6 +672,7 @@ void main() { ...@@ -665,6 +672,7 @@ void main() {
expect(invoked, isFalse); expect(invoked, isFalse);
expect(pressedKeys, isEmpty); expect(pressedKeys, isEmpty);
}); });
testWidgets("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async { testWidgets("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -704,6 +712,7 @@ void main() { ...@@ -704,6 +712,7 @@ void main() {
expect(invoked, isTrue); expect(invoked, isTrue);
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.shiftLeft]));
}); });
testWidgets('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async { testWidgets('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async {
final GlobalKey containerKey = GlobalKey(); final GlobalKey containerKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -745,6 +754,7 @@ void main() { ...@@ -745,6 +754,7 @@ void main() {
expect(invoked, isFalse); expect(invoked, isFalse);
expect(pressedKeys, isEmpty); expect(pressedKeys, isEmpty);
}); });
testWidgets("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async { testWidgets("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -769,6 +779,7 @@ void main() { ...@@ -769,6 +779,7 @@ void main() {
expect(handled, isFalse); expect(handled, isFalse);
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA]));
}); });
testWidgets('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async { testWidgets('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -805,6 +816,7 @@ void main() { ...@@ -805,6 +816,7 @@ void main() {
expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA])); expect(pressedKeys, equals(<LogicalKeyboardKey>[LogicalKeyboardKey.keyA]));
expect(invoked, isTrue); expect(invoked, isTrue);
}); });
testWidgets('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async { testWidgets('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -845,6 +857,7 @@ void main() { ...@@ -845,6 +857,7 @@ void main() {
expect(result, isFalse); expect(result, isFalse);
expect(invoked, isFalse); expect(invoked, isFalse);
}); });
testWidgets('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async { testWidgets('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async {
final GlobalKey textFieldKey = GlobalKey(); final GlobalKey textFieldKey = GlobalKey();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -885,6 +898,7 @@ void main() { ...@@ -885,6 +898,7 @@ void main() {
expect(result, isFalse); expect(result, isFalse);
expect(invoked, isFalse); expect(invoked, isFalse);
}); });
test('Shortcuts diagnostics work.', () { test('Shortcuts diagnostics work.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
...@@ -914,6 +928,7 @@ void main() { ...@@ -914,6 +928,7 @@ void main() {
), ),
); );
}); });
test('Shortcuts diagnostics work when debugLabel specified.', () { test('Shortcuts diagnostics work when debugLabel specified.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
...@@ -935,6 +950,7 @@ void main() { ...@@ -935,6 +950,7 @@ void main() {
expect(description.length, equals(1)); expect(description.length, equals(1));
expect(description[0], equals('shortcuts: <Debug Label>')); expect(description[0], equals('shortcuts: <Debug Label>'));
}); });
test('Shortcuts diagnostics work when manager not specified.', () { test('Shortcuts diagnostics work when manager not specified.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
...@@ -955,6 +971,7 @@ void main() { ...@@ -955,6 +971,7 @@ void main() {
expect(description.length, equals(1)); expect(description.length, equals(1));
expect(description[0], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}')); expect(description[0], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}'));
}); });
test('Shortcuts diagnostics work when manager specified.', () { test('Shortcuts diagnostics work when manager specified.', () {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[]; final List<LogicalKeyboardKey> pressedKeys = <LogicalKeyboardKey>[];
...@@ -981,6 +998,7 @@ void main() { ...@@ -981,6 +998,7 @@ void main() {
expect(description[0], equalsIgnoringHashCodes('manager: TestShortcutManager#00000(shortcuts: {LogicalKeySet#00000(keys: Key A + Key B): ActivateIntent#00000})')); expect(description[0], equalsIgnoringHashCodes('manager: TestShortcutManager#00000(shortcuts: {LogicalKeySet#00000(keys: Key A + Key B): ActivateIntent#00000})'));
expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}')); expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}'));
}); });
testWidgets('Shortcuts support multiple intents', (WidgetTester tester) async { testWidgets('Shortcuts support multiple intents', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true; bool? value = true;
...@@ -1956,7 +1974,7 @@ Widget activatorTester( ...@@ -1956,7 +1974,7 @@ Widget activatorTester(
ValueSetter<Intent> onInvoke, [ ValueSetter<Intent> onInvoke, [
ShortcutActivator? activator2, ShortcutActivator? activator2,
ValueSetter<Intent>? onInvoke2, ValueSetter<Intent>? onInvoke2,
]) { ]) {
final bool hasSecond = activator2 != null && onInvoke2 != null; final bool hasSecond = activator2 != null && onInvoke2 != null;
return Actions( return Actions(
key: GlobalKey(), key: GlobalKey(),
......
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