Unverified Commit 8f7e41a9 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Some MacOS control key shortcuts (#103936)

parent 20381801
......@@ -310,6 +310,12 @@ class DefaultTextEditingShortcuts extends StatelessWidget {
const SingleActivator(LogicalKeyboardKey.keyA, meta: true): const SelectAllTextIntent(SelectionChangedCause.keyboard),
const SingleActivator(LogicalKeyboardKey.keyZ, meta: true): const UndoTextIntent(SelectionChangedCause.keyboard),
const SingleActivator(LogicalKeyboardKey.keyZ, shift: true, meta: true): const RedoTextIntent(SelectionChangedCause.keyboard),
const SingleActivator(LogicalKeyboardKey.keyE, control: true): const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.keyA, control: true): const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.keyF, control: true): const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.keyB, control: true): const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.keyN, control: true): const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
const SingleActivator(LogicalKeyboardKey.keyP, control: true): const ExtendSelectionVerticallyToAdjacentLineIntent(forward: false, collapseSelection: true),
// These keys should go to the IME when a field is focused, not to other
// Shortcuts.
const SingleActivator(LogicalKeyboardKey.space): const DoNothingAndStopPropagationTextIntent(),
......
......@@ -11982,6 +11982,221 @@ void main() {
expect(tester.takeException(), null);
// On web, the text selection toolbar cut button is handled by the browser.
}, skip: kIsWeb); // [intended]
group('Mac document shortcuts', () {
testWidgets('ctrl-A/E', (WidgetTester tester) async {
final String targetPlatformString = defaultTargetPlatform.toString();
final String platform = targetPlatformString.substring(targetPlatformString.indexOf('.') + 1).toLowerCase();
final TextEditingController controller = TextEditingController(text: testText);
controller.selection = const TextSelection(
baseOffset: 0,
extentOffset: 0,
affinity: TextAffinity.upstream,
);
await tester.pumpWidget(MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 400,
child: EditableText(
maxLines: 10,
controller: controller,
showSelectionHandles: true,
autofocus: true,
focusNode: FocusNode(),
style: Typography.material2018().black.subtitle1!,
cursorColor: Colors.blue,
backgroundCursorColor: Colors.grey,
selectionControls: materialTextSelectionControls,
keyboardType: TextInputType.text,
textAlign: TextAlign.right,
),
),
),
));
await tester.pump(); // Wait for autofocus to take effect.
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 0);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyE, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(
controller.selection,
equals(
const TextSelection.collapsed(
offset: 19,
affinity: TextAffinity.upstream,
),
),
reason: 'on $platform',
);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyA, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(
controller.selection,
equals(
const TextSelection.collapsed(
offset: 0,
),
),
reason: 'on $platform',
);
},
skip: kIsWeb, // [intended] on web these keys are handled by the browser.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets('ctrl-F/B', (WidgetTester tester) async {
final String targetPlatformString = defaultTargetPlatform.toString();
final String platform = targetPlatformString.substring(targetPlatformString.indexOf('.') + 1).toLowerCase();
final TextEditingController controller = TextEditingController(text: testText);
controller.selection = const TextSelection(
baseOffset: 0,
extentOffset: 0,
affinity: TextAffinity.upstream,
);
await tester.pumpWidget(MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 400,
child: EditableText(
maxLines: 10,
controller: controller,
showSelectionHandles: true,
autofocus: true,
focusNode: FocusNode(),
style: Typography.material2018().black.subtitle1!,
cursorColor: Colors.blue,
backgroundCursorColor: Colors.grey,
selectionControls: materialTextSelectionControls,
keyboardType: TextInputType.text,
textAlign: TextAlign.right,
),
),
),
));
await tester.pump(); // Wait for autofocus to take effect.
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 0);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyF, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 1);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyB, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 0);
},
skip: kIsWeb, // [intended] on web these keys are handled by the browser.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
testWidgets('ctrl-N/P', (WidgetTester tester) async {
final String targetPlatformString = defaultTargetPlatform.toString();
final String platform = targetPlatformString.substring(targetPlatformString.indexOf('.') + 1).toLowerCase();
final TextEditingController controller = TextEditingController(text: testText);
controller.selection = const TextSelection(
baseOffset: 0,
extentOffset: 0,
affinity: TextAffinity.upstream,
);
await tester.pumpWidget(MaterialApp(
home: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 400,
child: EditableText(
maxLines: 10,
controller: controller,
showSelectionHandles: true,
autofocus: true,
focusNode: FocusNode(),
style: Typography.material2018().black.subtitle1!,
cursorColor: Colors.blue,
backgroundCursorColor: Colors.grey,
selectionControls: materialTextSelectionControls,
keyboardType: TextInputType.text,
textAlign: TextAlign.right,
),
),
),
));
await tester.pump(); // Wait for autofocus to take effect.
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 0);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyN, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 20);
await tester.sendKeyDownEvent(
LogicalKeyboardKey.controlLeft,
platform: platform,
);
await tester.pump();
await tester.sendKeyEvent(LogicalKeyboardKey.keyP, platform: platform);
await tester.pump();
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft, platform: platform);
await tester.pump();
expect(controller.selection.isCollapsed, isTrue);
expect(controller.selection.baseOffset, 0);
},
skip: kIsWeb, // [intended] on web these keys are handled by the browser.
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
);
});
}
class UnsettableController extends TextEditingController {
......
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