Unverified Commit c411065b authored by Renzo Olivares's avatar Renzo Olivares Committed by GitHub

Fix selection not deselected when TextField loses focus (#103424)

parent 594d524a
......@@ -3253,8 +3253,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
assert(debugCheckHasMediaQuery(context));
super.build(context); // See AutomaticKeepAliveClientMixin.
final Color? effectiveSelectionColor = widget.selectionColor ?? DefaultSelectionStyle.of(context).selectionColor;
final TextSelectionControls? controls = widget.selectionControls;
return MouseRegion(
cursor: widget.mouseCursor ?? SystemMouseCursors.text,
......@@ -3316,7 +3314,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
minLines: widget.minLines,
expands: widget.expands,
strutStyle: widget.strutStyle,
selectionColor: effectiveSelectionColor,
selectionColor: widget.selectionColor,
textScaleFactor: widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
textAlign: widget.textAlign,
textDirection: _textDirection,
......
......@@ -433,6 +433,63 @@ void main() {
},
);
testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/103341.
final Key key1 = UniqueKey();
final Key key2 = UniqueKey();
final TextEditingController controller1 = TextEditingController();
const Color selectionColor = Colors.orange;
const Color cursorColor = Colors.red;
await tester.pumpWidget(
CupertinoApp(
home: Center(
child: DefaultSelectionStyle(
selectionColor: selectionColor,
cursorColor: cursorColor,
child: Column(
children: <Widget>[
CupertinoTextField(
key: key1,
controller: controller1,
),
CupertinoTextField(key: key2),
],
),
),
),
),
);
const TextSelection selection = TextSelection(baseOffset: 0, extentOffset: 4);
final EditableTextState state1 = tester.state<EditableTextState>(find.byType(EditableText).first);
final EditableTextState state2 = tester.state<EditableTextState>(find.byType(EditableText).last);
await tester.tap(find.byKey(key1));
await tester.enterText(find.byKey(key1), 'abcd');
await tester.pump();
await tester.tap(find.byKey(key2));
await tester.enterText(find.byKey(key2), 'dcba');
await tester.pump();
// Focus and selection is active on first TextField, so the second TextFields
// selectionColor should be dropped.
await tester.tap(find.byKey(key1));
controller1.selection = const TextSelection(baseOffset: 0, extentOffset: 4);
await tester.pump();
expect(controller1.selection, selection);
expect(state1.widget.selectionColor, selectionColor);
expect(state2.widget.selectionColor, null);
// Focus and selection is active on second TextField, so the first TextFields
// selectionColor should be dropped.
await tester.tap(find.byKey(key2));
await tester.pump();
expect(state1.widget.selectionColor, null);
expect(state2.widget.selectionColor, selectionColor);
});
testWidgets(
'multi-lined text fields are intrinsically taller no-strut',
(WidgetTester tester) async {
......
......@@ -4198,6 +4198,61 @@ void main() {
feedback.dispose();
});
testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/103341.
final Key key1 = UniqueKey();
final Key key2 = UniqueKey();
final TextEditingController controller1 = TextEditingController();
const Color selectionColor = Colors.orange;
const Color cursorColor = Colors.red;
await tester.pumpWidget(
overlay(
child: DefaultSelectionStyle(
selectionColor: selectionColor,
cursorColor: cursorColor,
child: Column(
children: <Widget>[
TextField(
key: key1,
controller: controller1,
),
TextField(key: key2),
],
),
),
),
);
const TextSelection selection = TextSelection(baseOffset: 0, extentOffset: 4);
final EditableTextState state1 = tester.state<EditableTextState>(find.byType(EditableText).first);
final EditableTextState state2 = tester.state<EditableTextState>(find.byType(EditableText).last);
await tester.tap(find.byKey(key1));
await tester.enterText(find.byKey(key1), 'abcd');
await tester.pump();
await tester.tap(find.byKey(key2));
await tester.enterText(find.byKey(key2), 'dcba');
await tester.pump();
// Focus and selection is active on first TextField, so the second TextFields
// selectionColor should be dropped.
await tester.tap(find.byKey(key1));
controller1.selection = const TextSelection(baseOffset: 0, extentOffset: 4);
await tester.pump();
expect(controller1.selection, selection);
expect(state1.widget.selectionColor, selectionColor);
expect(state2.widget.selectionColor, null);
// Focus and selection is active on second TextField, so the first TextFields
// selectionColor should be dropped.
await tester.tap(find.byKey(key2));
await tester.pump();
expect(state1.widget.selectionColor, null);
expect(state2.widget.selectionColor, selectionColor);
});
testWidgets('Selection is consistent with text length', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
......
......@@ -48,6 +48,7 @@ void main() {
});
testWidgets('Theme overrides selection style', (WidgetTester tester) async {
final Key key = UniqueKey();
const Color defaultSelectionColor = Color(0x11111111);
const Color defaultCursorColor = Color(0x22222222);
const Color themeSelectionColor = Color(0x33333333);
......@@ -66,7 +67,9 @@ void main() {
cursorColor: themeCursorColor,
),
),
child: const TextField(),
child: TextField(
key: key,
),
)
),
),
......@@ -83,6 +86,12 @@ void main() {
child.visitChildren(recursiveFinder);
}
root.visitChildren(recursiveFinder);
// Focus text field so it has a selection color. The selection color is null
// on an unfocused text field.
await tester.tap(find.byKey(key));
await tester.pump();
expect(renderEditable.selectionColor, themeSelectionColor);
expect(tester.widget<EditableText>(find.byType(EditableText)).cursorColor, themeCursorColor);
});
......
......@@ -660,7 +660,8 @@ void main() {
expect(focusNode.hasFocus, isFalse);
});
testWidgets('use DefaultSelectionStyle for selection color', (WidgetTester tester) async {
testWidgets('EditableText does not derive selection color from DefaultSelectionStyle', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/103341.
const TextEditingValue value = TextEditingValue(
text: 'test test',
selection: TextSelection(affinity: TextAffinity.upstream, baseOffset: 5, extentOffset: 7),
......@@ -687,7 +688,7 @@ void main() {
),
);
final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
expect(state.renderEditable.selectionColor, selectionColor);
expect(state.renderEditable.selectionColor, null);
});
testWidgets('visiblePassword keyboard is requested when set explicitly', (WidgetTester tester) async {
......
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