Unverified Commit ac66b295 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Docs on the interaction between Shortcuts and text input (#144328)

I was talking with @tvolkert about the complex behavior of Shortcuts when a text field is focused.  I created [this dartpad](https://dartpad.dev/?id=0b5c08fa85637422baa84927b7f1ee5f) to illustrate the problem, which shows a key being stolen from a text field by Shortcuts, and how to prevent that using DoNothingAndStopPropagationIntent.

This PR adds a section in the docs explaining how all of this works and how to override this "stealing" problem.
parent 835112de
......@@ -25,6 +25,8 @@ import 'text_editing_intents.dart';
/// cause CJK input methods to discard more text than they should when the
/// backspace key is pressed during text composition on iOS.
///
/// {@macro flutter.widgets.editableText.shortcutsAndTextInput}
///
/// {@tool snippet}
///
/// This example shows how to use an additional [Shortcuts] widget to override
......
......@@ -631,9 +631,10 @@ class _DiscreteKeyFrameSimulation extends Simulation {
/// This widget provides default [Action]s for handling common text editing
/// [Intent]s such as deleting, copying and pasting in the text field. These
/// [Action]s can be directly invoked using [Actions.invoke] or the
/// [Actions.maybeInvoke] method. The default text editing keyboard [Shortcuts]
/// also use these [Intent]s and [Action]s to perform the text editing
/// operations they are bound to.
/// [Actions.maybeInvoke] method. The default text editing keyboard [Shortcuts],
/// typically declared in [DefaultTextEditingShortcuts], also use these
/// [Intent]s and [Action]s to perform the text editing operations they are
/// bound to.
///
/// The default handling of a specific [Intent] can be overridden by placing an
/// [Actions] widget above this widget. See the [Action] class and the
......@@ -683,6 +684,40 @@ class _DiscreteKeyFrameSimulation extends Simulation {
/// | [CopySelectionTextIntent] | Copies or cuts the selected text into the clipboard |
/// | [PasteTextIntent] | Inserts the current text in the clipboard after the caret location, or replaces the selected text if the selection is not collapsed. |
///
/// ## Text Editing [Shortcuts]
///
/// It's also possible to directly remap keyboard shortcuts to new [Intent]s by
/// inserting a [Shortcuts] widget above this in the widget tree. When using
/// [WidgetsApp], the large set of default text editing keyboard shortcuts are
/// declared near the top of the widget tree in [DefaultTextEditingShortcuts],
/// and any [Shortcuts] widget between it and this [EditableText] will override
/// those defaults.
///
/// {@template flutter.widgets.editableText.shortcutsAndTextInput}
/// ### Interactions Between [Shortcuts] and Text Input
///
/// Shortcuts prevent text input fields from receiving their keystrokes as text
/// input. For example, placing a [Shortcuts] widget in the widget tree above
/// a text input field and creating a shortcut for [LogicalKeyboardKey.keyA]
/// will prevent the field from receiving that key as text input. In other
/// words, typing key "A" into the field will trigger the shortcut and will not
/// insert a letter "a" into the field.
///
/// This happens because of the way that key strokes are handled in Flutter.
/// When a keystroke is received in Flutter's engine, it first gives the
/// framework the opportunity to handle it as a raw key event through
/// [SystemChannels.keyEvent]. This is what [Shortcuts] listens to indirectly
/// through its [FocusNode]. If it is not handled, then it will proceed to try
/// handling it as text input through [SystemChannels.textInput], which is what
/// [EditableTextState] listens to through [TextInputClient].
///
/// This behavior, where a shortcut prevents text input into some field, can be
/// overridden by using another [Shortcuts] widget lower in the widget tree and
/// mapping the desired key stroke(s) to [DoNothingAndStopPropagationIntent].
/// The key event will be reported as unhandled by the framework and will then
/// be sent as text input as usual.
/// {@endtemplate}
///
/// ## Gesture Events Handling
///
/// When [rendererIgnoresPointer] is false (the default), this widget provides
......
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