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

Enter detection fails in EnterPressedWatcher for Gboard keyboard #3316

Closed
mkevins opened this issue Mar 29, 2021 · 5 comments · Fixed by WordPress/gutenberg#32471 or #3590
Closed

Enter detection fails in EnterPressedWatcher for Gboard keyboard #3316

mkevins opened this issue Mar 29, 2021 · 5 comments · Fixed by WordPress/gutenberg#32471 or #3590
Assignees

Comments

@mkevins
Copy link
Contributor

mkevins commented Mar 29, 2021

Description

The mechanism to detect whether the [ENTER] key was pressed is not reliable for users with the Gboard keyboard. The Gboard keyboard exhibits some unusual behavior regarding the TextWatcher interface methods, which are breaking some assumptions in the logic we are using for key detection. This manifests as various bugs, and is likely not limited to the [ENTER] key (e.g. I believe [BACKSPACE] detection may be affected in a similar manner).

Example bug

On a Pixel 3a (physical device) with the Gboard keyboard:

  1. Create a new post
  2. Add a paragraph block
  3. Type a word (e.g. "Hello") without a space
  • Observe that the keyboard suggestions
  • Observe that the word is underlined
  1. Press [ENTER]
  2. Observe that the block does not split - instead, a newline is added to the paragraph block

Expected

The block should split and form a new paragraph block below.

Deeper details

The EnterPressedWatcher class works by implementing the TextWatcher interface, overriding the following methods:

  • beforeTextChanged
  • onTextChanged
  • afterTextChanged

and tracking state during a user's manipulation of the EditText input. These methods allow us to observe the mutations to the CharSequence, and to provide a means to reconcile what has changed, and respond in some way after evaluating the changes at each stage of the update. Typically, these changes are fairly straightforward, and these methods are invoked with predictable index boundaries for a given text input operation, but here is where Gboard exhibits some unusual behavior.

Here is a table describing some observations that surprised me:

Consider a scenario where we have the input with text Hello worl, and we then press d on the keyboard:

Comparison TextWatcher Interface Method text: CharSequence start: Int count: Int after: Int before: Int
Expected beforeTextChanged "Hello worl" 10 0 1 N/A
Actual beforeTextChanged "Hello worl" 6 4 5 N/A
Expected onTextChanged "Hello world" 10 1 N/A 0
Actual onTextChanged "Hello world" 6 5 N/A 4

The surprising part is that some characters from the original text are being replaced when nothing was selected (just a normal caret at the end of the input). It seems instead that Gboard is actually replacing the last 4 characters with those same 4 characters plus the typed text. It is even possible to notice a small underline style applied to the characters that will be included in the replacement. Before this, I would have only expected beforeTextChanged to be called with a count > 0 if there was a selection prior to the new characters being typed (or if characters were being deleted).

Note that the result is the same (and that the sum is still 11 for start + after and start + count for beforeTextChanged and onTextChanged respectively).

Interestingly, after selecting one of the suggestions offered by Gboard, the onEnter behavior was works normally (and the underlined text goes away).

@antonis
Copy link

antonis commented Mar 29, 2021

Thank you for the extensive research on this @mkevins 🙇
This issue might also be related since I was able to reproduce it only on Pixels.

@mkevins
Copy link
Contributor Author

mkevins commented Mar 30, 2021

This issue might also be related since I was able to reproduce it only on Pixels.

Thanks Antonis! It seems that there are several issues that may be affected by the same underlying cause, so I think it'll be worth revisiting them each if we can land a fix / solution to this one. 🤞

@hypest
Copy link
Contributor

hypest commented Mar 30, 2021

Thanks for the deeper look and the draft PR to fix @mkevins ! I've reproduced the issue on my Pixel 2XL Android 11. Since it looks like exactly the same issue as the one reported by @antonis , wdyt about copying over your analysis and closing this new ticket?

@hypest
Copy link
Contributor

hypest commented Mar 30, 2021

Added the "Priority High" label to be clear that this is still important to fix. GBoard might actually be used on phones other than the Pixels.

@mkevins
Copy link
Contributor Author

mkevins commented Mar 30, 2021

@hypest 👋 😄

wdyt about copying over your analysis and closing this new ticket?

I considered this, and did a search prior to opening this issue, which actually turned up several issues that are related to Gboard's behavior interfering with our [ENTER] detection. I don't quite agree that it "looks like exactly the same issue", though, as the intention here is to address the deeper source of several issues (for example, this issue linked in the issue Antonis reported). I was also deliberate in the title of this issue: "Enter detection fails in EnterPressedWatcher for Gboard keyboard" to make it clear I'm referring to an issue with this particular TextWatcher implementation (and not just an issue with one particular user flow).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment