1// Copyright 2014 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// @docImport 'app.dart';
6library;
7
8import 'package:flutter/foundation.dart';
9import 'package:flutter/painting.dart';
10import 'package:flutter/services.dart';
11
12import 'actions.dart';
13import 'focus_traversal.dart';
14import 'framework.dart';
15import 'scrollable_helpers.dart';
16import 'shortcuts.dart';
17import 'text_editing_intents.dart';
18
19/// A widget with the shortcuts used for the default text editing behavior.
20///
21/// This default behavior can be overridden by placing a [Shortcuts] widget
22/// lower in the widget tree than this. See the [Action] class for an example
23/// of remapping an [Intent] to a custom [Action].
24///
25/// The [Shortcuts] widget usually takes precedence over system keybindings.
26/// Proceed with caution if the shortcut you wish to override is also used by
27/// the system. For example, overriding [LogicalKeyboardKey.backspace] could
28/// cause CJK input methods to discard more text than they should when the
29/// backspace key is pressed during text composition on iOS.
30///
31/// {@macro flutter.widgets.editableText.shortcutsAndTextInput}
32///
33/// {@tool snippet}
34///
35/// This example shows how to use an additional [Shortcuts] widget to override
36/// some default text editing keyboard shortcuts to have new behavior. Instead
37/// of moving the cursor, alt + up/down will change the focused widget.
38///
39/// ```dart
40/// @override
41/// Widget build(BuildContext context) {
42/// // If using WidgetsApp or its descendants MaterialApp or CupertinoApp,
43/// // then DefaultTextEditingShortcuts is already being inserted into the
44/// // widget tree.
45/// return const DefaultTextEditingShortcuts(
46/// child: Center(
47/// child: Shortcuts(
48/// shortcuts: <ShortcutActivator, Intent>{
49/// SingleActivator(LogicalKeyboardKey.arrowDown, alt: true): NextFocusIntent(),
50/// SingleActivator(LogicalKeyboardKey.arrowUp, alt: true): PreviousFocusIntent(),
51/// },
52/// child: Column(
53/// children: <Widget>[
54/// TextField(
55/// decoration: InputDecoration(
56/// hintText: 'alt + down moves to the next field.',
57/// ),
58/// ),
59/// TextField(
60/// decoration: InputDecoration(
61/// hintText: 'And alt + up moves to the previous.',
62/// ),
63/// ),
64/// ],
65/// ),
66/// ),
67/// ),
68/// );
69/// }
70/// ```
71/// {@end-tool}
72///
73/// {@tool snippet}
74///
75/// This example shows how to use an additional [Shortcuts] widget to override
76/// default text editing shortcuts to have completely custom behavior defined by
77/// a custom Intent and Action. Here, the up/down arrow keys increment/decrement
78/// a counter instead of moving the cursor.
79///
80/// ```dart
81/// class IncrementCounterIntent extends Intent {}
82/// class DecrementCounterIntent extends Intent {}
83///
84/// class MyWidget extends StatefulWidget {
85/// const MyWidget({ super.key });
86///
87/// @override
88/// MyWidgetState createState() => MyWidgetState();
89/// }
90///
91/// class MyWidgetState extends State<MyWidget> {
92///
93/// int _counter = 0;
94///
95/// @override
96/// Widget build(BuildContext context) {
97/// // If using WidgetsApp or its descendants MaterialApp or CupertinoApp,
98/// // then DefaultTextEditingShortcuts is already being inserted into the
99/// // widget tree.
100/// return DefaultTextEditingShortcuts(
101/// child: Center(
102/// child: Column(
103/// mainAxisAlignment: MainAxisAlignment.center,
104/// children: <Widget>[
105/// const Text(
106/// 'You have pushed the button this many times:',
107/// ),
108/// Text(
109/// '$_counter',
110/// style: Theme.of(context).textTheme.headlineMedium,
111/// ),
112/// Shortcuts(
113/// shortcuts: <ShortcutActivator, Intent>{
114/// const SingleActivator(LogicalKeyboardKey.arrowUp): IncrementCounterIntent(),
115/// const SingleActivator(LogicalKeyboardKey.arrowDown): DecrementCounterIntent(),
116/// },
117/// child: Actions(
118/// actions: <Type, Action<Intent>>{
119/// IncrementCounterIntent: CallbackAction<IncrementCounterIntent>(
120/// onInvoke: (IncrementCounterIntent intent) {
121/// setState(() {
122/// _counter++;
123/// });
124/// return null;
125/// },
126/// ),
127/// DecrementCounterIntent: CallbackAction<DecrementCounterIntent>(
128/// onInvoke: (DecrementCounterIntent intent) {
129/// setState(() {
130/// _counter--;
131/// });
132/// return null;
133/// },
134/// ),
135/// },
136/// child: const TextField(
137/// maxLines: 2,
138/// decoration: InputDecoration(
139/// hintText: 'Up/down increment/decrement here.',
140/// ),
141/// ),
142/// ),
143/// ),
144/// const TextField(
145/// maxLines: 2,
146/// decoration: InputDecoration(
147/// hintText: 'Up/down behave normally here.',
148/// ),
149/// ),
150/// ],
151/// ),
152/// ),
153/// );
154/// }
155/// }
156/// ```
157/// {@end-tool}
158///
159/// See also:
160///
161/// * [WidgetsApp], which creates a DefaultTextEditingShortcuts.
162class DefaultTextEditingShortcuts extends StatelessWidget {
163 /// Creates a [DefaultTextEditingShortcuts] widget that provides the default text editing
164 /// shortcuts on the current platform.
165 const DefaultTextEditingShortcuts({super.key, required this.child});
166
167 /// {@macro flutter.widgets.ProxyWidget.child}
168 final Widget child;
169
170 // These shortcuts are shared between all platforms except Apple platforms,
171 // because they use different modifier keys as the line/word modifier.
172 static final Map<ShortcutActivator, Intent> _commonShortcuts = <ShortcutActivator, Intent>{
173 // Delete Shortcuts.
174 for (final bool pressShift in const <bool>[true, false]) ...<SingleActivator, Intent>{
175 SingleActivator(LogicalKeyboardKey.backspace, shift: pressShift): const DeleteCharacterIntent(
176 forward: false,
177 ),
178 SingleActivator(LogicalKeyboardKey.backspace, control: true, shift: pressShift):
179 const DeleteToNextWordBoundaryIntent(forward: false),
180 SingleActivator(LogicalKeyboardKey.backspace, alt: true, shift: pressShift):
181 const DeleteToLineBreakIntent(forward: false),
182 SingleActivator(LogicalKeyboardKey.delete, shift: pressShift): const DeleteCharacterIntent(
183 forward: true,
184 ),
185 SingleActivator(LogicalKeyboardKey.delete, control: true, shift: pressShift):
186 const DeleteToNextWordBoundaryIntent(forward: true),
187 SingleActivator(LogicalKeyboardKey.delete, alt: true, shift: pressShift):
188 const DeleteToLineBreakIntent(forward: true),
189 },
190
191 // Arrow: Move selection.
192 const SingleActivator(LogicalKeyboardKey.arrowLeft): const ExtendSelectionByCharacterIntent(
193 forward: false,
194 collapseSelection: true,
195 ),
196 const SingleActivator(LogicalKeyboardKey.arrowRight): const ExtendSelectionByCharacterIntent(
197 forward: true,
198 collapseSelection: true,
199 ),
200 const SingleActivator(
201 LogicalKeyboardKey.arrowUp,
202 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
203 forward: false,
204 collapseSelection: true,
205 ),
206 const SingleActivator(LogicalKeyboardKey.arrowDown):
207 const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
208
209 // Shift + Arrow: Extend selection.
210 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true):
211 const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: false),
212 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true):
213 const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: false),
214 const SingleActivator(
215 LogicalKeyboardKey.arrowUp,
216 shift: true,
217 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
218 forward: false,
219 collapseSelection: false,
220 ),
221 const SingleActivator(
222 LogicalKeyboardKey.arrowDown,
223 shift: true,
224 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
225 forward: true,
226 collapseSelection: false,
227 ),
228
229 const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true):
230 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: true),
231 const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true):
232 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: true),
233 const SingleActivator(LogicalKeyboardKey.arrowUp, alt: true):
234 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: true),
235 const SingleActivator(LogicalKeyboardKey.arrowDown, alt: true):
236 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: true),
237
238 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: true):
239 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: false),
240 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, alt: true):
241 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: false),
242 const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, alt: true):
243 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: false),
244 const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, alt: true):
245 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: false),
246
247 const SingleActivator(LogicalKeyboardKey.arrowLeft, control: true):
248 const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: true),
249 const SingleActivator(LogicalKeyboardKey.arrowRight, control: true):
250 const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: true),
251
252 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, control: true):
253 const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: false),
254 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, control: true):
255 const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: false),
256
257 const SingleActivator(
258 LogicalKeyboardKey.arrowUp,
259 shift: true,
260 control: true,
261 ): const ExtendSelectionToNextParagraphBoundaryIntent(
262 forward: false,
263 collapseSelection: false,
264 ),
265 const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, control: true):
266 const ExtendSelectionToNextParagraphBoundaryIntent(forward: true, collapseSelection: false),
267
268 // Page Up / Down: Move selection by page.
269 const SingleActivator(
270 LogicalKeyboardKey.pageUp,
271 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
272 forward: false,
273 collapseSelection: true,
274 ),
275 const SingleActivator(LogicalKeyboardKey.pageDown):
276 const ExtendSelectionVerticallyToAdjacentPageIntent(forward: true, collapseSelection: true),
277
278 // Shift + Page Up / Down: Extend selection by page.
279 const SingleActivator(
280 LogicalKeyboardKey.pageUp,
281 shift: true,
282 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
283 forward: false,
284 collapseSelection: false,
285 ),
286 const SingleActivator(
287 LogicalKeyboardKey.pageDown,
288 shift: true,
289 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
290 forward: true,
291 collapseSelection: false,
292 ),
293
294 const SingleActivator(LogicalKeyboardKey.keyX, control: true):
295 const CopySelectionTextIntent.cut(SelectionChangedCause.keyboard),
296 const SingleActivator(LogicalKeyboardKey.keyC, control: true): CopySelectionTextIntent.copy,
297 const SingleActivator(LogicalKeyboardKey.keyV, control: true): const PasteTextIntent(
298 SelectionChangedCause.keyboard,
299 ),
300 const SingleActivator(LogicalKeyboardKey.keyA, control: true): const SelectAllTextIntent(
301 SelectionChangedCause.keyboard,
302 ),
303 const SingleActivator(LogicalKeyboardKey.keyZ, control: true): const UndoTextIntent(
304 SelectionChangedCause.keyboard,
305 ),
306 const SingleActivator(LogicalKeyboardKey.keyZ, shift: true, control: true):
307 const RedoTextIntent(SelectionChangedCause.keyboard),
308 // These keys should go to the IME when a field is focused, not to other
309 // Shortcuts.
310 const SingleActivator(LogicalKeyboardKey.space): const DoNothingAndStopPropagationTextIntent(),
311 const SingleActivator(LogicalKeyboardKey.enter): const DoNothingAndStopPropagationTextIntent(),
312 };
313
314 // The following key combinations have no effect on text editing on this
315 // platform:
316 // * Meta + X
317 // * Meta + C
318 // * Meta + V
319 // * Meta + A
320 // * Meta + shift? + Z
321 // * Meta + shift? + arrow down
322 // * Meta + shift? + arrow left
323 // * Meta + shift? + arrow right
324 // * Meta + shift? + arrow up
325 // * Meta + shift? + delete
326 // * Meta + shift? + backspace
327 static final Map<ShortcutActivator, Intent> _androidShortcuts = <ShortcutActivator, Intent>{
328 ..._commonShortcuts,
329 const SingleActivator(LogicalKeyboardKey.home): const ExtendSelectionToLineBreakIntent(
330 forward: false,
331 collapseSelection: true,
332 continuesAtWrap: true,
333 ),
334 const SingleActivator(LogicalKeyboardKey.end): const ExtendSelectionToLineBreakIntent(
335 forward: true,
336 collapseSelection: true,
337 continuesAtWrap: true,
338 ),
339 const SingleActivator(
340 LogicalKeyboardKey.home,
341 shift: true,
342 ): const ExtendSelectionToLineBreakIntent(
343 forward: false,
344 collapseSelection: false,
345 continuesAtWrap: true,
346 ),
347 const SingleActivator(
348 LogicalKeyboardKey.end,
349 shift: true,
350 ): const ExtendSelectionToLineBreakIntent(
351 forward: true,
352 collapseSelection: false,
353 continuesAtWrap: true,
354 ),
355 const SingleActivator(LogicalKeyboardKey.home, control: true):
356 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: true),
357 const SingleActivator(LogicalKeyboardKey.end, control: true):
358 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: true),
359 const SingleActivator(LogicalKeyboardKey.home, shift: true, control: true):
360 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: false),
361 const SingleActivator(LogicalKeyboardKey.end, shift: true, control: true):
362 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: false),
363 };
364
365 static final Map<ShortcutActivator, Intent> _fuchsiaShortcuts = _androidShortcuts;
366
367 static final Map<ShortcutActivator, Intent> _linuxNumpadShortcuts = <ShortcutActivator, Intent>{
368 // When numLock is on, numpad keys shortcuts require shift to be pressed too.
369 const SingleActivator(LogicalKeyboardKey.numpad6, shift: true, numLock: LockState.locked):
370 const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: false),
371 const SingleActivator(LogicalKeyboardKey.numpad4, shift: true, numLock: LockState.locked):
372 const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: false),
373 const SingleActivator(
374 LogicalKeyboardKey.numpad8,
375 shift: true,
376 numLock: LockState.locked,
377 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
378 forward: false,
379 collapseSelection: false,
380 ),
381 const SingleActivator(
382 LogicalKeyboardKey.numpad2,
383 shift: true,
384 numLock: LockState.locked,
385 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
386 forward: true,
387 collapseSelection: false,
388 ),
389
390 const SingleActivator(
391 LogicalKeyboardKey.numpad6,
392 shift: true,
393 control: true,
394 numLock: LockState.locked,
395 ): const ExtendSelectionToNextWordBoundaryIntent(
396 forward: true,
397 collapseSelection: false,
398 ),
399 const SingleActivator(
400 LogicalKeyboardKey.numpad4,
401 shift: true,
402 control: true,
403 numLock: LockState.locked,
404 ): const ExtendSelectionToNextWordBoundaryIntent(
405 forward: false,
406 collapseSelection: false,
407 ),
408 const SingleActivator(
409 LogicalKeyboardKey.numpad8,
410 shift: true,
411 control: true,
412 numLock: LockState.locked,
413 ): const ExtendSelectionToNextParagraphBoundaryIntent(
414 forward: false,
415 collapseSelection: false,
416 ),
417 const SingleActivator(
418 LogicalKeyboardKey.numpad2,
419 shift: true,
420 control: true,
421 numLock: LockState.locked,
422 ): const ExtendSelectionToNextParagraphBoundaryIntent(
423 forward: true,
424 collapseSelection: false,
425 ),
426
427 const SingleActivator(
428 LogicalKeyboardKey.numpad9,
429 shift: true,
430 numLock: LockState.locked,
431 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
432 forward: false,
433 collapseSelection: false,
434 ),
435 const SingleActivator(
436 LogicalKeyboardKey.numpad3,
437 shift: true,
438 numLock: LockState.locked,
439 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
440 forward: true,
441 collapseSelection: false,
442 ),
443
444 const SingleActivator(
445 LogicalKeyboardKey.numpad7,
446 shift: true,
447 numLock: LockState.locked,
448 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
449 forward: false,
450 collapseSelection: false,
451 ),
452 const SingleActivator(
453 LogicalKeyboardKey.numpad1,
454 shift: true,
455 numLock: LockState.locked,
456 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
457 forward: true,
458 collapseSelection: false,
459 ),
460
461 const SingleActivator(LogicalKeyboardKey.numpadDecimal, shift: true, numLock: LockState.locked):
462 const DeleteCharacterIntent(forward: true),
463 const SingleActivator(
464 LogicalKeyboardKey.numpadDecimal,
465 shift: true,
466 control: true,
467 numLock: LockState.locked,
468 ): const DeleteToNextWordBoundaryIntent(
469 forward: true,
470 ),
471
472 // When numLock is off, numpad keys shortcuts require shift not to be pressed.
473 const SingleActivator(LogicalKeyboardKey.numpad6, numLock: LockState.unlocked):
474 const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: true),
475 const SingleActivator(LogicalKeyboardKey.numpad4, numLock: LockState.unlocked):
476 const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: true),
477 const SingleActivator(
478 LogicalKeyboardKey.numpad8,
479 numLock: LockState.unlocked,
480 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
481 forward: false,
482 collapseSelection: true,
483 ),
484 const SingleActivator(LogicalKeyboardKey.numpad2, numLock: LockState.unlocked):
485 const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
486
487 const SingleActivator(LogicalKeyboardKey.numpad6, control: true, numLock: LockState.unlocked):
488 const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: true),
489 const SingleActivator(LogicalKeyboardKey.numpad4, control: true, numLock: LockState.unlocked):
490 const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: true),
491 const SingleActivator(LogicalKeyboardKey.numpad8, control: true, numLock: LockState.unlocked):
492 const ExtendSelectionToNextParagraphBoundaryIntent(forward: false, collapseSelection: true),
493 const SingleActivator(LogicalKeyboardKey.numpad2, control: true, numLock: LockState.unlocked):
494 const ExtendSelectionToNextParagraphBoundaryIntent(forward: true, collapseSelection: true),
495
496 const SingleActivator(
497 LogicalKeyboardKey.numpad9,
498 numLock: LockState.unlocked,
499 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
500 forward: false,
501 collapseSelection: true,
502 ),
503 const SingleActivator(LogicalKeyboardKey.numpad3, numLock: LockState.unlocked):
504 const ExtendSelectionVerticallyToAdjacentPageIntent(forward: true, collapseSelection: true),
505
506 const SingleActivator(
507 LogicalKeyboardKey.numpad7,
508 numLock: LockState.unlocked,
509 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
510 forward: false,
511 collapseSelection: true,
512 ),
513 const SingleActivator(LogicalKeyboardKey.numpad1, numLock: LockState.unlocked):
514 const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
515
516 const SingleActivator(LogicalKeyboardKey.numpadDecimal, numLock: LockState.unlocked):
517 const DeleteCharacterIntent(forward: true),
518 const SingleActivator(
519 LogicalKeyboardKey.numpadDecimal,
520 control: true,
521 numLock: LockState.unlocked,
522 ): const DeleteToNextWordBoundaryIntent(
523 forward: true,
524 ),
525 };
526
527 static final Map<ShortcutActivator, Intent> _linuxShortcuts = <ShortcutActivator, Intent>{
528 ..._commonShortcuts,
529 ..._linuxNumpadShortcuts,
530 const SingleActivator(LogicalKeyboardKey.home): const ExtendSelectionToLineBreakIntent(
531 forward: false,
532 collapseSelection: true,
533 ),
534 const SingleActivator(LogicalKeyboardKey.end): const ExtendSelectionToLineBreakIntent(
535 forward: true,
536 collapseSelection: true,
537 ),
538 const SingleActivator(LogicalKeyboardKey.home, shift: true):
539 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: false),
540 const SingleActivator(LogicalKeyboardKey.end, shift: true):
541 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: false),
542 const SingleActivator(LogicalKeyboardKey.home, control: true):
543 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: true),
544 const SingleActivator(LogicalKeyboardKey.end, control: true):
545 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: true),
546 const SingleActivator(LogicalKeyboardKey.home, shift: true, control: true):
547 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: false),
548 const SingleActivator(LogicalKeyboardKey.end, shift: true, control: true):
549 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: false),
550 // The following key combinations have no effect on text editing on this
551 // platform:
552 // * Control + shift? + end
553 // * Control + shift? + home
554 // * Meta + X
555 // * Meta + C
556 // * Meta + V
557 // * Meta + A
558 // * Meta + shift? + Z
559 // * Meta + shift? + arrow down
560 // * Meta + shift? + arrow left
561 // * Meta + shift? + arrow right
562 // * Meta + shift? + arrow up
563 // * Meta + shift? + delete
564 // * Meta + shift? + backspace
565 };
566
567 // macOS document shortcuts: https://support.apple.com/en-us/HT201236.
568 // The macOS shortcuts uses different word/line modifiers than most other
569 // platforms.
570 static final Map<ShortcutActivator, Intent> _macShortcuts = <ShortcutActivator, Intent>{
571 for (final bool pressShift in const <bool>[true, false]) ...<SingleActivator, Intent>{
572 SingleActivator(LogicalKeyboardKey.backspace, shift: pressShift): const DeleteCharacterIntent(
573 forward: false,
574 ),
575 SingleActivator(LogicalKeyboardKey.backspace, alt: true, shift: pressShift):
576 const DeleteToNextWordBoundaryIntent(forward: false),
577 SingleActivator(LogicalKeyboardKey.backspace, meta: true, shift: pressShift):
578 const DeleteToLineBreakIntent(forward: false),
579 SingleActivator(LogicalKeyboardKey.delete, shift: pressShift): const DeleteCharacterIntent(
580 forward: true,
581 ),
582 SingleActivator(LogicalKeyboardKey.delete, alt: true, shift: pressShift):
583 const DeleteToNextWordBoundaryIntent(forward: true),
584 SingleActivator(LogicalKeyboardKey.delete, meta: true, shift: pressShift):
585 const DeleteToLineBreakIntent(forward: true),
586 },
587
588 const SingleActivator(LogicalKeyboardKey.arrowLeft): const ExtendSelectionByCharacterIntent(
589 forward: false,
590 collapseSelection: true,
591 ),
592 const SingleActivator(LogicalKeyboardKey.arrowRight): const ExtendSelectionByCharacterIntent(
593 forward: true,
594 collapseSelection: true,
595 ),
596 const SingleActivator(
597 LogicalKeyboardKey.arrowUp,
598 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
599 forward: false,
600 collapseSelection: true,
601 ),
602 const SingleActivator(LogicalKeyboardKey.arrowDown):
603 const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
604
605 // Shift + Arrow: Extend selection.
606 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true):
607 const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: false),
608 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true):
609 const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: false),
610 const SingleActivator(
611 LogicalKeyboardKey.arrowUp,
612 shift: true,
613 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
614 forward: false,
615 collapseSelection: false,
616 ),
617 const SingleActivator(
618 LogicalKeyboardKey.arrowDown,
619 shift: true,
620 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
621 forward: true,
622 collapseSelection: false,
623 ),
624
625 const SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true):
626 const ExtendSelectionToNextWordBoundaryIntent(forward: false, collapseSelection: true),
627 const SingleActivator(LogicalKeyboardKey.arrowRight, alt: true):
628 const ExtendSelectionToNextWordBoundaryIntent(forward: true, collapseSelection: true),
629 const SingleActivator(LogicalKeyboardKey.arrowUp, alt: true):
630 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: true),
631 const SingleActivator(LogicalKeyboardKey.arrowDown, alt: true):
632 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: true),
633
634 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: true):
635 const ExtendSelectionToNextWordBoundaryOrCaretLocationIntent(forward: false),
636 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, alt: true):
637 const ExtendSelectionToNextWordBoundaryOrCaretLocationIntent(forward: true),
638 const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, alt: true):
639 const ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent(forward: false),
640 const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, alt: true):
641 const ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent(forward: true),
642
643 const SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true):
644 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: true),
645 const SingleActivator(LogicalKeyboardKey.arrowRight, meta: true):
646 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: true),
647 const SingleActivator(LogicalKeyboardKey.arrowUp, meta: true):
648 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: true),
649 const SingleActivator(LogicalKeyboardKey.arrowDown, meta: true):
650 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: true),
651
652 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, meta: true):
653 const ExpandSelectionToLineBreakIntent(forward: false),
654 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, meta: true):
655 const ExpandSelectionToLineBreakIntent(forward: true),
656 const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, meta: true):
657 const ExpandSelectionToDocumentBoundaryIntent(forward: false),
658 const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, meta: true):
659 const ExpandSelectionToDocumentBoundaryIntent(forward: true),
660
661 const SingleActivator(LogicalKeyboardKey.keyT, control: true):
662 const TransposeCharactersIntent(),
663
664 const SingleActivator(LogicalKeyboardKey.home): const ScrollToDocumentBoundaryIntent(
665 forward: false,
666 ),
667 const SingleActivator(LogicalKeyboardKey.end): const ScrollToDocumentBoundaryIntent(
668 forward: true,
669 ),
670 const SingleActivator(LogicalKeyboardKey.home, shift: true):
671 const ExpandSelectionToDocumentBoundaryIntent(forward: false),
672 const SingleActivator(LogicalKeyboardKey.end, shift: true):
673 const ExpandSelectionToDocumentBoundaryIntent(forward: true),
674
675 const SingleActivator(LogicalKeyboardKey.pageUp): const ScrollIntent(
676 direction: AxisDirection.up,
677 type: ScrollIncrementType.page,
678 ),
679 const SingleActivator(LogicalKeyboardKey.pageDown): const ScrollIntent(
680 direction: AxisDirection.down,
681 type: ScrollIncrementType.page,
682 ),
683 const SingleActivator(
684 LogicalKeyboardKey.pageUp,
685 shift: true,
686 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
687 forward: false,
688 collapseSelection: false,
689 ),
690 const SingleActivator(
691 LogicalKeyboardKey.pageDown,
692 shift: true,
693 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
694 forward: true,
695 collapseSelection: false,
696 ),
697
698 const SingleActivator(LogicalKeyboardKey.keyX, meta: true): const CopySelectionTextIntent.cut(
699 SelectionChangedCause.keyboard,
700 ),
701 const SingleActivator(LogicalKeyboardKey.keyC, meta: true): CopySelectionTextIntent.copy,
702 const SingleActivator(LogicalKeyboardKey.keyV, meta: true): const PasteTextIntent(
703 SelectionChangedCause.keyboard,
704 ),
705 const SingleActivator(LogicalKeyboardKey.keyA, meta: true): const SelectAllTextIntent(
706 SelectionChangedCause.keyboard,
707 ),
708 const SingleActivator(LogicalKeyboardKey.keyZ, meta: true): const UndoTextIntent(
709 SelectionChangedCause.keyboard,
710 ),
711 const SingleActivator(LogicalKeyboardKey.keyZ, shift: true, meta: true): const RedoTextIntent(
712 SelectionChangedCause.keyboard,
713 ),
714 const SingleActivator(LogicalKeyboardKey.keyE, control: true):
715 const ExtendSelectionToLineBreakIntent(forward: true, collapseSelection: true),
716 const SingleActivator(LogicalKeyboardKey.keyA, control: true):
717 const ExtendSelectionToLineBreakIntent(forward: false, collapseSelection: true),
718 const SingleActivator(LogicalKeyboardKey.keyF, control: true):
719 const ExtendSelectionByCharacterIntent(forward: true, collapseSelection: true),
720 const SingleActivator(LogicalKeyboardKey.keyB, control: true):
721 const ExtendSelectionByCharacterIntent(forward: false, collapseSelection: true),
722 const SingleActivator(LogicalKeyboardKey.keyN, control: true):
723 const ExtendSelectionVerticallyToAdjacentLineIntent(forward: true, collapseSelection: true),
724 const SingleActivator(
725 LogicalKeyboardKey.keyP,
726 control: true,
727 ): const ExtendSelectionVerticallyToAdjacentLineIntent(
728 forward: false,
729 collapseSelection: true,
730 ),
731 // These keys should go to the IME when a field is focused, not to other
732 // Shortcuts.
733 const SingleActivator(LogicalKeyboardKey.space): const DoNothingAndStopPropagationTextIntent(),
734 const SingleActivator(LogicalKeyboardKey.enter): const DoNothingAndStopPropagationTextIntent(),
735 // The following key combinations have no effect on text editing on this
736 // platform:
737 // * End
738 // * Home
739 // * Control + shift? + end
740 // * Control + shift? + home
741 // * Control + shift? + Z
742 };
743
744 // There is no complete documentation of iOS shortcuts: use macOS ones.
745 static final Map<ShortcutActivator, Intent> _iOSShortcuts = _macShortcuts;
746
747 // The following key combinations have no effect on text editing on this
748 // platform:
749 // * Meta + X
750 // * Meta + C
751 // * Meta + V
752 // * Meta + A
753 // * Meta + shift? + arrow down
754 // * Meta + shift? + arrow left
755 // * Meta + shift? + arrow right
756 // * Meta + shift? + arrow up
757 // * Meta + delete
758 // * Meta + backspace
759 static final Map<ShortcutActivator, Intent> _windowsShortcuts = <ShortcutActivator, Intent>{
760 ..._commonShortcuts,
761 const SingleActivator(
762 LogicalKeyboardKey.pageUp,
763 ): const ExtendSelectionVerticallyToAdjacentPageIntent(
764 forward: false,
765 collapseSelection: true,
766 ),
767 const SingleActivator(LogicalKeyboardKey.pageDown):
768 const ExtendSelectionVerticallyToAdjacentPageIntent(forward: true, collapseSelection: true),
769 const SingleActivator(LogicalKeyboardKey.home): const ExtendSelectionToLineBreakIntent(
770 forward: false,
771 collapseSelection: true,
772 continuesAtWrap: true,
773 ),
774 const SingleActivator(LogicalKeyboardKey.end): const ExtendSelectionToLineBreakIntent(
775 forward: true,
776 collapseSelection: true,
777 continuesAtWrap: true,
778 ),
779 const SingleActivator(
780 LogicalKeyboardKey.home,
781 shift: true,
782 ): const ExtendSelectionToLineBreakIntent(
783 forward: false,
784 collapseSelection: false,
785 continuesAtWrap: true,
786 ),
787 const SingleActivator(
788 LogicalKeyboardKey.end,
789 shift: true,
790 ): const ExtendSelectionToLineBreakIntent(
791 forward: true,
792 collapseSelection: false,
793 continuesAtWrap: true,
794 ),
795 const SingleActivator(LogicalKeyboardKey.home, control: true):
796 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: true),
797 const SingleActivator(LogicalKeyboardKey.end, control: true):
798 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: true),
799 const SingleActivator(LogicalKeyboardKey.home, shift: true, control: true):
800 const ExtendSelectionToDocumentBoundaryIntent(forward: false, collapseSelection: false),
801 const SingleActivator(LogicalKeyboardKey.end, shift: true, control: true):
802 const ExtendSelectionToDocumentBoundaryIntent(forward: true, collapseSelection: false),
803 };
804
805 // Web handles its text selection natively and doesn't use any of these
806 // shortcuts in Flutter.
807 static final Map<ShortcutActivator, Intent> _webDisablingTextShortcuts =
808 <ShortcutActivator, Intent>{
809 for (final bool pressShift in const <bool>[true, false]) ...<SingleActivator, Intent>{
810 SingleActivator(LogicalKeyboardKey.backspace, shift: pressShift):
811 const DoNothingAndStopPropagationTextIntent(),
812 SingleActivator(LogicalKeyboardKey.delete, shift: pressShift):
813 const DoNothingAndStopPropagationTextIntent(),
814 SingleActivator(LogicalKeyboardKey.backspace, alt: true, shift: pressShift):
815 const DoNothingAndStopPropagationTextIntent(),
816 SingleActivator(LogicalKeyboardKey.delete, alt: true, shift: pressShift):
817 const DoNothingAndStopPropagationTextIntent(),
818 SingleActivator(LogicalKeyboardKey.backspace, control: true, shift: pressShift):
819 const DoNothingAndStopPropagationTextIntent(),
820 SingleActivator(LogicalKeyboardKey.delete, control: true, shift: pressShift):
821 const DoNothingAndStopPropagationTextIntent(),
822 SingleActivator(LogicalKeyboardKey.backspace, meta: true, shift: pressShift):
823 const DoNothingAndStopPropagationTextIntent(),
824 SingleActivator(LogicalKeyboardKey.delete, meta: true, shift: pressShift):
825 const DoNothingAndStopPropagationTextIntent(),
826 },
827 ..._commonDisablingTextShortcuts,
828 const SingleActivator(LogicalKeyboardKey.keyX, control: true):
829 const DoNothingAndStopPropagationTextIntent(),
830 const SingleActivator(LogicalKeyboardKey.keyX, meta: true):
831 const DoNothingAndStopPropagationTextIntent(),
832 const SingleActivator(LogicalKeyboardKey.keyC, control: true):
833 const DoNothingAndStopPropagationTextIntent(),
834 const SingleActivator(LogicalKeyboardKey.keyC, meta: true):
835 const DoNothingAndStopPropagationTextIntent(),
836 const SingleActivator(LogicalKeyboardKey.keyV, control: true):
837 const DoNothingAndStopPropagationTextIntent(),
838 const SingleActivator(LogicalKeyboardKey.keyV, meta: true):
839 const DoNothingAndStopPropagationTextIntent(),
840 const SingleActivator(LogicalKeyboardKey.keyA, control: true):
841 const DoNothingAndStopPropagationTextIntent(),
842 const SingleActivator(LogicalKeyboardKey.keyA, meta: true):
843 const DoNothingAndStopPropagationTextIntent(),
844 };
845
846 static const Map<ShortcutActivator, Intent> _commonDisablingTextShortcuts =
847 <ShortcutActivator, Intent>{
848 SingleActivator(LogicalKeyboardKey.arrowDown, alt: true):
849 DoNothingAndStopPropagationTextIntent(),
850 SingleActivator(LogicalKeyboardKey.arrowLeft, alt: true):
851 DoNothingAndStopPropagationTextIntent(),
852 SingleActivator(LogicalKeyboardKey.arrowRight, alt: true):
853 DoNothingAndStopPropagationTextIntent(),
854 SingleActivator(LogicalKeyboardKey.arrowUp, alt: true):
855 DoNothingAndStopPropagationTextIntent(),
856 SingleActivator(LogicalKeyboardKey.arrowDown, meta: true):
857 DoNothingAndStopPropagationTextIntent(),
858 SingleActivator(LogicalKeyboardKey.arrowLeft, meta: true):
859 DoNothingAndStopPropagationTextIntent(),
860 SingleActivator(LogicalKeyboardKey.arrowRight, meta: true):
861 DoNothingAndStopPropagationTextIntent(),
862 SingleActivator(LogicalKeyboardKey.arrowUp, meta: true):
863 DoNothingAndStopPropagationTextIntent(),
864 SingleActivator(LogicalKeyboardKey.arrowDown): DoNothingAndStopPropagationTextIntent(),
865 SingleActivator(LogicalKeyboardKey.arrowLeft): DoNothingAndStopPropagationTextIntent(),
866 SingleActivator(LogicalKeyboardKey.arrowRight): DoNothingAndStopPropagationTextIntent(),
867 SingleActivator(LogicalKeyboardKey.arrowUp): DoNothingAndStopPropagationTextIntent(),
868 SingleActivator(LogicalKeyboardKey.arrowLeft, control: true):
869 DoNothingAndStopPropagationTextIntent(),
870 SingleActivator(LogicalKeyboardKey.arrowRight, control: true):
871 DoNothingAndStopPropagationTextIntent(),
872 SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, control: true):
873 DoNothingAndStopPropagationTextIntent(),
874 SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, control: true):
875 DoNothingAndStopPropagationTextIntent(),
876 SingleActivator(LogicalKeyboardKey.space): DoNothingAndStopPropagationTextIntent(),
877 SingleActivator(LogicalKeyboardKey.enter): DoNothingAndStopPropagationTextIntent(),
878 };
879
880 static final Map<ShortcutActivator, Intent>
881 _macDisablingTextShortcuts = <ShortcutActivator, Intent>{
882 ..._commonDisablingTextShortcuts,
883 ..._iOSDisablingTextShortcuts,
884 const SingleActivator(LogicalKeyboardKey.escape): const DoNothingAndStopPropagationTextIntent(),
885 const SingleActivator(LogicalKeyboardKey.tab): const DoNothingAndStopPropagationTextIntent(),
886 const SingleActivator(LogicalKeyboardKey.tab, shift: true):
887 const DoNothingAndStopPropagationTextIntent(),
888 const SingleActivator(LogicalKeyboardKey.arrowDown, shift: true, alt: true):
889 const DoNothingAndStopPropagationTextIntent(),
890 const SingleActivator(LogicalKeyboardKey.arrowUp, shift: true, alt: true):
891 const DoNothingAndStopPropagationTextIntent(),
892 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true):
893 const DoNothingAndStopPropagationTextIntent(),
894 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true):
895 const DoNothingAndStopPropagationTextIntent(),
896 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, alt: true):
897 const DoNothingAndStopPropagationTextIntent(),
898 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, alt: true):
899 const DoNothingAndStopPropagationTextIntent(),
900 const SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true, meta: true):
901 const DoNothingAndStopPropagationTextIntent(),
902 const SingleActivator(LogicalKeyboardKey.arrowRight, shift: true, meta: true):
903 const DoNothingAndStopPropagationTextIntent(),
904 const SingleActivator(LogicalKeyboardKey.pageUp): const DoNothingAndStopPropagationTextIntent(),
905 const SingleActivator(LogicalKeyboardKey.pageDown):
906 const DoNothingAndStopPropagationTextIntent(),
907 const SingleActivator(LogicalKeyboardKey.end): const DoNothingAndStopPropagationTextIntent(),
908 const SingleActivator(LogicalKeyboardKey.home): const DoNothingAndStopPropagationTextIntent(),
909 const SingleActivator(LogicalKeyboardKey.pageUp, shift: true):
910 const DoNothingAndStopPropagationTextIntent(),
911 const SingleActivator(LogicalKeyboardKey.pageDown, shift: true):
912 const DoNothingAndStopPropagationTextIntent(),
913 const SingleActivator(LogicalKeyboardKey.end, shift: true):
914 const DoNothingAndStopPropagationTextIntent(),
915 const SingleActivator(LogicalKeyboardKey.home, shift: true):
916 const DoNothingAndStopPropagationTextIntent(),
917 const SingleActivator(LogicalKeyboardKey.end, control: true):
918 const DoNothingAndStopPropagationTextIntent(),
919 const SingleActivator(LogicalKeyboardKey.home, control: true):
920 const DoNothingAndStopPropagationTextIntent(),
921 };
922
923 // Hand backspace/delete events that do not depend on text layout (delete
924 // character and delete to the next word) back to the IME to allow it to
925 // update composing text properly.
926 static const Map<ShortcutActivator, Intent> _iOSDisablingTextShortcuts =
927 <ShortcutActivator, Intent>{
928 SingleActivator(LogicalKeyboardKey.backspace): DoNothingAndStopPropagationTextIntent(),
929 SingleActivator(LogicalKeyboardKey.backspace, shift: true):
930 DoNothingAndStopPropagationTextIntent(),
931 SingleActivator(LogicalKeyboardKey.delete): DoNothingAndStopPropagationTextIntent(),
932 SingleActivator(LogicalKeyboardKey.delete, shift: true):
933 DoNothingAndStopPropagationTextIntent(),
934 SingleActivator(LogicalKeyboardKey.backspace, alt: true, shift: true):
935 DoNothingAndStopPropagationTextIntent(),
936 SingleActivator(LogicalKeyboardKey.backspace, alt: true):
937 DoNothingAndStopPropagationTextIntent(),
938 SingleActivator(LogicalKeyboardKey.delete, alt: true, shift: true):
939 DoNothingAndStopPropagationTextIntent(),
940 SingleActivator(LogicalKeyboardKey.delete, alt: true):
941 DoNothingAndStopPropagationTextIntent(),
942 };
943
944 static Map<ShortcutActivator, Intent> get _shortcuts {
945 return switch (defaultTargetPlatform) {
946 TargetPlatform.android => _androidShortcuts,
947 TargetPlatform.fuchsia => _fuchsiaShortcuts,
948 TargetPlatform.iOS => _iOSShortcuts,
949 TargetPlatform.linux => _linuxShortcuts,
950 TargetPlatform.macOS => _macShortcuts,
951 TargetPlatform.windows => _windowsShortcuts,
952 };
953 }
954
955 Map<ShortcutActivator, Intent>? _getDisablingShortcut() {
956 if (kIsWeb) {
957 switch (defaultTargetPlatform) {
958 case TargetPlatform.linux:
959 return <ShortcutActivator, Intent>{
960 ..._webDisablingTextShortcuts,
961 for (final ShortcutActivator activator in _linuxNumpadShortcuts.keys)
962 activator as SingleActivator: const DoNothingAndStopPropagationTextIntent(),
963 };
964 case TargetPlatform.android:
965 case TargetPlatform.fuchsia:
966 case TargetPlatform.windows:
967 case TargetPlatform.iOS:
968 case TargetPlatform.macOS:
969 return _webDisablingTextShortcuts;
970 }
971 }
972 switch (defaultTargetPlatform) {
973 case TargetPlatform.android:
974 case TargetPlatform.fuchsia:
975 case TargetPlatform.linux:
976 case TargetPlatform.windows:
977 return null;
978 case TargetPlatform.iOS:
979 return _iOSDisablingTextShortcuts;
980 case TargetPlatform.macOS:
981 return _macDisablingTextShortcuts;
982 }
983 }
984
985 @override
986 Widget build(BuildContext context) {
987 Widget result = child;
988 final Map<ShortcutActivator, Intent>? disablingShortcut = _getDisablingShortcut();
989 if (disablingShortcut != null) {
990 // These shortcuts make sure of the following:
991 //
992 // 1. Shortcuts fired when an EditableText is focused are ignored and
993 // forwarded to the platform by the EditableText's Actions, because it
994 // maps DoNothingAndStopPropagationTextIntent to DoNothingAction.
995 // 2. Shortcuts fired when no EditableText is focused will still trigger
996 // _shortcuts assuming DoNothingAndStopPropagationTextIntent is
997 // unhandled elsewhere.
998 result = Shortcuts(
999 debugLabel: '<Web Disabling Text Editing Shortcuts>',
1000 shortcuts: disablingShortcut,
1001 child: result,
1002 );
1003 }
1004 return Shortcuts(
1005 debugLabel: '<Default Text Editing Shortcuts>',
1006 shortcuts: _shortcuts,
1007 child: result,
1008 );
1009 }
1010}
1011
1012/// Maps the selector from NSStandardKeyBindingResponding to the Intent if the
1013/// selector is recognized.
1014Intent? intentForMacOSSelector(String selectorName) {
1015 const Map<String, Intent> selectorToIntent = <String, Intent>{
1016 'deleteBackward:': DeleteCharacterIntent(forward: false),
1017 'deleteWordBackward:': DeleteToNextWordBoundaryIntent(forward: false),
1018 'deleteToBeginningOfLine:': DeleteToLineBreakIntent(forward: false),
1019 'deleteForward:': DeleteCharacterIntent(forward: true),
1020 'deleteWordForward:': DeleteToNextWordBoundaryIntent(forward: true),
1021 'deleteToEndOfLine:': DeleteToLineBreakIntent(forward: true),
1022
1023 'moveLeft:': ExtendSelectionByCharacterIntent(forward: false, collapseSelection: true),
1024 'moveRight:': ExtendSelectionByCharacterIntent(forward: true, collapseSelection: true),
1025 'moveForward:': ExtendSelectionByCharacterIntent(forward: true, collapseSelection: true),
1026 'moveBackward:': ExtendSelectionByCharacterIntent(forward: false, collapseSelection: true),
1027
1028 'moveUp:': ExtendSelectionVerticallyToAdjacentLineIntent(
1029 forward: false,
1030 collapseSelection: true,
1031 ),
1032 'moveDown:': ExtendSelectionVerticallyToAdjacentLineIntent(
1033 forward: true,
1034 collapseSelection: true,
1035 ),
1036
1037 'moveLeftAndModifySelection:': ExtendSelectionByCharacterIntent(
1038 forward: false,
1039 collapseSelection: false,
1040 ),
1041 'moveRightAndModifySelection:': ExtendSelectionByCharacterIntent(
1042 forward: true,
1043 collapseSelection: false,
1044 ),
1045 'moveUpAndModifySelection:': ExtendSelectionVerticallyToAdjacentLineIntent(
1046 forward: false,
1047 collapseSelection: false,
1048 ),
1049 'moveDownAndModifySelection:': ExtendSelectionVerticallyToAdjacentLineIntent(
1050 forward: true,
1051 collapseSelection: false,
1052 ),
1053
1054 'moveWordLeft:': ExtendSelectionToNextWordBoundaryIntent(
1055 forward: false,
1056 collapseSelection: true,
1057 ),
1058 'moveWordRight:': ExtendSelectionToNextWordBoundaryIntent(
1059 forward: true,
1060 collapseSelection: true,
1061 ),
1062 'moveToBeginningOfParagraph:': ExtendSelectionToLineBreakIntent(
1063 forward: false,
1064 collapseSelection: true,
1065 ),
1066 'moveToEndOfParagraph:': ExtendSelectionToLineBreakIntent(
1067 forward: true,
1068 collapseSelection: true,
1069 ),
1070
1071 'moveWordLeftAndModifySelection:': ExtendSelectionToNextWordBoundaryOrCaretLocationIntent(
1072 forward: false,
1073 ),
1074 'moveWordRightAndModifySelection:': ExtendSelectionToNextWordBoundaryOrCaretLocationIntent(
1075 forward: true,
1076 ),
1077 'moveParagraphBackwardAndModifySelection:':
1078 ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent(forward: false),
1079 'moveParagraphForwardAndModifySelection:':
1080 ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent(forward: true),
1081
1082 'moveToLeftEndOfLine:': ExtendSelectionToLineBreakIntent(
1083 forward: false,
1084 collapseSelection: true,
1085 ),
1086 'moveToRightEndOfLine:': ExtendSelectionToLineBreakIntent(
1087 forward: true,
1088 collapseSelection: true,
1089 ),
1090 'moveToBeginningOfDocument:': ExtendSelectionToDocumentBoundaryIntent(
1091 forward: false,
1092 collapseSelection: true,
1093 ),
1094 'moveToEndOfDocument:': ExtendSelectionToDocumentBoundaryIntent(
1095 forward: true,
1096 collapseSelection: true,
1097 ),
1098
1099 'moveToLeftEndOfLineAndModifySelection:': ExpandSelectionToLineBreakIntent(forward: false),
1100 'moveToRightEndOfLineAndModifySelection:': ExpandSelectionToLineBreakIntent(forward: true),
1101 'moveToBeginningOfDocumentAndModifySelection:': ExpandSelectionToDocumentBoundaryIntent(
1102 forward: false,
1103 ),
1104 'moveToEndOfDocumentAndModifySelection:': ExpandSelectionToDocumentBoundaryIntent(
1105 forward: true,
1106 ),
1107
1108 'transpose:': TransposeCharactersIntent(),
1109
1110 'scrollToBeginningOfDocument:': ScrollToDocumentBoundaryIntent(forward: false),
1111 'scrollToEndOfDocument:': ScrollToDocumentBoundaryIntent(forward: true),
1112
1113 'scrollPageUp:': ScrollIntent(direction: AxisDirection.up, type: ScrollIncrementType.page),
1114 'scrollPageDown:': ScrollIntent(direction: AxisDirection.down, type: ScrollIncrementType.page),
1115 'pageUpAndModifySelection:': ExtendSelectionVerticallyToAdjacentPageIntent(
1116 forward: false,
1117 collapseSelection: false,
1118 ),
1119 'pageDownAndModifySelection:': ExtendSelectionVerticallyToAdjacentPageIntent(
1120 forward: true,
1121 collapseSelection: false,
1122 ),
1123
1124 // Escape key when there's no IME selection popup.
1125 'cancelOperation:': DismissIntent(),
1126 // Tab when there's no IME selection.
1127 'insertTab:': NextFocusIntent(),
1128 'insertBacktab:': PreviousFocusIntent(),
1129 };
1130 return selectorToIntent[selectorName];
1131}
1132

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com