Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WEB] TextField actions are not triggered on Android #89384

Closed
franarolas opened this issue Sep 2, 2021 · 29 comments · Fixed by flutter/engine#33298
Closed

[WEB] TextField actions are not triggered on Android #89384

franarolas opened this issue Sep 2, 2021 · 29 comments · Fixed by flutter/engine#33298
Assignees
Labels
a: text input Entering text in a text field or keyboard related problems assigned for triage issue is assigned to a domain expert for further triage found in release: 2.2 Found to occur in 2.2 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on platform-android Android applications specifically platform-web Web applications specifically r: fixed Issue is closed as already fixed in a newer version

Comments

@franarolas
Copy link

I'm encountering a really strange issue as I haven't seen anyone reporting it and I think that it should be a P1 issue.
I've tested it in iOS through web server, it works properly, also I did built the app in Android and everything works fine, whatever it seems that it is not working with Android in Flutter web.

Steps to Reproduce

  1. Run the code below as a web-server and go to the website through an Android operating system and chrome browser:
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Home(),
      ),
    );
  }
}

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  final _controller = TextEditingController();
  String text = 'Nothing pressed';

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Column(
        children: [
          Text(text),
          TextField(
            controller: _controller,
            textInputAction: TextInputAction.send,
            onEditingComplete: () => setState(() => text = 'onEditingComplete pressed'),
            onSubmitted: (value) => setState(() => text = 'onFieldSubmitted pressed'),
          ),
        ],
      ),
    );
  }
}

Expected results:
The onFieldSubmitted action is not triggered when there is text in the TextField(Same result with TextFormField).

Actual results:
Nothing is triggered.

Flutter doctor
[√] Flutter (Channel stable, 2.2.3, on Microsoft Windows [Versión 10.0.19042.1165], locale es-ES)
    • Flutter version 2.2.3 at C:\flutter
    • Framework revision f4abaa0735 (9 weeks ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[√] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at C:\Users\frana\AppData\Local\Android\sdk
    • Platform android-31, build-tools 31.0.0
    • Java binary at: C:\Program Files\Java\jdk1.8.0_301\bin\java.exe
    • Java version Java(TM) SE Runtime Environment (build 1.8.0_301-b09)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files\Google\Chrome\Application\chrome.exe

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/windows#android-setup for detailed instructions).

[√] IntelliJ IDEA Ultimate Edition (version 2021.2)
    • IntelliJ at C:\Program Files\JetBrains\IntelliJ IDEA 2021.2.1
    • Flutter plugin version 59.0.4
    • Dart plugin version 212.5080.8

[√] Connected device (3 available)
    • M2003J15SC (mobile) • 1996586a0403 • android-arm64  • Android 10 (API 29)
    • Chrome (web)        • chrome       • web-javascript • Google Chrome 93.0.4577.63
    • Edge (web)          • edge         • web-javascript • Microsoft Edge 92.0.902.84

! Doctor found issues in 1 category.
@maheshmnj maheshmnj added the in triage Presently being triaged by the triage team label Sep 3, 2021
@maheshmnj
Copy link
Member

maheshmnj commented Sep 3, 2021

Hi @franarolas, I verifief this on the latest stable channel on Xiomi Android k20 pro and I am not able to reproduce the issue. I see that onSubmitted getting triggered.

Screen.Recording.2021-09-03.at.11.55.54.AM.mov

What device are you facing this issue on?

flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-arm,
    locale en-GB)
    • Flutter version 2.2.3 at /Users/mahesh/Documents/flutter
    • Framework revision f4abaa0735 (9 weeks ago), 2021-07-01 12:46:11
      -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK
    version 31.0.0)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google
      Chrome

[✓] Android Studio (version 4.2)
    • 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
    • Java version OpenJDK Runtime Environment (build
      11.0.8+10-b944.6916264)

[✓] VS Code (version 1.59.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.26.0

[✓] Connected device (3 available)
    • Redmi K20 Pro (mobile) • 192.168.1.2:5555 • android-arm64  •
      Android 11 (API 30)
    • macOS (desktop)        • macos            • darwin-arm64   •
      macOS 11.5.2 20G95 darwin-arm
    • Chrome (web)           • chrome           • web-javascript •
      Google Chrome 93.0.4577.63

• No issues found!

@maheshmnj maheshmnj added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Sep 3, 2021
@Fito989
Copy link

Fito989 commented Sep 3, 2021

Hello, if i try this code running with
flutter run -d web-server --release --web-hostname 192.168.x.x --web-port 8989

When I don't write on the TextField it works, but if i write and then submit it don't work

Im trying this in Realme X3 PRO

my flutter doctor:
`
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel dev, 2.6.0-0.0.pre, on Microsoft Windows [Versión 10.0.22000.168], locale es-ES)
[√] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
[√] Chrome - develop for the web
[!] Android Studio (not installed)
[√] IntelliJ IDEA Ultimate Edition (version 2021.1)
[√] IntelliJ IDEA Ultimate Edition (version 2021.2)
[√] Connected device (2 available)

! Doctor found issues in 1 category.

`

@franarolas
Copy link
Author

@maheshmnj I really think that this issue is related to android system and not to the device, as my testing team reported this issue and they tryed it with different Android devices, also I tried it with a Redmi note 9 and a Poco x3 pro.

Whatever as @Fito989 said, you have to write some text first, it "works"(The keyboard action doesn't change) if you don't enter text but it doesn't if the textfield has some text in it.

@github-actions github-actions bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Sep 3, 2021
@maheshmnj
Copy link
Member

maheshmnj commented Sep 3, 2021

@franarolas thanks for the details, I can reproduce the issue on the latest stable and the master channel, The issue only occurs in Android and works fine on IOS. The onSubmitted is not being triggered when the textfield is non-empty
Firefox on Android has strange behaviour the onSubmitted is getting triggered on second click.

Output
Android(Chrome) IOS
Screen.Recording.2021-09-03.at.4.15.37.PM.mov
Screen.Recording.2021-09-03.at.4.18.33.PM.mov
Android (Firefox) App
firefix.mov
app.mov
flutter doctor -v
[✓] Flutter (Channel stable, 2.2.3, on macOS 11.5.2 20G95 darwin-arm, locale
    en-GB)
    • Flutter version 2.2.3 at /Users/mahesh/Documents/flutter
    • Framework revision f4abaa0735 (9 weeks ago), 2021-07-01 12:46:11 -0700
    • Engine revision 241c87ad80
    • Dart version 2.13.4

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 12.5.1, Build version 12E507
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
    • 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
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] VS Code (version 1.59.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.26.0

[✓] Connected device (4 available)
    • Redmi K20 Pro (mobile) • d9dac45d                             •
      android-arm64  • Android 11 (API 30)
    • iPhone 12 Pro (mobile) • B622CBB7-F906-4FA7-8F49-FACEAAC905AB • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                •
      darwin-arm64   • macOS 11.5.2 20G95 darwin-arm
    • Chrome (web)           • chrome                               •
      web-javascript • Google Chrome 93.0.4577.63

• No issues found!
[✓] Flutter (Channel master, 2.6.0-1.0.pre.103, on macOS 11.5.2 20G95 darwin-arm,
    locale en-GB)
    • Flutter version 2.6.0-1.0.pre.103 at /Users/mahesh/Documents/flutter_master
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 2c30b252a5 (6 days ago), 2021-08-27 23:26:03 -0400
    • Engine revision ca52647cd2
    • Dart version 2.15.0 (build 2.15.0-65.0.dev)

[✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/mahesh/Library/Android/sdk
    • Platform android-31, build-tools 31.0.0
    • ANDROID_HOME = /Users/mahesh/Library/Android/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 12.5.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.10.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 4.2)
    • 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
    • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264)

[✓] VS Code (version 1.59.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.26.0

[✓] Connected device (4 available)
    • Redmi K20 Pro (mobile) • d9dac45d                             •
      android-arm64  • Android 11 (API 30)
    • iPhone 12 Pro (mobile) • B622CBB7-F906-4FA7-8F49-FACEAAC905AB • ios
      • com.apple.CoreSimulator.SimRuntime.iOS-14-5 (simulator)
    • macOS (desktop)        • macos                                •
      darwin-arm64   • macOS 11.5.2 20G95 darwin-arm
    • Chrome (web)           • chrome                               •
      web-javascript • Google Chrome 93.0.4577.63

• No issues found!
Android(Web) IOS(web) App (IOS/Android)

✅ : No Issue ❌: Issue reproduced

@maheshmnj maheshmnj added a: text input Entering text in a text field or keyboard related problems found in release: 2.2 Found to occur in 2.2 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on platform-web Web applications specifically platform-android Android applications specifically and removed in triage Presently being triaged by the triage team labels Sep 3, 2021
@franarolas
Copy link
Author

franarolas commented Sep 3, 2021

@maheshmnj I think that this should be marked as P3, how is it possible that one of main widgets of the Flutter framework is failing like that on the stable version? Are we really the first people to encounter this issue?

I can't imagine the amount of webs in production having this problem without noticing, there should be a hotfix for that.

@maheshmnj
Copy link
Member

@franarolas Please read this https://github.com/flutter/flutter/wiki/Issue-hygiene for understanding how the issues are prioritized.

@franarolas
Copy link
Author

@franarolas Please read this https://github.com/flutter/flutter/wiki/Issue-hygiene for understanding how the issues are prioritized.

My bad, then it should be P3.

@yjbanov yjbanov added the assigned for triage issue is assigned to a domain expert for further triage label Sep 9, 2021
@RedQuark
Copy link

RedQuark commented Jan 11, 2022

I'll just mention the one thing I discovered that has not been mentioned yet is that if you append a trailing space to the text you are trying to enter, then the text string is submitted. Also, I will add that you don't need onSubmitted to see the problem. It still occurs if all you have is onEditingComplete.

@RedQuark
Copy link

RedQuark commented Jan 16, 2022

I have traced the issue down one level to EditableText (gist here, or just run the code here). It definitely goes deeper than that though. I was hoping to get some information on just what key is being sent from the Android software keyboard (GBoard on my Pixel 6 Pro, I believe) that is supposed to trigger onEditingComplete, but unfortunately it is being consumed before it gets to EditableText and does not show up in RawKeyboardListener either.

The gist includes debug output from RawKeyboardListener in the Console. The data from RawKeyboardListener is quite rich on Chrome on a desktop computer, but on Chrome on Android it is very poor.

I am diving deeper down into the problem now.

@RedQuark
Copy link

RedQuark commented Jan 17, 2022

Another new observation: There is something special about the ASCII symbols '!' through '@' (33 - 64, 0x21 - 0x40), which are all of the characters between the space (32, 0x20) and the uppercase letter 'A' (65, 0x41). If you put any number of spaces followed by one of those symbols in between two strings (like "first" and "second"), then the input works properly. Example: "first @second" will work.

Additional weird observation: If you put three or more spaces between any two strings, the input works properly. If there are just one or two spaces between the strings, and the second string starts with a character with an ASCII code higher than 64, then it does not.

@RedQuark
Copy link

The other non-character ASCII symbols behave the same as those from '!' to '@'. Those symbols are: [ \ ] ^ _ ` { | } ~

A period is also special: "first.second" works, but "first,second" does not.

@RedQuark
Copy link

RedQuark commented Jan 19, 2022

Does the fact that the keyboard has a different enter key have anything to do with this issue? Note that the "key" in the bottom-right of the Flutter app is a return ↩️ , whereas the key in the bottom-right of the w3c keyboard listener is a right arrow ➡️ that inputs "Enter" (ASCII 13, which is also called "Carriage Return"). I do not yet know how to bring up the right arrow and get its ASCII equivalent, but it may be ASCII 10, also called "New Line" or "Line Feed".

To get the Flutter app return ↩️ key, don't set type and do set inputmode="text" for the <input> tag.

@RedQuark
Copy link

I was able to determine that the 0x0 "submitBtn" input field is responsible for eating all of the enter/return key events. By changing the type from "submit" to "text" in the generated main.dart.js file, I was able to capture the keys using the RawKeyboardListener. Not that it does me much good, because they all report as the same non-sensical thing, but I did discover that entering a number after a space does send another key. (I just don't know what it is, because they all report as the same non-sensical thing.) Here is the output:

controller = #d9465(TextEditingValue(text: ┤├, selection: TextSelection.collapsed(offset: 0, affinity: TextAffinity.upstream, isDirectional: false), composing: TextRange(start: -1, end: -1)))
RawKeyDownEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

controller = #d9465(TextEditingValue(text: ┤1├, selection: TextSelection.collapsed(offset: 1, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1)))
RawKeyUpEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

RawKeyDownEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

controller = #d9465(TextEditingValue(text: ┤1 ├, selection: TextSelection.collapsed(offset: 2, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1)))
RawKeyUpEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

RawKeyDownEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

controller = #d9465(TextEditingValue(text: ┤1 1├, selection: TextSelection.collapsed(offset: 3, affinity: TextAffinity.downstream, isDirectional: false), composing: TextRange(start: -1, end: -1)))
RawKeyUpEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

RawKeyDownEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

RawKeyUpEvent
Raw Key Event Data = #4d3b8
Raw Key Event Character = null
Logical Key ID = 98784247808
Logical Key Label =

So, initially the controller reports that there is no text in the editable text widget ("┤├"). We then tap the "1" key, we get a RawKeyDownEvent, the controller reports there is a "1" in the widget ("┤1├"), and we get a RawKeyUpEvent. Next we tap the space bar, get a RawKeyDownEvent, the controller reports "┤1 ├", and we get a RawKeyUpEvent. But when we tap the "1" key now, we get more than just what we expect (down, "┤1 1├", up). We get an additional RawKeyDownEvent followed by a RawKeyUpEvent with no triggering of the controller.

You can see for yourself at https://www.redquark.com/flutterBug3/#/

@RedQuark
Copy link

RedQuark commented Jan 20, 2022

Well, I have a potential (*) fix for the problem. Remove inputmode="text" from the <input> field of the EditableText widget. This changes the enter key from the return arrow ↩️ to the right arrow ➡️ and eliminates the problem of not being to enter text without appending a space at the end of the string.

(*) I only say "potential" because I don't know if this is going to mess up anything else. It 100% fixes the problem of not being able to enter text that does not end in a space or contain any of those intervening combinations of spaces and symbols. I am thinking that perhaps the return inputmode="text" is appropriate for multi-line text fields, but not for single-line text fields?

@RedQuark
Copy link

As far as what events are generated in the browser, the two keys behave the same (a series of keyCode=13 and related events) except for the return arrow key first sends both a keydown event and a keyup event for keyCode=229. I read that "it is a W3C standard to return 229 when an 'Input Method Editor' is processing."

@mdebbar
Copy link
Contributor

mdebbar commented Jan 20, 2022

@RedQuark thanks for the detailed analysis!

We actually only use inputmode="text" for single-line text fields as you can see here and here.

After you remove inputmode="text", do you see onSubmitted and onEditingComplete working as expected? If that's the case, I think it's fine to remove. Just make sure you test it in a variety of scenarios to make sure nothing is broken. I don't expect this change to break anything, but you never know.

@RedQuark
Copy link

RedQuark commented Jan 21, 2022

@mdebbar Thanks for the additional information!

I have only had the opportunity to test EditableText, not onSubmitted or onEditingComplete with TextField. But I have no doubts whatsoever that removing inputmode="text" fixes onSubmitted and onEditingComplete for TextField. I would verify that now, but I am AFK until January 29th. If this issue is still open then, I will verify it then and report back.

@RedQuark
Copy link

RedQuark commented Feb 7, 2022

@mdebbar I was on the precipice of submitting the pull request for removing inputmode="text" from the single-line text input, which thanks to your assistance I was able to implement and test thoroughly (it does work as advertised), when my son pointed out that there is another HTML attribute for changing the enter key for mobile web browser software keyboards: enterkeyhint. (We had been discussing the fact that MDN says inputmode="text" is the default, meaning removing it might not be a permanent fix.)

I tested this solution of adding the enterkeyhint with a couple of different values, and it definitely works to fix the issue, and it also appears to be the better, more robust solution. My question now is which value to assign to enterkeyhint.

On Android Chrome, the enterkeyhint value of go presents the right arrow ➡️, which is what you would get if there were no inputmode and no enterkeyhint. In other words, it is the default keyboard enter key. That seems to be the safest bet here. MDN's description of go does not provide much confidence in the messaging however as it says go means "take the user to the target of the text they typed." Clearly, that's not appropriate for the multi-line text input where it currently appears, and for single-line text input seems to limit usage to browser URL entry.

The alternatives are not much better. done is a checkmark that means "there is nothing more to input and the input method editor (IME) will be closed." That might be appropriate for the last single-line text input, but not appropriate if there are other later inputs on the page. The only other viable candidate is the next value ⇥ right arrow to bar, which means take "the user to the next field that will accept text".

Oh, and in case you were wondering, using the enterkeyhint value of enter yields the same result, the return arrow ↩️and the associated buggy behavior, as the current build. According to MDN, enter is used to indicate "inserting a new line."

Given the limited and unsatisfactory options above, I would opt for the go value myself, but I wanted your opinion as well. Ultimately, it would be beneficial if the inputmode and enterkeyhint could be specified at the Flutter level for all inputs, but that is obviously something to consider for a future enhancement. I also think that ultimately the Input Method Editor key events should be properly handled and not just worked around, but I am still not clear on where precisely those are being (improperly) handled (even on the macro level of Flutter versus browser versus OS).

Thank you for your time and assistance.

@RedQuark
Copy link

RedQuark commented Mar 8, 2022

That was my first (aborted) attempt at a PR for fixing this issue. The code fix was easy. It's everything else about the PR process that is hard.

@jtmcdole
Copy link
Contributor

done would be good for single line text, which is what I was encountering.

@RedQuark
Copy link

@jtmcdole I am currently working on a solution which lets you pick which key you want to use for Enter, including done.

@Ionys320
Copy link

Ionys320 commented Apr 9, 2022

Having the same issue. Added a space after the text do the job, but it's not a good way to solve the problem x')

@RedQuark
Copy link

I apologize for not being able to set aside adequate time to finish submitting a PR for this issue yet. I have not forgotten it. In the meantime though, I can't help but think what we are proposing for Flutter is not a fix of a Flutter problem, but rather a workaround for an Android and/or GBoard and/or Chrome on Android problem. That is unless someone can propose a reason that "string" and "string " should not have the same behavior for any given combination of inputmode and enterkeyhint.

So does anyone have any insight as to where in the Android/GBoard/Chrome on Android ecosystem the problem really lies, and if so, has anyone submitted a bug report to the appropriate project(s)?

@pdblasi
Copy link

pdblasi commented Apr 12, 2022

@RedQuark

I suspect it's not truly an Android/GBoard problem, or else we'd see this issue in non-Flutter contexts as well. Other people may have seen it out there, but I haven't seen this issue while trying to research/debug it in any context but Flutter.

I'm not certain (still chasing things down looking for a workaround), but I think it's a bug in the SystemChannels.textChannel for web. I was able to confirm that in text_input.dart the tie-in to the TextInputClient for "performAction" (which eventually ends up calling the onSubmitted function) is not hit when the GBoard is in a state where it's providing suggestions. Here's where the channel should be calling the performAction method.

This means that the action isn't even getting to the widget to try to be handled. I think it's part of why I'm not even able to get the "enter" press from a FocusNode (either the root one or for the specific TextField widget).

@dvalles
Copy link

dvalles commented Apr 20, 2022

@mdebbar Thanks for the additional information!

I have only had the opportunity to test EditableText, not onSubmitted or onEditingComplete with TextField. But I have no doubts whatsoever that removing inputmode="text" fixes onSubmitted and onEditingComplete for TextField. I would verify that now, but I am AFK until January 29th. If this issue is still open then, I will verify it then and report back.

Where exactly is it that you're removing inputmode = "text" from, I can't seem to find it in the TextField or EditableText class. I'd like to implement this solution if possible.

@maheshmnj maheshmnj changed the title [WEB] TextField actions are not triggered in Android in Flutter WEB [WEB] TextField actions are not triggered on Android Apr 22, 2022
@artificerchris
Copy link

artificerchris commented Apr 22, 2022

I have come up with a work around for this, but it is unfortunately super in the weeds and only works on web, my solution is to use an HtmlElementView and just wrap my own <input type="text"> here's what I've got to start from:

main.dart

// This is required since we have both dart:html and flutter in this file.
// ignore_for_file: avoid_web_libraries_in_flutter

import 'dart:html';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

// This is the UI shim described in flutter/flutter#55000
import 'ui_shim/ui_shim.dart' as ui;

void main() {
  WebTextInput.register();
  runApp(const TextInputIssueApp());
}

class TextInputIssueApp extends StatelessWidget {
  const TextInputIssueApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  const HomePage({Key? key}) : super(key: key);

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var inputValue = 'No input value';

  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
          child: Padding(
            padding: const EdgeInsets.all(16),
            child: Column(
              mainAxisSize: MainAxisSize.min,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Text(inputValue.isEmpty ? '<empty>' : inputValue),
                WebTextInput(
                  onTextChanged: _onTextChanged,
                  margin: EdgeInsets.all(32),
                ),
              ],
            ),
          ),
        ),
      );

  void _onTextChanged(String value) {
    if (kDebugMode) {
      print('text changed: $value');
    }
    setState(() {
      inputValue = value;
    });
  }
}

class WebTextInput extends StatefulWidget {
  const WebTextInput({
    Key? key,
    this.onTextChanged,
    this.fontSize = 24,
    this.margin = const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
    this.padding = const EdgeInsets.symmetric(horizontal: 8.0, vertical: 4.0),
  }) : super(key: key);

  static const viewType = 'web-text-input';

  static void register() => ui.platformViewRegistry.registerViewFactory(
        viewType,
        _WebTextInputState.cameraViewFactory,
      );

  final double fontSize;
  final EdgeInsets margin;
  final EdgeInsets padding;
  final void Function(String value)? onTextChanged;

  @override
  State<WebTextInput> createState() => _WebTextInputState();
}

class _WebTextInputState extends State<WebTextInput> {
  int? viewId;
  late HtmlElement view;

  static HtmlElement cameraViewFactory(int viewId) {
    final element = DivElement();
    element.id = _makeIdString(viewId);
    element.classes.add(WebTextInput.viewType);
    element.style.width = '100%';
    element.style.height = '100%';

    // Any options you'd like on the <input type="text"> should be set here.
    final input = InputElement(type: 'text');
    input.style.width = '100%';
    input.style.height = '100%';
    element.append(input);

    return element;
  }

  static String _makeIdString(int viewId) => '${WebTextInput.viewType}-$viewId';

  @override
  Widget build(BuildContext context) => Container(
        margin: widget.margin,
        constraints: BoxConstraints(
          minHeight: widget.fontSize,
          maxHeight: widget.fontSize,
          minWidth: 32,
          maxWidth: double.infinity,
        ),
        child: HtmlElementView(
          viewType: WebTextInput.viewType,
          onPlatformViewCreated: _onPlatformViewCreated,
        ),
      );

  void _onPlatformViewCreated(int viewId) {
    setState(() {
      this.viewId = viewId;
      view = document.getElementById(_makeIdString(viewId)) as DivElement;
    });

    final textInput = view.querySelector('input')!;

    final topPadding = '${widget.padding.top}px';
    final bottomPadding = '${widget.padding.bottom}px';
    final leftPadding = '${widget.padding.left}px';
    final rightPadding = '${widget.padding.right}px';

    textInput.style.paddingTop = topPadding;
    textInput.style.paddingBottom = bottomPadding;
    textInput.style.paddingLeft = leftPadding;
    textInput.style.paddingRight = rightPadding;

    textInput.onChange.listen((event) {
      final input = event.target as InputElement;
      widget.onTextChanged?.call(input.value ?? '');
    });
  }
}

@RedQuark
Copy link

@dvalles The file is input_type.dart and is located in the engine repository. The path is something like this:

flutter/engine/src/flutter/lib/web_ui/lib/src/engine/text_editing/input_type.dart

This is the code:

/// Single-line text input type.
class TextInputType extends EngineInputType {
const TextInputType();

@OverRide
String get inputmodeAttribute => 'text';
}

Change 'text' to 'none'.

@ahetawal-p
Copy link

Facing the same issue, for mobile web on Android...

@maheshmnj maheshmnj added the r: fixed Issue is closed as already fixed in a newer version label May 17, 2022
jtmcdole added a commit to jtmcdole/le_word_solver that referenced this issue May 27, 2022
prior to flutter/flutter#89384, text would not get inserted when
completing on android web.
@github-actions
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 31, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
a: text input Entering text in a text field or keyboard related problems assigned for triage issue is assigned to a domain expert for further triage found in release: 2.2 Found to occur in 2.2 found in release: 2.6 Found to occur in 2.6 framework flutter/packages/flutter repository. See also f: labels. has reproducible steps The issue has been confirmed reproducible and is ready to work on platform-android Android applications specifically platform-web Web applications specifically r: fixed Issue is closed as already fixed in a newer version
Projects
None yet
Development

Successfully merging a pull request may close this issue.