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

[webview_flutter] Keyboard persists after tapping outside text field #36478

Open
mklim opened this issue Jul 18, 2019 · 31 comments

Comments

@mklim
Copy link
Member

@mklim mklim commented Jul 18, 2019

Internal: b/144488201

To reproduce:

  1. Run webview_flutter/example.
  2. Tap into a text field. Observe that the keyboard is shown as expected.
  3. Tap anywhere else on the screen.

Expected: Keyboard minimizes.
Actual: Keyboard persists.

Haven't tested this on iOS, but this reproduces on all versions of Android. This means that it should be unrelated to any of the ThreadedInputProxyAdapterView logic and may be a deeper problem with the platform views. The keyboard also appears to switch from the text field's InputConnection. If there's any text typed in the field the suggestion bar will lose it, and it will switch from title to lower case.

See the reproduction also in #36250.

(/cc @amirh)

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Jul 18, 2019

I'll work on this.

@mklim

This comment has been minimized.

Copy link
Member Author

@mklim mklim commented Jul 18, 2019

@meggamind thanks for giving it a try! I expect this issue to be very involved. I haven't root caused it yet so I could very much be wrong, but I think at its root it probably has to do with how flutter/engine handles input connections for embedded Platform Views in TextInputPlugin.java. I think it may have something to do with this deliberately empty return when we clear a platform text input, but this is all a guess at this point. It's possible that this is something just in the plugin itself still.

If you haven't seen it yet, our Contributor Guide is the right place to go for getting started. You can read about how to set up and test with a local build of flutter/engine on the wiki: setting it up and compiling it.

Good luck!

@saitbnzl

This comment has been minimized.

Copy link

@saitbnzl saitbnzl commented Jul 30, 2019

Is there a workaround for this issue? I can't even dismiss the keyboard via FocusScope onPop or somewhere else on Android. This makes webview_flutter unusable for me.

@jessetinell

This comment has been minimized.

Copy link

@jessetinell jessetinell commented Aug 8, 2019

@saitbnzl I managed to dismiss the keyboard with this:

import 'package:flutter/services.dart';

SystemChannels.textInput.invokeMethod('TextInput.hide');

@joelbrostrom

This comment has been minimized.

Copy link

@joelbrostrom joelbrostrom commented Aug 9, 2019

@saitbnzl pressing the back button on an Android device will hide the keyboard unless you somehow intercept and cancel the event.
It sounds like you are handling the back event in inPop.
Is it possible that you return false, therefore not calling the super class's implementation?

I too need the keyboard to disappear when focus is lost by pressing outside or pressing "GO/RETURN/SEND/Etc" button.

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 13, 2019

Sorry I was busy, I'll start workin on this today, will update in a couple of days

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 20, 2019

@mklim I put in a bunch of system println in TextInputPlugin.java, then I build using ./flutter/tools/gn --android --unoptimized && ninja -C out/android_debug_unopt and then flutter run --local-engine=android_debug_unopt. However I don't see those print statements. Do I need to do something more?

@mklim

This comment has been minimized.

Copy link
Member Author

@mklim mklim commented Aug 22, 2019

@meggamind hmm, that should be enough to get everything working. My only guess is if you were literally using System.out.println and not android.util.Log? That doesn't work on some android versions. If it's not that, it's possible that your specific log statements just weren't getting hit yet, but hard to say for sure. One thing that should be hit right away in most basic apps is the constructor of FlutterView, so you could add a log there to be sure. Also, just in case, the logs also don't show up under flutter run. You need to look for them with a separate adb logcat command.

@amirh and I were talking about this bug earlier and he pointed out to me that this is also a different issue than I thought. Flutter apps don't automatically dismisses the soft keyboard when tapping outside the text field, you can see that now with the gallery example app. So it's not that this is a basic Flutter behavior that we're missing for webviews. It's webview itself that's doing this normally, and we're not matching it in the plugin.

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 22, 2019

@mklim ahh damn, thanks, I was using System.out.println. Thanks, will try util.log it out tonight and will re-check adblogcat. I think I did check there, but will do it again. Thanks!

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 23, 2019

@mklim no luck. Is there a chat group, where I can get help?

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 23, 2019

I commented constructor code in /view/FlutterView and the app still builds and works.

SO I'm thinking that my build commands are wrong.
Is it that ninja -C out/android_debug_unopt is only for C files and not for building changes made in java?

@mklim

This comment has been minimized.

Copy link
Member Author

@mklim mklim commented Aug 23, 2019

@meggamind check out https://github.com/flutter/flutter/wiki/Chat. :)

That does sound like either your build commands aren't working or for some reason your --local-engine= command isn't picking up the changes. In either case there should theoretically be terminal output saying that things aren't working, but there may be some subtle issue going on.

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 23, 2019

I have asked for help in discord and Gitter, hope I get this issue addressed soon.

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Aug 23, 2019

I downloaded the repos from scratch works now. I can work on the issue now!

@johnliedtke

This comment has been minimized.

Copy link

@johnliedtke johnliedtke commented Sep 5, 2019

@meggamind, do you have an update on the fix? I really need this in the app I'm working on :)

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Sep 5, 2019

I'll make a PR over the weekend (PST).

@johnsonted

This comment has been minimized.

Copy link

@johnsonted johnsonted commented Oct 11, 2019

Having this same problem. Also notice that if the web page asks for a specific keyboard, like a numeric keyboard for entering a credit card number, the numeric keyboard comes up for a moment then is replaced with full keyboard that's impossible to dismiss.

@NoamDev

This comment has been minimized.

Copy link

@NoamDev NoamDev commented Oct 17, 2019

@meggamind

I'll make a PR over the weekend (PST).

Have you already made the PR?
I'm sorry but I couldn't find it...
Thanks!

@deandreamatias

This comment has been minimized.

Copy link

@deandreamatias deandreamatias commented Oct 22, 2019

We have a iPad 7th generation with 13.1.3 and iPhone 6 with 12.4.2 and a keyboard works fine. It disappears when you navigate and when you touch outside it

@johnliedtke

This comment has been minimized.

Copy link

@johnliedtke johnliedtke commented Oct 28, 2019

The issue is specific to Android. Do we have any updates on this?

@liuguoping1024

This comment has been minimized.

Copy link

@liuguoping1024 liuguoping1024 commented Nov 2, 2019

How is it going ?

@OsamaFelFel

This comment has been minimized.

Copy link

@OsamaFelFel OsamaFelFel commented Nov 24, 2019

Is there any progress on this?

@zecar

This comment has been minimized.

Copy link

@zecar zecar commented Nov 27, 2019

I'm trying to implement a workaround for this. It is a compromise for now, but I can't manage to get past one thing.

Testing with:
[✓] Flutter (Channel stable, v1.9.1+hotfix.6, on Mac OS X 10.14.5 18F132, locale en-RO)
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS (Xcode 11.2.1)
[✓] Android Studio (version 3.5)

  • Samsung Galaxy J3 - Android 9

This is what I'm trying to do:

  1. Set blur event listeners in html
  2. On blur event -> send event to flutter app through JavascriptChannel
  3. Close the keyboard programatically with SystemChannels.textInput.invokeMethod('TextInput.hide');

Simple, but a compromise.

The thing that I am stuck with is that when I focus a input in webview when the keyboard is hidden, it triggers Focus Event -> Blur event -> Focus event - all 3 while the keyboard is opening. Needless to say this causes the keyboard to be hidden because the event listener for blur.

I haven't managed to find out why the blur event is triggered while the keyboard is opening - visually, the input does not lose focus

Can anyone help me finish this workaround so we can all stop struggling with this issue until it is solved by the flutter team?

@NoamDev

This comment has been minimized.

Copy link

@NoamDev NoamDev commented Nov 27, 2019

@edwin-egalite

This comment has been minimized.

Copy link

@edwin-egalite edwin-egalite commented Nov 28, 2019

My current project stuck on this too. Hope this could be resolved soon.

@zecar

This comment has been minimized.

Copy link

@zecar zecar commented Nov 28, 2019

@NoamDev due to the time waste i've switched to flutter_webview_plugin and it seems to work fine. Plus, it handles physical android back button well.

I don't think i'll come back to this issue in this project. But I hope I helped someone with my experiment

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Nov 29, 2019

on it! will finish it this thanksgiving holiday for sure. (3 days)

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Nov 30, 2019

@mklim I still can't see my changes I make in the engine. So one thing when I follow setting it up, it only pulls src directory, then I have engine/src/*, I don't have engine/shell folder when I dog client sync. so I don't know how to edit TextInputPlugin.java.
Can you please help

@meggamind

This comment has been minimized.

Copy link

@meggamind meggamind commented Dec 1, 2019

I'm able to debug now, got help from the wiki chat groups. 🎉 Will update soon

@mklim

This comment has been minimized.

Copy link
Member Author

@mklim mklim commented Dec 3, 2019

@meggamind glad you've got something working!

I haven't managed to find out why the blur event is triggered while the keyboard is opening - visually, the input does not lose focus

@zecar thank you for looking into it. The input could actually be losing focus here. On Android we draw platform views by rendering them to a virtual display, and then compositing that virtual display with Flutter's texture. When the keyboard appears on the screen we basically detach the existing virtual display and create a new one at a smaller size to compensate for the keyboard taking up half the screen, then reattach the existing view to the new display. I don't know for sure, but I wouldn't be surprised if this reattachment causes the input to lose focus. You quickly could test to see if this is the issue by putting the entire WebView in a SizedBox that was small enough to prevent the keyboard from covering the webview at all when it opens. If the issue was from the resize logic, that would prevent a resize on keyboard opening and you wouldn't see the issue then.

That said, if that is the issue I'm not really sure the right way to work around it. The onInputConnectionLocked callbacks trigger at about this time and could possibly be useful, but I don't know if the timing is going to be reliable enough for this.

/cc @amirh

@zecar

This comment has been minimized.

Copy link

@zecar zecar commented Dec 4, 2019

I don't know for sure, but I wouldn't be surprised if this reattachment causes the input to lose focus. You quickly could test to see if this is the issue by putting the entire WebView in a SizedBox that was small enough to prevent the keyboard from covering the webview at all when it opens. If the issue was from the resize logic, that would prevent a resize on keyboard opening and you wouldn't see the issue then.

@mklim thanks for your input

I've put it in a Positioned element with small height at the top of the page and indeed the focus/blur events are triggered as expected - so you were right.

Now that i have the piece of code that you provided (resize function) maybe I can listen to some events to pause the listener (the one for closing the keyboard) during the time of resize. I see in the code the onViewAttachedToWindow and onViewDetachedFromWindow but I'm not sure on how to add callbacks to those events

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.