Fix Linux numpad shortcuts on web (#148988)
## Description This PRs fixes a Web issue on Linux related to numpad keys. In https://github.com/flutter/flutter/pull/145464, I introduced numpad shortcuts for Linux. These shortcuts work well on a desktop Linux application but they broke the Linux+Web numpad logic. When I added these shortcuts, I expected them to not be active on Web (because I knew that on Web, those shortcuts are handled by the browser). But there is a trick: text editing shortcuts are still defined on Web but they are disabled at the editable text level so one can use them in components that are not `EditableText` (see https://github.com/flutter/flutter/pull/103377). In this PR, I used the same approach than for other text editing shortcuts: when on web associate those shortcuts to the `DoNothingAndStopPropagationTextIntent` intent. ## Related Issue Fixes https://github.com/flutter/flutter/issues/148447. ## Tests Updates 2 tests. Adds 2 tests.
This commit is contained in:
parent
cb26a01a40
commit
0f3882e050
@ -529,7 +529,20 @@ class DefaultTextEditingShortcuts extends StatelessWidget {
|
||||
|
||||
Map<ShortcutActivator, Intent>? _getDisablingShortcut() {
|
||||
if (kIsWeb) {
|
||||
return _webDisablingTextShortcuts;
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.linux:
|
||||
return <ShortcutActivator, Intent>{
|
||||
..._webDisablingTextShortcuts,
|
||||
for (final ShortcutActivator activator in _linuxNumpadShortcuts.keys)
|
||||
activator as SingleActivator: const DoNothingAndStopPropagationTextIntent(),
|
||||
};
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.fuchsia:
|
||||
case TargetPlatform.windows:
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.macOS:
|
||||
return _webDisablingTextShortcuts;
|
||||
}
|
||||
}
|
||||
switch (defaultTargetPlatform) {
|
||||
case TargetPlatform.android:
|
||||
|
@ -487,8 +487,8 @@ void main() {
|
||||
}, variant: macOSOnly);
|
||||
}, skip: kIsWeb); // [intended] specific tests target non-web.
|
||||
|
||||
group('Linux does accept numpad shortcuts', () {
|
||||
testWidgets('when numlock is locked', (WidgetTester tester) async {
|
||||
group('Linux numpad shortcuts', () {
|
||||
testWidgets('are triggered when numlock is locked', (WidgetTester tester) async {
|
||||
final FocusNode editable = FocusNode();
|
||||
addTearDown(editable.dispose);
|
||||
final FocusNode spy = FocusNode();
|
||||
@ -577,7 +577,7 @@ void main() {
|
||||
expect((state.lastIntent! as DeleteToNextWordBoundaryIntent).forward, true);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.linux));
|
||||
|
||||
testWidgets('when numlock is unlocked', (WidgetTester tester) async {
|
||||
testWidgets('are triggered when numlock is unlocked', (WidgetTester tester) async {
|
||||
final FocusNode editable = FocusNode();
|
||||
addTearDown(editable.dispose);
|
||||
final FocusNode spy = FocusNode();
|
||||
@ -664,7 +664,79 @@ void main() {
|
||||
expect(state.lastIntent, isA<DeleteToNextWordBoundaryIntent>());
|
||||
expect((state.lastIntent! as DeleteToNextWordBoundaryIntent).forward, true);
|
||||
}, variant: TargetPlatformVariant.only(TargetPlatform.linux));
|
||||
}, skip: kIsWeb); // [intended] specific tests target non-web.
|
||||
|
||||
testWidgets('update the editable text content when triggered on non-web', (WidgetTester tester) async {
|
||||
final FocusNode focusNode = FocusNode();
|
||||
addTearDown(focusNode.dispose);
|
||||
final TextEditingController controller = TextEditingController(text: 'Flutter');
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: EditableText(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
focusNode: focusNode,
|
||||
style: const TextStyle(fontSize: 10.0),
|
||||
cursorColor: Colors.blue,
|
||||
backgroundCursorColor: Colors.grey,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify that NumLock is unlocked.
|
||||
expect(HardwareKeyboard.instance.lockModesEnabled.contains(KeyboardLockMode.numLock), isFalse);
|
||||
|
||||
await tester.enterText(find.byType(EditableText), 'Flutter');
|
||||
expect(controller.selection.end, 7);
|
||||
|
||||
await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.numpad4));
|
||||
// Verify the cursor moved to the left (numpad4).
|
||||
expect(controller.selection.end, 6);
|
||||
},
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.linux),
|
||||
skip: kIsWeb, // [intended] Non-web test.
|
||||
);
|
||||
|
||||
testWidgets('do not update the editable text content when triggered on web', (WidgetTester tester) async {
|
||||
final FocusNode focusNode = FocusNode();
|
||||
addTearDown(focusNode.dispose);
|
||||
final TextEditingController controller = TextEditingController(text: 'Flutter');
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: EditableText(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
focusNode: focusNode,
|
||||
style: const TextStyle(fontSize: 10.0),
|
||||
cursorColor: Colors.blue,
|
||||
backgroundCursorColor: Colors.grey,
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
// Verify that NumLock is unlocked.
|
||||
expect(HardwareKeyboard.instance.lockModesEnabled.contains(KeyboardLockMode.numLock), isFalse);
|
||||
|
||||
await tester.enterText(find.byType(EditableText), 'Flutter');
|
||||
expect(controller.selection.end, 7);
|
||||
|
||||
await sendKeyCombination(tester, const SingleActivator(LogicalKeyboardKey.numpad4));
|
||||
// On web, the editable text would have been updated by the browser.
|
||||
// In the flutter test environment, the browser logic is not called
|
||||
// so the editable content is not updated when a shortcut is triggered.
|
||||
// This is the intended result, this test is checking that numpad shortcuts
|
||||
// have no effect on the web (their intent is set to DoNothingAndStopPropagationTextIntent).
|
||||
expect(controller.selection.end, 7);
|
||||
},
|
||||
variant: TargetPlatformVariant.only(TargetPlatform.linux),
|
||||
skip: !kIsWeb, // [intended] Web only.
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
class ActionSpy extends StatefulWidget {
|
||||
|
Loading…
x
Reference in New Issue
Block a user