Skip to content

Commit f32b6fe

Browse files
authored
Fix cursorColor with an opacity is not respected (#133548)
fixes [`cursorColor` with an opacity is not respected](flutter/flutter#132886) <details> <summary>expand to view the code sample</summary> ```dart import "package:flutter/material.dart"; // import "package:flutter/scheduler.dart"; // final color = Colors.red; const color = Color(0x55ff0000); void main() { // timeDilation = 4; runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @OverRide Widget build(BuildContext context) { return const MaterialApp( debugShowCheckedModeBanner: false, home: Example(), ); } } class Example extends StatefulWidget { const Example({super.key}); @OverRide State<Example> createState() => _ExampleState(); } class _ExampleState extends State<Example> { late FocusNode _focusNode; late TextEditingController _controller; @OverRide void initState() { super.initState(); _focusNode = FocusNode(); _controller = TextEditingController(text: 'Hello World'); } @OverRide void dispose() { _focusNode.dispose(); _controller.dispose(); super.dispose(); } @OverRide Widget build(BuildContext context) { const bool cursorOpacityAnimates = false; double cursorWidth = 6; return Scaffold( body: Center( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 16, ), child: Column( children: <Widget>[ const Spacer(), const Text('EditableText'), const SizedBox(height: 8), InputDecorator( decoration: InputDecoration( border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), child: EditableText( cursorColor: color, cursorWidth: cursorWidth, cursorOpacityAnimates: cursorOpacityAnimates, focusNode: _focusNode, controller: _controller, style: Theme.of(context).textTheme.bodyLarge!, backgroundCursorColor: Colors.amber, onSubmitted: (String value) { // Add your code here. }, ), ), const Spacer(), const Text('TextField'), const SizedBox(height: 8), TextField( cursorColor: color, cursorWidth: cursorWidth, cursorOpacityAnimates: cursorOpacityAnimates, controller: _controller, focusNode: _focusNode, onSubmitted: (String value) { // Add your code here. }, ), const Spacer(), ], ), ), ), ); } } ``` </details> ### Before ![Screenshot 2023-08-29 at 14 57 57](https://github.com/flutter/flutter/assets/48603081/cd55bb74-23b8-4980-915d-f13dee22a50f) ### After ![Screenshot 2023-08-29 at 14 58 20](https://github.com/flutter/flutter/assets/48603081/c94af4e3-f24b-44e7-bbed-7c6c21e90f2a)
1 parent 8128b2e commit f32b6fe

File tree

2 files changed

+30
-2
lines changed

2 files changed

+30
-2
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2219,7 +2219,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
22192219
@override
22202220
bool get wantKeepAlive => widget.focusNode.hasFocus;
22212221

2222-
Color get _cursorColor => widget.cursorColor.withOpacity(_cursorBlinkOpacityController.value);
2222+
Color get _cursorColor {
2223+
final double effectiveOpacity = math.min(widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value);
2224+
return widget.cursorColor.withOpacity(effectiveOpacity);
2225+
}
22232226

22242227
@override
22252228
bool get cutEnabled {
@@ -3873,7 +3876,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
38733876
}
38743877

38753878
void _onCursorColorTick() {
3876-
renderEditable.cursorColor = widget.cursorColor.withOpacity(_cursorBlinkOpacityController.value);
3879+
final double effectiveOpacity = math.min(widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value);
3880+
renderEditable.cursorColor = widget.cursorColor.withOpacity(effectiveOpacity);
38773881
_cursorVisibilityNotifier.value = widget.showCursor && _cursorBlinkOpacityController.value > 0;
38783882
}
38793883

packages/flutter/test/widgets/editable_text_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16657,6 +16657,30 @@ testWidgets('Floating cursor ending with selection', (WidgetTester tester) async
1665716657
expect(calls, equals(kIsWeb ? 0 : 2));
1665816658
});
1665916659
});
16660+
16661+
testWidgets('Cursor color with an opacity is respected', (WidgetTester tester) async {
16662+
final GlobalKey key = GlobalKey();
16663+
const double opacity = 0.55;
16664+
await tester.pumpWidget(
16665+
MaterialApp(
16666+
home: EditableText(
16667+
key: key,
16668+
cursorColor: cursorColor.withOpacity(opacity),
16669+
backgroundCursorColor: Colors.grey,
16670+
controller: TextEditingController(text: 'blah blah'),
16671+
focusNode: focusNode,
16672+
style: textStyle,
16673+
),
16674+
),
16675+
);
16676+
16677+
// Tap to show the cursor.
16678+
await tester.tap(find.byKey(key));
16679+
await tester.pumpAndSettle();
16680+
16681+
final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
16682+
expect(state.renderEditable.cursorColor, cursorColor.withOpacity(opacity));
16683+
});
1666016684
}
1666116685

1666216686
class UnsettableController extends TextEditingController {

0 commit comments

Comments
 (0)