-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Android Firefox and Chrome: Swipe typing is aborted very often #2952
Comments
It's hard to reference the input tester on mobile. I wonder if maybe debugging this is easier on a tablet?) I think this occurs because the I'm thinking this because of the following order of events:
Similarly if you type a word key by key and then quickly start tapping the auto-text option will insert it but the newly inserted word will enter the document as if it's being composed (it has the underline under it, and the vibrate that normally accompanies word insertion is oddly cut off during this. @thesunny I'm finally approaching a time where I can start to turn more towards the internals of Slate that you've done so much great work on. If you can give me your thoughts on what the cause might be I'd love to take a look so my subconscious can hopefully come up with something by a couple weeks from now when I'll have some time. I tested out Draft and it doesn't seem to have this issue. I know we're using mutation observers which I think we turned to after seeing the success they had with that approach, if I'm not mistaken, so I'm hopeful we can find some clues in their implementation. Thanks again for all your hard work bud! Hope I can help build on it! I'll hopefully be on Slack more starting later this week if you want to discuss in real-time. PS: I recall Slate and/or Slate-React having |
You can enable useful debugging information by setting your Everything for android is in one plugin you can find here https://github.com/ianstormtaylor/slate/tree/master/packages/slate-react/src/plugins/android There are support files in the same directory. There are timing issues and I'm pretty sure right now things aren't happening synchronously even though they should. The flushControlled code here https://github.com/ianstormtaylor/slate/blob/master/packages/slate-react/src/plugins/android/composition-manager.js doesn't seem to be doing it's job but maybe there is a way to make it work better. If I remember correctly, the basics of the plugin is that we wait for a composition to start and do nothing until it finishes. When it finishes, we inspect the DOM for changes and then run the commands in Slate. Certain changes like enter and backspace, especially at certain boundaries, cause a flurry of DOM mutations. We make an educated guess based on what the mutations are doing in aggregate that translates them into commands like There is also additional documentation here https://github.com/ianstormtaylor/slate/blob/master/packages/slate-react/src/plugins/android/composition-manager.md |
That's all extremely helpful! I'm excited to see what I can find now that I've got some leads. I've only gotten to take the briefest look so far. I'll take a closer look at Regarding swiping specifically, I've noticed that the behavior is seemingly 100% consistent no matter how long you wait, word length, etc. Combined with what I found previously, I'm thinking the cause is that we have no way to detect the end of one swipe event and the start of another, so the composition stays open. I can't think of any time this would be valid under normal circumstances, so my suspicion is that the keyboard recognizes that beginning a composition while you're already mid-composition is invalid and cancels the user's request. After cancelling, the keyboard re-focuses on the still open composition. This manifests as a loss of the originally suggested alternatives. The originally suggested alternatives were specifically tailored to the unique imprecisions of that particular swipe event, but are lost under this circumstance in favor of the generic composition suggestions based only on the word and its context, with the original swipe pattern having no relevance to the new suggestions. This is what happens when you revisit a word you previously swiped after losing focus on it. Is what I wrote clear? If so, thoughts on this possibility? I guess, in short, do we think this is a problem of us not doing something (eg, closing the composition) or is this because we are doing something (eg, updating the underlying editor value) By the way, the Composition Manager doc reminds me, has anyone had a chance to try Android 10 with Slate yet? I hope Google didn't screw us. Thanks again for taking the time @thesunny! |
Android 10 test results:
|
It's worth experimenting with timing; however, at the same time, be careful about adjusting the times with This is not ideal and it's one of the reasons why the recovery mechanism of a broken DOM is important (i.e. we redraw the content on a Slate crash). Some things that you may also want to pay attention to:
Also if it is indeed a composition that is not being finished, try and look at the mutations and events to see if there is a way to figure out that a composition has completed at the end of a swipe. You may have to look at combinations of mutations and events. |
It seem that the swipe aborting is connected to |
@gracicot To provide some more details and ideas for future, there are some improvements we can performance-wise for most uses of I have code which I think is in Slate now but is not used that will rebuild only two root level blocks (the current one and the one before). The way it does this is that it creates a mirror of the DOM in memory using arrays and objects. This mirror stores the positions and text contents of the DOM. When we need to restore the DOM, we run this method and it moves the DOM elements around to match the mirror and fixes the text inside it where it has differed. I didn't include this in the initial release because |
@thesunny Only restoring mininum amount of nodes would be awesome. It may fix some slugginess I observed when editing larger texts. It would require testing, but from previous experiment (when the whole document was re-rendered), the keyboard lost context from previously typed words. That context loss prevent some operation that span multiple composition. One simple example would be pressing and holding down the backspace key to delete many characters and autocorrect on previous words (android and iOS can apply autocorrect on the word before the composed one). Swipe typing may also be included since a swipe usually starts before the previous composition ends. Right now I'm investiguating on a way to avoid calls to |
Hey, there are lots of open Android-related issues that are out of date with the latest If it cannot be implemented simply in core with Thank you for understanding. |
Do you want to request a feature or report a bug?
bug
What's the current behavior?
On the Slate JS front page rich text demo (https://www.slatejs.org/#/rich-text), position the cursor at the end of the first line (after the "!"). Type "the quick brown fox jumps over the lazy dog", only by swiping each word.
On Firefox Android (version 68), the result is " The quickbrown jumps overthe dog". When "fox" and "lazy" are swiped, the swipe is aborted partway through (the blue line left by your finger while swiping disappears while swiping the word!) and the word is dropped entirely. The words "brown" and "the" don't get leading spaces, so they're combined with the previous word. It seems like there's a repeating pattern: two words work fine, followed by one word that doesn't get a leading space, followed by one word dropped.
On Chrome for Android (version 75.0.3770.143), the result is " The brown jumps the dog". Every second word is aborted partway through swiping, similar to how it happened on Firefox.
Testing on Android 9 on a Pixel 3.
The text was updated successfully, but these errors were encountered: