Repository: flutter
Issue: Moving cursor while composing should stay in composing region
Labels: a: text input,platform-android,platform-ios,framework,a: internationalization,a: fidelity,P3,team-framework,triaged-framework

When there's an active composing region for a multi-step IME (like for Chinese or Japanese), if the user moves the cursor (aka the caret) around, it should stay clamped within the composing region. This is what iOS and Android do for native text inputs. (With a few exceptions, that is; details below.)

This applies to moving the cursor by tapping inside the text field, and on iOS applies also to using the "floating cursor" feature by long-pressing the space bar and dragging around.

## Steps to Reproduce

1. Go to a text input field in a Flutter app, such as the code sample below, on iOS or Android.
2. Select (for example) a Japanese kana keyboard. Type some text, for example "あかさあかさあかさ". Hit the big "確定" key on iOS, or "enter" key with Gboard on Android, to end composing and confirm your input.
3. Put the cursor in the middle of the text you've typed. Type some more text, for example "たなたな". Leave the input in a still-composing state.
4. Try to move the cursor beyond the composing area:
   * Tap in the left part of the text input, before the "たなたな" composing region.
   * Tap in the right part of the text input, after the composing region.
   * On iOS, long-press the big "確定" key until all the keyboard's keys go blank, then drag far to the left or the right.
5. Observe where the cursor lands.
6. Go to a text input field in a native iOS or Android app, and repeat steps 2-5.


**Expected results:**

Steps 2-5 should produce similar results in Flutter as in a native iOS or Android app.

Specifically: moving far to the left should take the cursor only to the start of the composing region, and moving far to the right should take the cursor only to the end of the composing region.

This behavior is helpful if, for example, you want to get back to the end of the composing region and resume typing there after correcting something in the beginning or middle of the region: it means you can just hastily move the cursor toward the end, without needing to be precise, and it'll go exactly to the end.

**Actual results:**

Moving to a point outside the composing region takes the cursor to that point, and ends composing.

This can be pretty annoying if you wanted to go to the start or end, and you miss by even a little bit: if you weren't done composing, you'll likely have to delete and retype the whole composing region again.

(If you move the cursor somewhere within the composing region, instead of outside it, you'll see a different issue:
* #108016

)

<details>
<summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(DemoApp());
}

class DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(title: "Demo app", home: HomePage());
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Demo app")),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          TextField(maxLines: null),
          ElevatedButton(
              onPressed: () => FocusScope.of(context).unfocus(),
              child: Text('Unfocus'),
          ),
        ],
      ),
    );
  }
}
```

</details>