Repository: flutter
Issue: [Windows][Web] Unexpected deltas when using Japanese keyboard
Labels: a: text input,framework,a: internationalization,platform-web,has reproducible steps,P2,found in release: 3.16,found in release: 3.18,team-text-input,triaged-text-input

### Is there an existing issue for this?

- [X] I have searched the [existing issues](https://github.com/flutter/flutter/issues)
- [X] I have read the [guide to filing a bug](https://flutter.dev/docs/resources/bug-reports)

### Steps to reproduce

1. Switch to Japanese keyboard (Hiragana)
2. Run the sample app on windows web (using chrome)
3. Tap  "Attach to IME"
4. Check if the keyboard is still set to Hiragana, if not, select Hiragana again
5. Type the letter "k" 

### Expected results

The resulting text is "ｋWelcome to SuperEditor"

### Actual results

The resulting text is "ｋWeｋlcome to SuperEditor"

### Code sample

<details><summary>Code sample</summary>

```dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {
  runApp(
    const MaterialApp(
      home: Scaffold(
        body: TextInputExample(),
      ),
    ),
  );
}

class TextInputExample extends StatefulWidget {
  const TextInputExample({Key? key}) : super(key: key);

  @override
  State<TextInputExample> createState() => _TextInputExampleState();
}

class _TextInputExampleState extends State<TextInputExample> implements DeltaTextInputClient {
  TextInputConnection? _inputConnection;
  TextEditingValue _currentEditingValue = TextEditingValue(
    text: '. Welcome to SuperEditor',
    selection: TextSelection.collapsed(offset: 2),
  );

  FocusNode _focusNode = FocusNode();

  @override
  void dispose() {
    _focusNode.dispose();
    super.dispose();
  }

  @override
  void updateEditingValueWithDeltas(List<TextEditingDelta> textEditingDeltas) {
    print('Received ${textEditingDeltas.length} deltas');
    TextEditingValue newEditingValue = _currentEditingValue;

    for (final delta in textEditingDeltas) {
      print(delta);
      newEditingValue = delta.apply(newEditingValue);
    }

    TextEditingValue expectedImeValue = newEditingValue;

    if (newEditingValue.text.startsWith(". ")) {
      // Simulate the editor doing some work that results in an edit value
      // that differs from what the IME thinks it is.
      newEditingValue = newEditingValue.copyWith(text: newEditingValue.text.substring(2));
    }

    if (expectedImeValue != newEditingValue) {
      // Our editing value differs from the IME editing value.
      // Sync again.
      _inputConnection!.setEditingState(newEditingValue);
    }

    setState(() {
      _currentEditingValue = newEditingValue;
    });
  }

  void _run() {
    _detach();
    _attach();
  }

  void _attach() {
    if (_inputConnection != null) {
      return;
    }
    _inputConnection = TextInput.attach(
      this,
      const TextInputConfiguration(
        enableDeltaModel: true,
        inputType: TextInputType.multiline,
        textCapitalization: TextCapitalization.sentences,
        inputAction: TextInputAction.newline,
        keyboardAppearance: Brightness.light,
      ),
    );
    _inputConnection!.show();
    _inputConnection!.setEditingState(_currentEditingValue);
  }

  void _detach() {
    _inputConnection?.close();
    _inputConnection = null;
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          Focus(
            focusNode: _focusNode,
            autofocus: true,
            child: Text(
              _currentEditingValue.toString(),
              textAlign: TextAlign.center,
            ),
          ),
          ElevatedButton(
            onPressed: _run,
            child: const Text('Attach to IME'),
          ),
        ],
      ),
    );
  }

  @override
  void connectionClosed() {}

  @override
  AutofillScope? get currentAutofillScope => null;

  @override
  TextEditingValue? get currentTextEditingValue => null;

  @override
  void insertTextPlaceholder(Size size) {}

  @override
  void performPrivateCommand(String action, Map<String, dynamic> data) {}

  @override
  void removeTextPlaceholder() {}

  @override
  void showAutocorrectionPromptRect(int start, int end) {}

  @override
  void showToolbar() {}

  @override
  void updateEditingValue(TextEditingValue value) {}

  @override
  void updateFloatingCursor(RawFloatingCursorPoint point) {}

  @override
  void didChangeInputControl(TextInputControl? oldControl, TextInputControl? newControl) {}

  @override
  void insertContent(KeyboardInsertedContent content) {}

  @override
  void performSelector(String selectorName) {}

  @override
  void performAction(TextInputAction action) {}
}


```

</details>


### Screenshots or Video

<details>
<summary>Screenshots / Video demonstration</summary>

[Upload media here]

</details>


### Logs

<details><summary>Logs</summary>

```console
Received 1 deltas
TextEditingDeltaInsertion#476c4(oldText: . Welcome to SuperEditor, textInserted: ｋ, insertionOffset: 2, selection: TextSelection.collapsed(offset: 3, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: 2, end: 3))
Received 1 deltas
TextEditingDeltaInsertion#d2d86(oldText: ｋWelcome to SuperEditor, textInserted: ｋ, insertionOffset: 3, selection: TextSelection.collapsed(offset: 4, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: 3, end: 4))
```

</details>


### Flutter Doctor output

<details><summary>Doctor output</summary>

```console
[✓] Flutter (Channel master, 3.18.0-3.0.pre.17, on Microsoft Windows [versÆo 10.0.22000.2538], locale pt-BR)
    • Flutter version 3.18.0-3.0.pre.17 on channel master at c:\git\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 4ea7a98009 (2 hours ago), 2023-12-05 15:43:37 -0500
    • Engine revision 9660439223
    • Dart version 3.3.0 (build 3.3.0-193.0.dev)
    • DevTools version 2.30.0

[✓] Windows Version (Installed version of Windows is version 10 or higher)

[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
    • Android SDK at C:\Users\angelo\AppData\Local\Android\sdk
    • Platform android-33, build-tools 33.0.0
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[✓] Visual Studio - develop Windows apps (Visual Studio Community 2022 17.5.3)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.5.33516.290
    • Windows 10 SDK version 10.0.22621.0

[✓] Android Studio (version 2021.2)
    • Android Studio at C:\Program Files\Android\Android Studio
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 11.0.12+7-b1504.28-7817840)

[✓] VS Code (version 1.83.0)
    • VS Code at C:\Users\angelo\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.74.0

[✓] Connected device (3 available)
    • Windows (desktop) • windows • windows-x64    • Microsoft Windows [versÆo 10.0.22000.2538]
    • Chrome (web)      • chrome  • web-javascript • Google Chrome 119.0.6045.160
    • Edge (web)        • edge    • web-javascript • Microsoft Edge 119.0.2151.97

[✓] Network resources
    • All expected network resources are available.

• No issues found!
```

</details>