Make EditableText respect MediaQuery.boldTextOf (#122754)
diff --git a/packages/flutter/lib/src/material/selectable_text.dart b/packages/flutter/lib/src/material/selectable_text.dart
index 0a8e4bf..272e552 100644
--- a/packages/flutter/lib/src/material/selectable_text.dart
+++ b/packages/flutter/lib/src/material/selectable_text.dart
@@ -677,9 +677,6 @@
if (effectiveTextStyle == null || effectiveTextStyle.inherit) {
effectiveTextStyle = defaultTextStyle.style.merge(widget.style ?? _controller._textSpan.style);
}
- if (MediaQuery.boldTextOf(context)) {
- effectiveTextStyle = effectiveTextStyle.merge(const TextStyle(fontWeight: FontWeight.bold));
- }
final Widget child = RepaintBoundary(
child: EditableText(
key: editableTextKey,
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index 5614329..fe30c3b 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -2084,6 +2084,7 @@
AutofillClient get _effectiveAutofillClient => widget.autofillClient ?? this;
late SpellCheckConfiguration _spellCheckConfiguration;
+ late TextStyle _style;
/// Configuration that determines how spell check will be performed.
///
@@ -2589,6 +2590,10 @@
void didChangeDependencies() {
super.didChangeDependencies();
+ _style = MediaQuery.boldTextOf(context)
+ ? widget.style.merge(const TextStyle(fontWeight: FontWeight.bold))
+ : widget.style;
+
final AutofillGroupState? newAutofillGroup = AutofillGroup.maybeOf(context);
if (currentAutofillScope != newAutofillGroup) {
_currentAutofillScope?.unregister(autofillId);
@@ -2682,14 +2687,16 @@
}
if (widget.style != oldWidget.style) {
- final TextStyle style = widget.style;
// The _textInputConnection will pick up the new style when it attaches in
// _openInputConnection.
+ _style = MediaQuery.boldTextOf(context)
+ ? widget.style.merge(const TextStyle(fontWeight: FontWeight.bold))
+ : widget.style;
if (_hasInputConnection) {
_textInputConnection!.setStyle(
- fontFamily: style.fontFamily,
- fontSize: style.fontSize,
- fontWeight: style.fontWeight,
+ fontFamily: _style.fontFamily,
+ fontSize: _style.fontSize,
+ fontWeight: _style.fontWeight,
textDirection: _textDirection,
textAlign: widget.textAlign,
);
@@ -3154,12 +3161,11 @@
: TextInput.attach(this, _effectiveAutofillClient.textInputConfiguration);
_updateSizeAndTransform();
_schedulePeriodicPostFrameCallbacks();
- final TextStyle style = widget.style;
_textInputConnection!
..setStyle(
- fontFamily: style.fontFamily,
- fontSize: style.fontSize,
- fontWeight: style.fontWeight,
+ fontFamily: _style.fontFamily,
+ fontSize: _style.fontSize,
+ fontWeight: _style.fontWeight,
textDirection: _textDirection,
textAlign: widget.textAlign,
)
@@ -3222,13 +3228,12 @@
?? TextInput.attach(this, _effectiveAutofillClient.textInputConfiguration);
_textInputConnection = newConnection;
- final TextStyle style = widget.style;
newConnection
..show()
..setStyle(
- fontFamily: style.fontFamily,
- fontSize: style.fontSize,
- fontWeight: style.fontWeight,
+ fontFamily: _style.fontFamily,
+ fontSize: _style.fontSize,
+ fontWeight: _style.fontWeight,
textDirection: _textDirection,
textAlign: widget.textAlign,
)
@@ -4636,6 +4641,7 @@
/// By default makes text in composing range appear as underlined.
/// Descendants can override this method to customize appearance of text.
TextSpan buildTextSpan() {
+
if (widget.obscureText) {
String text = _value.text;
text = widget.obscuringCharacter * text.length;
@@ -4653,7 +4659,7 @@
text = text.replaceRange(o, o + 1, _value.text.substring(o, o + 1));
}
}
- return TextSpan(style: widget.style, text: text);
+ return TextSpan(style: _style, text: text);
}
if (_placeholderLocation >= 0 && _placeholderLocation <= _value.text.length) {
final List<_ScribblePlaceholder> placeholders = <_ScribblePlaceholder>[];
@@ -4665,7 +4671,7 @@
} else {
placeholders.add(const _ScribblePlaceholder(child: SizedBox.shrink(), size: Size(100.0, 0.0)));
}
- return TextSpan(style: widget.style, children: <InlineSpan>[
+ return TextSpan(style: _style, children: <InlineSpan>[
TextSpan(text: _value.text.substring(0, placeholderLocation)),
...placeholders,
TextSpan(text: _value.text.substring(placeholderLocation)),
@@ -4684,7 +4690,7 @@
return buildTextSpanWithSpellCheckSuggestions(
_value,
composingRegionOutOfRange,
- widget.style,
+ _style,
_spellCheckConfiguration.misspelledTextStyle!,
spellCheckResults!,
);
@@ -4693,7 +4699,7 @@
// Read only mode should not paint text composing.
return widget.controller.buildTextSpan(
context: context,
- style: widget.style,
+ style: _style,
withComposing: withComposing,
);
}
diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart
index ce684b6..9c6678e 100644
--- a/packages/flutter/test/widgets/editable_text_test.dart
+++ b/packages/flutter/test/widgets/editable_text_test.dart
@@ -5374,6 +5374,46 @@
);
});
+ testWidgets('text styling info is sent on show keyboard (bold override)', (WidgetTester tester) async {
+ final List<MethodCall> log = <MethodCall>[];
+ tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ log.add(methodCall);
+ return null;
+ });
+
+ final TextEditingController controller = TextEditingController();
+ await tester.pumpWidget(
+ MediaQuery(
+ data: const MediaQueryData(boldText: true),
+ child: EditableText(
+ textDirection: TextDirection.rtl,
+ controller: controller,
+ focusNode: FocusNode(),
+ style: const TextStyle(
+ fontSize: 20.0,
+ fontFamily: 'Roboto',
+ fontWeight: FontWeight.w600,
+ ),
+ cursorColor: Colors.blue,
+ backgroundCursorColor: Colors.grey,
+ ),
+ ),
+ );
+
+ await tester.showKeyboard(find.byType(EditableText));
+ final MethodCall setStyle = log.firstWhere((MethodCall m) => m.method == 'TextInput.setStyle');
+ expect(
+ setStyle,
+ isMethodCall('TextInput.setStyle', arguments: <String, dynamic>{
+ 'fontSize': 20.0,
+ 'fontFamily': 'Roboto',
+ 'fontWeightIndex': FontWeight.bold.index,
+ 'textAlignIndex': 4,
+ 'textDirectionIndex': 0,
+ }),
+ );
+ });
+
testWidgets('text styling info is sent on style update', (WidgetTester tester) async {
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
late StateSetter setState;
@@ -15519,6 +15559,27 @@
skip: !kIsWeb, // [intended]
);
});
+
+ testWidgets('EditableText respects MediaQuery.boldText', (WidgetTester tester) async {
+ await tester.pumpWidget(Directionality(
+ textDirection: TextDirection.ltr,
+ child: MediaQuery(
+ data: const MediaQueryData(boldText: true),
+ child: EditableText(
+ controller: controller,
+ focusNode: focusNode,
+ style: const TextStyle(fontWeight: FontWeight.normal),
+ cursorColor: Colors.red,
+ backgroundCursorColor: Colors.green,
+ ),
+ ),
+ ));
+
+ controller.text = 'foo';
+ final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
+
+ expect(state.buildTextSpan().style!.fontWeight, FontWeight.bold);
+ });
}
class UnsettableController extends TextEditingController {