Unverified Commit f32b6fed authored by Taha Tesser's avatar Taha Tesser Committed by GitHub

Fix `cursorColor` with an opacity is not respected (#133548)

fixes [`cursorColor` with an opacity  is not respected](https://github.com/flutter/flutter/issues/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)
parent 8128b2e2
......@@ -2219,7 +2219,10 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
@override
bool get wantKeepAlive => widget.focusNode.hasFocus;
Color get _cursorColor => widget.cursorColor.withOpacity(_cursorBlinkOpacityController.value);
Color get _cursorColor {
final double effectiveOpacity = math.min(widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value);
return widget.cursorColor.withOpacity(effectiveOpacity);
}
@override
bool get cutEnabled {
......@@ -3873,7 +3876,8 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
}
void _onCursorColorTick() {
renderEditable.cursorColor = widget.cursorColor.withOpacity(_cursorBlinkOpacityController.value);
final double effectiveOpacity = math.min(widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value);
renderEditable.cursorColor = widget.cursorColor.withOpacity(effectiveOpacity);
_cursorVisibilityNotifier.value = widget.showCursor && _cursorBlinkOpacityController.value > 0;
}
......
......@@ -16657,6 +16657,30 @@ testWidgets('Floating cursor ending with selection', (WidgetTester tester) async
expect(calls, equals(kIsWeb ? 0 : 2));
});
});
testWidgets('Cursor color with an opacity is respected', (WidgetTester tester) async {
final GlobalKey key = GlobalKey();
const double opacity = 0.55;
await tester.pumpWidget(
MaterialApp(
home: EditableText(
key: key,
cursorColor: cursorColor.withOpacity(opacity),
backgroundCursorColor: Colors.grey,
controller: TextEditingController(text: 'blah blah'),
focusNode: focusNode,
style: textStyle,
),
),
);
// Tap to show the cursor.
await tester.tap(find.byKey(key));
await tester.pumpAndSettle();
final EditableTextState state = tester.state<EditableTextState>(find.byType(EditableText));
expect(state.renderEditable.cursorColor, cursorColor.withOpacity(opacity));
});
}
class UnsettableController extends TextEditingController {
......
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