Justin McCandless 1cd946ee31
Text editing inside of Transformed.scale (#146019)
Fixes bugs in the text selection positioning calculations so that they work even when the field is scaled. In many cases, we were simply translating things around without applying the proper localToGlobal (or vice versa) transform.

| Before | After |
| --- | --- |
| <img src="https://github.com/flutter/flutter/assets/389558/a5a45472-98c5-4cdf-b382-218971fd9404" /> | <img src="https://github.com/flutter/flutter/assets/389558/f396a1af-2546-4e38-a9d9-6c6edfa38d94" /> |

Partial fix for: https://github.com/flutter/flutter/issues/144685
It looks like there are other problems where transforms aren't applied properly. Putting a transform at the root of the application, above MaterialApp, will expose more problems.

<details>

<summary>Sample code</summary>

```dart
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';

void main() => runApp(const _App());

class _App extends StatelessWidget {
  const _App();

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: _Home());
  }
}

class _Home extends StatefulWidget {
  const _Home();

  @override
  State<_Home> createState() => _HomeState();
}

class _HomeState extends State<_Home> {
  final _controller = WebViewController();
  final TextEditingController textEditingController = TextEditingController(
    text: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
  );
  final OverlayPortalController overlayPortalController = OverlayPortalController();

  @override
  void initState() {
    super.initState();
    _controller
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(Uri.https('api.flutter.dev'));
  }

  @override
  Widget build(BuildContext context) {
    overlayPortalController.show();
    return Scaffold(
      appBar: AppBar(
        title: const Text('Scaled WebView Tester'),
      ),
      body: Stack(
        children: <Widget>[
          Transform.scale(
            alignment: Alignment.topLeft,
            scale: 0.5,
            child: TextField(
              controller: textEditingController,
              maxLines: null,
            ),
          ),
          OverlayPortal(
            controller: overlayPortalController,
            overlayChildBuilder: (BuildContext context) {
              return Positioned(
                top: 0.0,
                left: 0.0,
                child: SizedBox(
                  height: 1000,
                  width: 1000,
                  child: Stack(
                    children: <Widget>[
                      Positioned(
                        top: 90.0,
                        left: 0.0,
                        child: Container(
                          height: 1.0,
                          width: 1000,
                          color: Colors.blue,
                        ),
                      ),
                      Positioned(
                        top: 102.0,
                        left: 0.0,
                        child: Container(
                          height: 1.0,
                          width: 1000,
                          color: Colors.blue,
                        ),
                      ),
                    ],
                  ),
                ),
              );
            },
          ),
        ],
      ),
    );
  }
}
```

</details>
2024-04-08 22:01:05 +00:00
..
2024-04-08 18:48:19 +00:00