Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c411065

Browse files
Fix selection not deselected when TextField loses focus (#103424)
1 parent 594d524 commit c411065

File tree

5 files changed

+126
-6
lines changed

5 files changed

+126
-6
lines changed

packages/flutter/lib/src/widgets/editable_text.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,8 +3253,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
32533253
assert(debugCheckHasMediaQuery(context));
32543254
super.build(context); // See AutomaticKeepAliveClientMixin.
32553255

3256-
final Color? effectiveSelectionColor = widget.selectionColor ?? DefaultSelectionStyle.of(context).selectionColor;
3257-
32583256
final TextSelectionControls? controls = widget.selectionControls;
32593257
return MouseRegion(
32603258
cursor: widget.mouseCursor ?? SystemMouseCursors.text,
@@ -3316,7 +3314,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
33163314
minLines: widget.minLines,
33173315
expands: widget.expands,
33183316
strutStyle: widget.strutStyle,
3319-
selectionColor: effectiveSelectionColor,
3317+
selectionColor: widget.selectionColor,
33203318
textScaleFactor: widget.textScaleFactor ?? MediaQuery.textScaleFactorOf(context),
33213319
textAlign: widget.textAlign,
33223320
textDirection: _textDirection,

packages/flutter/test/cupertino/text_field_test.dart

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,63 @@ void main() {
433433
},
434434
);
435435

436+
testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async {
437+
// Regression test for https://github.com/flutter/flutter/issues/103341.
438+
final Key key1 = UniqueKey();
439+
final Key key2 = UniqueKey();
440+
final TextEditingController controller1 = TextEditingController();
441+
const Color selectionColor = Colors.orange;
442+
const Color cursorColor = Colors.red;
443+
444+
await tester.pumpWidget(
445+
CupertinoApp(
446+
home: Center(
447+
child: DefaultSelectionStyle(
448+
selectionColor: selectionColor,
449+
cursorColor: cursorColor,
450+
child: Column(
451+
children: <Widget>[
452+
CupertinoTextField(
453+
key: key1,
454+
controller: controller1,
455+
),
456+
CupertinoTextField(key: key2),
457+
],
458+
),
459+
),
460+
),
461+
),
462+
);
463+
464+
const TextSelection selection = TextSelection(baseOffset: 0, extentOffset: 4);
465+
final EditableTextState state1 = tester.state<EditableTextState>(find.byType(EditableText).first);
466+
final EditableTextState state2 = tester.state<EditableTextState>(find.byType(EditableText).last);
467+
468+
await tester.tap(find.byKey(key1));
469+
await tester.enterText(find.byKey(key1), 'abcd');
470+
await tester.pump();
471+
472+
await tester.tap(find.byKey(key2));
473+
await tester.enterText(find.byKey(key2), 'dcba');
474+
await tester.pump();
475+
476+
// Focus and selection is active on first TextField, so the second TextFields
477+
// selectionColor should be dropped.
478+
await tester.tap(find.byKey(key1));
479+
controller1.selection = const TextSelection(baseOffset: 0, extentOffset: 4);
480+
await tester.pump();
481+
expect(controller1.selection, selection);
482+
expect(state1.widget.selectionColor, selectionColor);
483+
expect(state2.widget.selectionColor, null);
484+
485+
// Focus and selection is active on second TextField, so the first TextFields
486+
// selectionColor should be dropped.
487+
await tester.tap(find.byKey(key2));
488+
await tester.pump();
489+
expect(state1.widget.selectionColor, null);
490+
expect(state2.widget.selectionColor, selectionColor);
491+
});
492+
436493
testWidgets(
437494
'multi-lined text fields are intrinsically taller no-strut',
438495
(WidgetTester tester) async {

packages/flutter/test/material/text_field_test.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4198,6 +4198,61 @@ void main() {
41984198
feedback.dispose();
41994199
});
42004200

4201+
testWidgets('Text field drops selection color when losing focus', (WidgetTester tester) async {
4202+
// Regression test for https://github.com/flutter/flutter/issues/103341.
4203+
final Key key1 = UniqueKey();
4204+
final Key key2 = UniqueKey();
4205+
final TextEditingController controller1 = TextEditingController();
4206+
const Color selectionColor = Colors.orange;
4207+
const Color cursorColor = Colors.red;
4208+
4209+
await tester.pumpWidget(
4210+
overlay(
4211+
child: DefaultSelectionStyle(
4212+
selectionColor: selectionColor,
4213+
cursorColor: cursorColor,
4214+
child: Column(
4215+
children: <Widget>[
4216+
TextField(
4217+
key: key1,
4218+
controller: controller1,
4219+
),
4220+
TextField(key: key2),
4221+
],
4222+
),
4223+
),
4224+
),
4225+
);
4226+
4227+
const TextSelection selection = TextSelection(baseOffset: 0, extentOffset: 4);
4228+
final EditableTextState state1 = tester.state<EditableTextState>(find.byType(EditableText).first);
4229+
final EditableTextState state2 = tester.state<EditableTextState>(find.byType(EditableText).last);
4230+
4231+
await tester.tap(find.byKey(key1));
4232+
await tester.enterText(find.byKey(key1), 'abcd');
4233+
await tester.pump();
4234+
4235+
await tester.tap(find.byKey(key2));
4236+
await tester.enterText(find.byKey(key2), 'dcba');
4237+
await tester.pump();
4238+
4239+
// Focus and selection is active on first TextField, so the second TextFields
4240+
// selectionColor should be dropped.
4241+
await tester.tap(find.byKey(key1));
4242+
controller1.selection = const TextSelection(baseOffset: 0, extentOffset: 4);
4243+
await tester.pump();
4244+
expect(controller1.selection, selection);
4245+
expect(state1.widget.selectionColor, selectionColor);
4246+
expect(state2.widget.selectionColor, null);
4247+
4248+
// Focus and selection is active on second TextField, so the first TextFields
4249+
// selectionColor should be dropped.
4250+
await tester.tap(find.byKey(key2));
4251+
await tester.pump();
4252+
expect(state1.widget.selectionColor, null);
4253+
expect(state2.widget.selectionColor, selectionColor);
4254+
});
4255+
42014256
testWidgets('Selection is consistent with text length', (WidgetTester tester) async {
42024257
final TextEditingController controller = TextEditingController();
42034258

packages/flutter/test/material/theme_test.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ void main() {
4848
});
4949

5050
testWidgets('Theme overrides selection style', (WidgetTester tester) async {
51+
final Key key = UniqueKey();
5152
const Color defaultSelectionColor = Color(0x11111111);
5253
const Color defaultCursorColor = Color(0x22222222);
5354
const Color themeSelectionColor = Color(0x33333333);
@@ -66,7 +67,9 @@ void main() {
6667
cursorColor: themeCursorColor,
6768
),
6869
),
69-
child: const TextField(),
70+
child: TextField(
71+
key: key,
72+
),
7073
)
7174
),
7275
),
@@ -83,6 +86,12 @@ void main() {
8386
child.visitChildren(recursiveFinder);
8487
}
8588
root.visitChildren(recursiveFinder);
89+
90+
// Focus text field so it has a selection color. The selection color is null
91+
// on an unfocused text field.
92+
await tester.tap(find.byKey(key));
93+
await tester.pump();
94+
8695
expect(renderEditable.selectionColor, themeSelectionColor);
8796
expect(tester.widget<EditableText>(find.byType(EditableText)).cursorColor, themeCursorColor);
8897
});

packages/flutter/test/widgets/editable_text_test.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,8 @@ void main() {
660660
expect(focusNode.hasFocus, isFalse);
661661
});
662662

663-
testWidgets('use DefaultSelectionStyle for selection color', (WidgetTester tester) async {
663+
testWidgets('EditableText does not derive selection color from DefaultSelectionStyle', (WidgetTester tester) async {
664+
// Regression test for https://github.com/flutter/flutter/issues/103341.
664665
const TextEditingValue value = TextEditingValue(
665666
text: 'test test',
666667
selection: TextSelection(affinity: TextAffinity.upstream, baseOffset: 5, extentOffset: 7),
@@ -687,7 +688,7 @@ void main() {
687688
),
688689
);
689690
final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
690-
expect(state.renderEditable.selectionColor, selectionColor);
691+
expect(state.renderEditable.selectionColor, null);
691692
});
692693

693694
testWidgets('visiblePassword keyboard is requested when set explicitly', (WidgetTester tester) async {

0 commit comments

Comments
 (0)