Unverified Commit a3b7feb8 authored by chunhtai's avatar chunhtai Committed by GitHub

Editable text sends enableInteractiveSelection to text input client (#100649)

* Editable text sends enableInteractiveSelection to text input client

* addressing comments
parent b346a593
......@@ -461,6 +461,7 @@ class TextInputConfiguration {
SmartDashesType? smartDashesType,
SmartQuotesType? smartQuotesType,
this.enableSuggestions = true,
this.enableInteractiveSelection = true,
this.actionLabel,
this.inputAction = TextInputAction.done,
this.keyboardAppearance = Brightness.light,
......@@ -571,6 +572,15 @@ class TextInputConfiguration {
/// {@endtemplate}
final bool enableSuggestions;
/// Whether a user can change its selection.
///
/// This flag only affects iOS VoiceOver. On Android Talkback, the selection
/// change is sent through semantics actions and is directly disabled from
/// the widget side.
///
/// Defaults to true. Cannot be null.
final bool enableInteractiveSelection;
/// What text to display in the text input control's action button.
final String? actionLabel;
......@@ -618,6 +628,7 @@ class TextInputConfiguration {
SmartDashesType? smartDashesType,
SmartQuotesType? smartQuotesType,
bool? enableSuggestions,
bool? enableInteractiveSelection,
String? actionLabel,
TextInputAction? inputAction,
Brightness? keyboardAppearance,
......@@ -634,6 +645,7 @@ class TextInputConfiguration {
smartDashesType: smartDashesType ?? this.smartDashesType,
smartQuotesType: smartQuotesType ?? this.smartQuotesType,
enableSuggestions: enableSuggestions ?? this.enableSuggestions,
enableInteractiveSelection: enableInteractiveSelection ?? this.enableInteractiveSelection,
inputAction: inputAction ?? this.inputAction,
textCapitalization: textCapitalization ?? this.textCapitalization,
keyboardAppearance: keyboardAppearance ?? this.keyboardAppearance,
......@@ -679,6 +691,7 @@ class TextInputConfiguration {
'smartDashesType': smartDashesType.index.toString(),
'smartQuotesType': smartQuotesType.index.toString(),
'enableSuggestions': enableSuggestions,
'enableInteractiveSelection': enableInteractiveSelection,
'actionLabel': actionLabel,
'inputAction': inputAction.toString(),
'textCapitalization': textCapitalization.toString(),
......
......@@ -1387,6 +1387,8 @@ class EditableText extends StatefulWidget {
/// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning}
final bool enableIMEPersonalizedLearning;
bool get _userSelectionEnabled => enableInteractiveSelection && (!readOnly || !obscureText);
// Infer the keyboard type of an `EditableText` if it's not specified.
static TextInputType _inferKeyboardType({
required Iterable<String>? autofillHints,
......@@ -3021,6 +3023,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
smartDashesType: widget.smartDashesType,
smartQuotesType: widget.smartQuotesType,
enableSuggestions: widget.enableSuggestions,
enableInteractiveSelection: widget._userSelectionEnabled,
inputAction: widget.textInputAction ?? (widget.keyboardType == TextInputType.multiline
? TextInputAction.newline
: TextInputAction.done
......@@ -3327,7 +3330,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
selectionHeightStyle: widget.selectionHeightStyle,
selectionWidthStyle: widget.selectionWidthStyle,
paintCursorAboveText: widget.paintCursorAboveText,
enableInteractiveSelection: widget.enableInteractiveSelection && (!widget.readOnly || !widget.obscureText),
enableInteractiveSelection: widget._userSelectionEnabled,
textSelectionDelegate: this,
devicePixelRatio: _devicePixelRatio,
promptRectRange: _currentPromptRectRange,
......
......@@ -569,6 +569,58 @@ void main() {
expect(tester.testTextInput.setClientArgs!['inputAction'], equals('TextInputAction.newline'));
});
testWidgets('EditableText sends enableInteractiveSelection to config', (WidgetTester tester) async {
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: FocusScope(
node: focusScopeNode,
autofocus: true,
child: EditableText(
enableInteractiveSelection: true,
controller: controller,
backgroundCursorColor: Colors.grey,
focusNode: focusNode,
keyboardType: TextInputType.multiline,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
);
EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
expect(state.textInputConfiguration.enableInteractiveSelection, isTrue);
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(),
child: Directionality(
textDirection: TextDirection.ltr,
child: FocusScope(
node: focusScopeNode,
autofocus: true,
child: EditableText(
enableInteractiveSelection: false,
controller: controller,
backgroundCursorColor: Colors.grey,
focusNode: focusNode,
keyboardType: TextInputType.multiline,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
);
state = tester.state<EditableTextState>(find.byType(EditableText));
expect(state.textInputConfiguration.enableInteractiveSelection, isFalse);
});
testWidgets('selection persists when unfocused', (WidgetTester tester) async {
const TextEditingValue value = TextEditingValue(
text: 'test test',
......
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