flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
164.86k stars 27.16k forks source link

Text field cursor position in RTL goes to the penultimate character #118566

Closed guy-evdev closed 11 months ago

guy-evdev commented 1 year ago

In https://github.com/flutter/flutter/issues/107006, this issue has been marked as resolved since v3.1.0 but this issue is still reproduced in v3.3.10. Tested in Hebrew using a TextField and a TextFormField

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Write in Hebrew or any other RTL language in the text field.
  3. Tap on any place to change the cursor position then tap again at the end of the text field, the cursor position will change to the penultimate character

Expected results: The cursor position should be after the last character.

Actual results: The cursor position moves to the penultimate character.

Code sample ``` import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', locale: const Locale("he"), localizationsDelegates: const [ GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, GlobalCupertinoLocalizations.delegate, ], supportedLocales: const [Locale("he")], theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: const Center( child: Padding( padding: EdgeInsets.all(16), child: TextField(), ), ), ); } } ```
Logs ``` Performing hot restart... [ +12 ms] Scanned through 547 files in 9ms Syncing files to device Pixel 6 Pro... [ ] <- reset [ ] Compiling dart to kernel with 0 updated files [ ] Processing bundle. [ ] <- recompile package:testing/main.dart 7acc36df-1abf-488c-9f8a-9807e5f9b4f4 [ ] <- 7acc36df-1abf-488c-9f8a-9807e5f9b4f4 [ ] Bundle processing done. [ +39 ms] Updating files. [ +497 ms] DevFS: Sync finished [ ] Synced 33.8MB. [ ] <- accept [ +230 ms] Hot restart performed in 778ms. [ ] Restarted application in 784ms. [+11501 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F....ID 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +8 ms] I/AssistStructure(17108): Flattened final assist data: 384 bytes, containing 1 windows, 3 views [ +13 ms] W/OnBackInvokedCallback(17108): OnBackInvokedCallback is not enabled for the application. [ ] W/OnBackInvokedCallback(17108): Set 'android:enableOnBackInvokedCallback="true"' in the application manifest. [ +19 ms] D/InsetsController(17108): show(ime(), fromIme=true) [+1835 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +1 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +201 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +2 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +197 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +1 ms] D/InsetsController(17108): show(ime(), fromIme=true) [+1721 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +1 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +337 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +2 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +188 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +1 ms] D/InsetsController(17108): show(ime(), fromIme=true) [+1929 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +2 ms] D/InsetsController(17108): show(ime(), fromIme=true) [+1868 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +2 ms] I/TextInputPlugin(17108): Composing region changed by the framework. Restarting the input method. [ +5 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ ] D/InsetsController(17108): show(ime(), fromIme=true) [ ] W/RemoteInputConnectionImpl(17108): getSurroundingText on inactive InputConnection [ +8 ms] W/RemoteInputConnectionImpl(17108): getTextBeforeCursor on inactive InputConnection [ ] W/RemoteInputConnectionImpl(17108): getSurroundingText on inactive InputConnection [ +10 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +22 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ ] D/InsetsController(17108): show(ime(), fromIme=true) [ +11 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +572 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ +1 ms] I/TextInputPlugin(17108): Composing region changed by the framework. Restarting the input method. [ +3 ms] D/InputMethodManager(17108): showSoftInput() view=io.flutter.embedding.android.FlutterView{f60bf33 VFED..... .F...... 0,0-1440,3036 #1 aid=1073741824} flags=0 reason=SHOW_SOFT_INPUT [ ] D/InsetsController(17108): show(ime(), fromIme=true) [ ] W/RemoteInputConnectionImpl(17108): getSurroundingText on inactive InputConnection [ +2 ms] W/RemoteInputConnectionImpl(17108): getTextBeforeCursor on inactive InputConnection [ ] W/RemoteInputConnectionImpl(17108): getSurroundingText on inactive InputConnection [ +24 ms] D/InsetsController(17108): show(ime(), fromIme=true) [ +4 ms] D/InsetsController(17108): show(ime(), fromIme=true) ``` ``` Analyzing testing... No issues found! (ran in 3.0s) ``` ``` [✓] Flutter (Channel stable, 3.3.10, on macOS 13.0.1 22A400 darwin-arm, locale en-IL) • Flutter version 3.3.10 on channel stable at /Users/___/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 135454af32 (5 weeks ago), 2022-12-15 07:36:55 -0800 • Engine revision 3316dd8728 • Dart version 2.18.6 • DevTools version 2.15.0 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1) • Android SDK at /Users/___/Library/Android/sdk • Platform android-33, build-tools 33.0.1 • Java binary at: /Users/___/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents/jre/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866) • All Android licenses accepted. [!] Xcode - develop for iOS and macOS (Xcode 14.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14C18 ✗ CocoaPods installed but not working. You appear to have CocoaPods installed but it is not working. This can happen if the version of Ruby that CocoaPods was installed with is different from the one being used to invoke it. This can usually be fixed by re-installing CocoaPods. To re-install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions. [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 2021.3) • Android Studio at /Users/___/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/213.7172.25.2113.9123335/Android Studio.app/Contents • 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.13+0-b1751.21-8125866) [!] Android Studio (version 2022.1) • Android Studio at /Users/___/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/Android Studio.app/Contents • 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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [✓] VS Code (version 1.71.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension can be installed from: 🔨 https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter [✓] Connected device (3 available) • Pixel 6 Pro (mobile) • 19281FDEE000BN • android-arm64 • Android 13 (API 33) • macOS (desktop) • macos • darwin-arm64 • macOS 13.0.1 22A400 darwin-arm • Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.87 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 2 categories. ```
Recording https://user-images.githubusercontent.com/95240607/213135361-28e529ad-265a-4a4d-9c44-ae3b65efc207.mp4
moffatman commented 1 year ago

I have a fix for the cause in upstream library, but seems to be stalled

https://skia-review.googlesource.com/c/skia/+/619838/1

danagbemava-nc commented 1 year ago

Hi @guy-evdev, does the recording below capture the issue in question, or is there something missing in my repro?

recording https://user-images.githubusercontent.com/88313112/213106221-9b99d6a9-b7b0-4747-9d26-f3bc1434c399.mp4
guy-evdev commented 1 year ago

I believe that it captures the issue. I edited my original post and added my own recording from today showcasing the issue as well

danagbemava-nc commented 1 year ago

Thanks for the video and confirmation. It made the issue much clearer.

Reproduces on the latest versions of stable and master.

Labeling for further investigation.

recordings | iOS | android | | -- | -- | |
flutter doctor -v ``` [✓] Flutter (Channel stable, 3.3.10, on macOS 13.1 22C65 darwin-arm, locale en-GB) • Flutter version 3.3.10 on channel stable at /Users/nexus/dev/sdks/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 135454af32 (5 weeks ago), 2022-12-15 07:36:55 -0800 • Engine revision 3316dd8728 • Dart version 2.18.6 • DevTools version 2.15.0 [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/nexus/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14C18 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [!] Android Studio (version 2022.1) • Android Studio at /Applications/Android Studio.app/Contents • 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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [!] Android Studio (version 2022.1) • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/Android Studio.app/Contents • 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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [✓] IntelliJ IDEA Community Edition (version 2022.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • 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 [✓] VS Code (version 1.74.3) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.56.0 [✓] Connected device (5 available) • Pixel 7 (mobile) • adb-28291FDH2001SA-5Lv71w._adb-tls-connect._tcp. • android-arm64 • Android 13 (API 33) • M2007J20CG (mobile) • adb-5dd3be00-17AYzd._adb-tls-connect._tcp. • android-arm64 • Android 12 (API 31) • Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 16.2 20C65 • macOS (desktop) • macos • darwin-arm64 • macOS 13.1 22C65 darwin-arm • Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.87 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 2 categories. ``` ``` [!] Flutter (Channel master, 3.7.0-22.0.pre.9, on macOS 13.1 22C65 darwin-arm64, locale en-GB) • Flutter version 3.7.0-22.0.pre.9 on channel master at /Users/nexus/dev/sdks/flutters ! Warning: `flutter` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path. ! Warning: `dart` on your path resolves to /Users/nexus/dev/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/nexus/dev/sdks/flutters. Consider adding /Users/nexus/dev/sdks/flutters/bin to the front of your path. • Upstream repository https://github.com/flutter/flutter.git • Framework revision 780563ce05 (12 hours ago), 2023-01-18 09:55:33 +0900 • Engine revision f790304409 • Dart version 3.0.0 (build 3.0.0-122.0.dev) • DevTools version 2.20.0 • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades. [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) • Android SDK at /Users/nexus/Library/Android/sdk • Platform android-33, build-tools 33.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.15+0-b2043.56-8887301) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 14.2) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 14C18 • CocoaPods version 1.11.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [!] Android Studio (version 2022.1) • Android Studio at /Applications/Android Studio.app/Contents • 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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [!] Android Studio (version 2022.1) • Android Studio at /Users/nexus/Library/Application Support/JetBrains/Toolbox/apps/AndroidStudio/ch-0/221.6008.13.2211.9477386/Android Studio.app/Contents • 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 ✗ Unable to find bundled Java version. • Try updating or re-installing Android Studio. [✓] IntelliJ IDEA Community Edition (version 2022.2) • IntelliJ at /Applications/IntelliJ IDEA CE.app • 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 [✓] VS Code (version 1.74.3) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.56.0 [✓] Connected device (5 available) • Pixel 7 (mobile) • adb-28291FDH2001SA-5Lv71w._adb-tls-connect._tcp. • android-arm64 • Android 13 (API 33) • M2007J20CG (mobile) • adb-5dd3be00-17AYzd._adb-tls-connect._tcp. • android-arm64 • Android 12 (API 31) • Nexus (mobile) • 00008020-001875E83A38002E • ios • iOS 16.2 20C65 • macOS (desktop) • macos • darwin-arm64 • macOS 13.1 22C65 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 109.0.5414.87 [✓] HTTP Host Availability • All required HTTP hosts are available ! Doctor found issues in 3 categories. ```
justinmc commented 1 year ago

@jason-simmons Is the Skia fix mentioned above a viable fix for this?

jason-simmons commented 1 year ago

Yes - tried applying that patch to SkParagraph and the fix LGTM.

One of the framework tests (https://github.com/flutter/flutter/blob/master/packages/flutter/test/widgets/selectable_region_test.dart#L845) has an expectation based on the old behavior and will need to be updated when the patch rolls into the framework.

justinmc commented 1 year ago

Awesome, thank you! I opened a quick draft PR so it's ready to go when the Skia fix is rolled into Flutter: https://github.com/flutter/flutter/pull/118902

Or now that I think about it, maybe the test needs to be changed as a part of the roll PR?

chinmaygarde commented 1 year ago

This is waiting for https://skia-review.googlesource.com/c/skia/+/619838/1 and be rolled in.

abdullahalamodi commented 1 year ago

Hi @guy-evdev, does the recording below capture the issue in question, or is there something missing in my repro?

recording telegram-cloud-document-4-5927042189736546000.mp4

you add space after the last letter and when you tap curser goes to the penultimate character where the space is the last character this is a joke and not a solution the problem still exists

the same is here https://github.com/flutter/flutter/issues/107006#issuecomment-1173658912

I don't want to say more than that

moffatman commented 1 year ago

@abdullahalamodi Hi, I think my fix is included in the master branch as of today. Can you try it out and see if it's solved for you? Thanks 😁

LongCatIsLooong commented 11 months ago

Couldn't reproduce this any more. Closing.

github-actions[bot] commented 10 months ago

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.