Skip to content

Commit a24d556

Browse files
authored
Fix ActivateIntent overriding the spacebar for text entry (flutter#91129)
1 parent acf6464 commit a24d556

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

packages/flutter/lib/src/widgets/app.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,10 @@ class WidgetsApp extends StatefulWidget {
11491149
/// with "s".
11501150
static bool debugAllowBannerOverride = true;
11511151

1152+
// Any shortcuts added here have the potential to conflict with normal text
1153+
// input. If this should not happen and text input should take preference,
1154+
// then add a shortcut for the relevant key in DefaultTextEditingShortcuts
1155+
// mapped to DoNothingAndStopPropagationTextIntent.
11521156
static const Map<ShortcutActivator, Intent> _defaultShortcuts = <ShortcutActivator, Intent>{
11531157
// Activation
11541158
SingleActivator(LogicalKeyboardKey.enter): ActivateIntent(),
@@ -1206,6 +1210,11 @@ class WidgetsApp extends StatefulWidget {
12061210
};
12071211

12081212
// Default shortcuts for the macOS platform.
1213+
//
1214+
// Any shortcuts added here have the potential to conflict with normal text
1215+
// input. If this should not happen and text input should take preference,
1216+
// then add a shortcut for the relevant key in DefaultTextEditingShortcuts
1217+
// mapped to DoNothingAndStopPropagationTextIntent.
12091218
static const Map<ShortcutActivator, Intent> _defaultAppleOsShortcuts = <ShortcutActivator, Intent>{
12101219
// Activation
12111220
SingleActivator(LogicalKeyboardKey.enter): ActivateIntent(),

packages/flutter/lib/src/widgets/default_text_editing_shortcuts.dart

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,13 @@ class DefaultTextEditingShortcuts extends Shortcuts {
160160
child: child,
161161
);
162162

163+
static const Map<ShortcutActivator, Intent> _commonShortcuts = <ShortcutActivator, Intent>{
164+
// Allows space and enter to be used as input instead of a shortcut by
165+
// another widget. See https://github.com/flutter/flutter/issues/90907
166+
SingleActivator(LogicalKeyboardKey.space): DoNothingAndStopPropagationTextIntent(),
167+
SingleActivator(LogicalKeyboardKey.enter): DoNothingAndStopPropagationTextIntent(),
168+
};
169+
163170
static const Map<ShortcutActivator, Intent> _androidShortcuts = <ShortcutActivator, Intent>{
164171
SingleActivator(LogicalKeyboardKey.backspace): DeleteTextIntent(),
165172
SingleActivator(LogicalKeyboardKey.backspace, control: true): DeleteByWordTextIntent(),
@@ -532,7 +539,7 @@ class DefaultTextEditingShortcuts extends Shortcuts {
532539
SingleActivator(LogicalKeyboardKey.keyA, meta: true): DoNothingAndStopPropagationTextIntent(),
533540
};
534541

535-
static Map<ShortcutActivator, Intent> get _shortcuts {
542+
static Map<ShortcutActivator, Intent> get _platformShortcuts {
536543
if (kIsWeb) {
537544
return _webShortcuts;
538545
}
@@ -552,4 +559,11 @@ class DefaultTextEditingShortcuts extends Shortcuts {
552559
return _windowsShortcuts;
553560
}
554561
}
562+
563+
static Map<ShortcutActivator, Intent> get _shortcuts {
564+
return <ShortcutActivator, Intent>{
565+
..._commonShortcuts,
566+
..._platformShortcuts,
567+
};
568+
}
555569
}

packages/flutter/test/widgets/editable_text_test.dart

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import 'package:flutter/gestures.dart';
88
import 'package:flutter/material.dart';
99
import 'package:flutter/rendering.dart';
1010
import 'package:flutter/services.dart';
11+
import 'package:flutter/widgets.dart';
1112
import 'package:flutter_test/flutter_test.dart';
1213

1314
import '../rendering/mock_canvas.dart';
@@ -8635,6 +8636,71 @@ void main() {
86358636
await tester.pump();
86368637
expect(scrollController.offset.roundToDouble(), 0.0);
86378638
});
8639+
8640+
// Regression test for https://github.com/flutter/flutter/issues/90907.
8641+
testWidgets("ActivateIntent doesn't block space entry", (WidgetTester tester) async {
8642+
final FocusNode focusNode = FocusNode();
8643+
bool invoked = false;
8644+
8645+
await tester.pumpWidget(MaterialApp(
8646+
home: Scaffold(
8647+
body: Align(
8648+
alignment: Alignment.topLeft,
8649+
child: SizedBox(
8650+
width: 100,
8651+
child: ListTile(
8652+
title: Actions(
8653+
actions: <Type, Action<Intent>>{
8654+
ActivateIntent: CallbackAction<ActivateIntent>(
8655+
onInvoke: (ActivateIntent intent) {
8656+
invoked = true;
8657+
},
8658+
),
8659+
},
8660+
child: Column(
8661+
children: <Widget>[
8662+
EditableText(
8663+
autofocus: true,
8664+
showSelectionHandles: true,
8665+
maxLines: 2,
8666+
controller: TextEditingController(),
8667+
focusNode: FocusNode(),
8668+
cursorColor: Colors.red,
8669+
backgroundCursorColor: Colors.blue,
8670+
style: Typography.material2018(platform: TargetPlatform.android).black.subtitle1!.copyWith(fontFamily: 'Roboto'),
8671+
keyboardType: TextInputType.text,
8672+
),
8673+
Focus(
8674+
focusNode: focusNode,
8675+
child: const Text('Hello'),
8676+
),
8677+
],
8678+
),
8679+
),
8680+
),
8681+
),
8682+
),
8683+
),
8684+
));
8685+
8686+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
8687+
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
8688+
await tester.pump();
8689+
expect(invoked, isFalse);
8690+
8691+
focusNode.requestFocus();
8692+
await tester.pump();
8693+
await tester.sendKeyEvent(LogicalKeyboardKey.space);
8694+
await tester.pump();
8695+
expect(invoked, isTrue);
8696+
8697+
invoked = false;
8698+
await tester.pump();
8699+
await tester.sendKeyEvent(LogicalKeyboardKey.enter);
8700+
await tester.pump();
8701+
// On the web, enter doesn't activate any controls except for buttons.
8702+
expect(invoked, kIsWeb ? isFalse : isTrue);
8703+
});
86388704
}
86398705

86408706
class UnsettableController extends TextEditingController {

0 commit comments

Comments
 (0)