diff --git a/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart b/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart index e57f04418d1..a6700375430 100644 --- a/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart +++ b/packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart @@ -412,16 +412,10 @@ class DefaultTextEditingShortcuts extends StatelessWidget { SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowRight, alt: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowUp, alt: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, alt: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowDown, meta: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowRight, meta: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.arrowUp, meta: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, meta: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, meta: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true): DoNothingAndStopPropagationTextIntent(), - SingleActivator(LogicalKeyboardKey.arrowRight, shift: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.pageUp, shift: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.pageDown, shift: true): DoNothingAndStopPropagationTextIntent(), SingleActivator(LogicalKeyboardKey.end, shift: true): DoNothingAndStopPropagationTextIntent(), @@ -452,6 +446,12 @@ class DefaultTextEditingShortcuts extends StatelessWidget { const SingleActivator(LogicalKeyboardKey.tab, shift: true): const DoNothingAndStopPropagationTextIntent(), const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, alt: true): const DoNothingAndStopPropagationTextIntent(), const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, alt: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, alt: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, meta: true): const DoNothingAndStopPropagationTextIntent(), + const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, meta: true): const DoNothingAndStopPropagationTextIntent(), }; // Hand backspace/delete events that do not depend on text layout (delete diff --git a/packages/flutter/test/widgets/editable_text_shortcuts_test.dart b/packages/flutter/test/widgets/editable_text_shortcuts_test.dart index 0e76e8d9b30..2ecb88010d1 100644 --- a/packages/flutter/test/widgets/editable_text_shortcuts_test.dart +++ b/packages/flutter/test/widgets/editable_text_shortcuts_test.dart @@ -57,6 +57,7 @@ void main() { bool readOnly = false, bool obscured = false, TextStyle style = const TextStyle(fontSize: 10.0), + bool enableInteractiveSelection = true }) { return MaterialApp( home: Align( @@ -82,6 +83,7 @@ void main() { readOnly: readOnly, textAlign: textAlign, obscureText: obscured, + enableInteractiveSelection: enableInteractiveSelection, ), ), ), @@ -2051,22 +2053,6 @@ void main() { } }, variant: TargetPlatformVariant.all()); - testWidgets('horizontal movement', (WidgetTester tester) async { - controller.text = testText; - controller.selection = const TextSelection.collapsed( - offset: 0, - ); - - await tester.pumpWidget(buildEditableText()); - - for (final SingleActivator activator in allModifierVariants(LogicalKeyboardKey.arrowRight)) { - await sendKeyCombination(tester, activator); - await tester.pump(); - - expect(controller.selection, const TextSelection.collapsed(offset: 0)); - } - }, variant: TargetPlatformVariant.all()); - testWidgets('select all non apple', (WidgetTester tester) async { controller.text = testText; controller.selection = const TextSelection.collapsed( @@ -2285,5 +2271,139 @@ void main() { reason: selectAllDown.toString(), ); }, variant: TargetPlatformVariant.desktop()); + + testWidgets('select left', (WidgetTester tester) async { + const SingleActivator selectLeft = + SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed( + offset: 5, + ); + + await tester.pumpWidget(buildEditableText()); + await sendKeyCombination(tester, selectLeft); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection(baseOffset: 5, extentOffset: 4), + reason: selectLeft.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); + + testWidgets('select right', (WidgetTester tester) async { + const SingleActivator selectRight = + SingleActivator(LogicalKeyboardKey.arrowRight, shift: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed( + offset: 5, + ); + + await tester.pumpWidget(buildEditableText()); + await sendKeyCombination(tester, selectRight); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection(baseOffset: 5, extentOffset: 6), + reason: selectRight.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); + + testWidgets( + 'select left should not expand selection if selection is disabled', + (WidgetTester tester) async { + const SingleActivator selectLeft = + SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed( + offset: 5, + ); + + await tester + .pumpWidget(buildEditableText(enableInteractiveSelection: false)); + await sendKeyCombination(tester, selectLeft); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection.collapsed(offset: 4), // should not expand selection + reason: selectLeft.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); + + testWidgets( + 'select right should not expand selection if selection is disabled', + (WidgetTester tester) async { + const SingleActivator selectRight = + SingleActivator(LogicalKeyboardKey.arrowRight, shift: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed(offset: 5); + + await tester + .pumpWidget(buildEditableText(enableInteractiveSelection: false)); + await sendKeyCombination(tester, selectRight); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection.collapsed( + offset: 6, + affinity: TextAffinity.upstream), // should not expand selection + reason: selectRight.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); + + testWidgets('select all left', (WidgetTester tester) async { + final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS; + final SingleActivator selectAllLeft = isMacOS + ? const SingleActivator(LogicalKeyboardKey.arrowLeft, + shift: true, meta: true) + : const SingleActivator(LogicalKeyboardKey.arrowLeft, + shift: true, alt: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed( + offset: 5, + ); + + await tester.pumpWidget(buildEditableText()); + await sendKeyCombination(tester, selectAllLeft); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection(baseOffset: 5, extentOffset: 0), + reason: selectAllLeft.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); + + testWidgets('select all right', (WidgetTester tester) async { + final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS; + final SingleActivator selectAllRight = isMacOS + ? const SingleActivator(LogicalKeyboardKey.arrowRight, + shift: true, meta: true) + : const SingleActivator(LogicalKeyboardKey.arrowRight, + shift: true, alt: true); + controller.text = 'testing'; + controller.selection = const TextSelection.collapsed( + offset: 5, + ); + + await tester.pumpWidget(buildEditableText()); + await sendKeyCombination(tester, selectAllRight); + await tester.pump(); + + expect(controller.text, 'testing'); + expect( + controller.selection, + const TextSelection(baseOffset: 5, extentOffset: 7), + reason: selectAllRight.toString(), + ); + }, variant: TargetPlatformVariant.desktop()); }, skip: !kIsWeb); // [intended] specific tests target web. }