keymanapp / keyman

Keyman cross platform input methods system running on Android, iOS, Linux, macOS, Windows and mobile and desktop web
https://keyman.com/
Other
386 stars 107 forks source link

bug(android): double-tap on Shift inconsistent #11183

Open ermshiperete opened 5 months ago

ermshiperete commented 5 months ago

When in caps layer and double tapping on the Shift button the keyboard should toggle between shift layer and caps layer. However, it's possible to end up in the default layer instead. See the very end of the attached screencast. You might have to single step through the frames to see that there are two taps. What's interesting is that when single stepping over that last double tap you can see that it changes shift layer → caps layer → default layer. For the correctly working double taps it's shift layer → default layer → caps layer.

https://github.com/keymanapp/keyman/assets/181336/bf3bd20f-fc32-44e1-862c-fd662addd6fc

mcdurdin commented 4 months ago

So, what you are saying is that double tapping the shift key should:

I'm not sure we've ever specified that third pathway. That could be the issue.

jahorton commented 4 months ago

So, what you are saying is that double tapping the shift key should:

  • default layer --> caps layer

  • shift layer --> caps layer

  • caps layer --> shift layer

I'm not sure we've ever specified that third pathway. That could be the issue.

For a key defined like this:

All our other multitaps operate this way:

  1. (single tap) A
  2. B
  3. C
  4. D
  5. A
  6. B
  7. etc. Basically, a rota effect.

Alternating between shift and caps when the base is default does not match rota pattern.

I think there was a point where we'd left the base layer out by accident, but I seem to recall that feeling "off" for some other reason. I don't see an issue corresponding directly to it, but this behavior - rota back to the base layer - was in place at the time of #10281, as its description explicitly mentions maintaining the behavior.

ermshiperete commented 4 months ago

Yes, using rota for multitaps makes sense.

However, this issue is not about triple or quadruple taps but multiple double taps with pauses in between. When I slowly double tap I see the shift layer <--> caps layer alteration. But when I do it more quickly it's not always consistent.

It's possible that the system sees it as multi taps, but the time elapsed between the 2. and 3. tap is greater than between the 1. and 2. as well as 3. and 4. tap. So basically like this:

time: . . . . . . . .
tap:  | |   | |   | |
jahorton commented 4 months ago

Ah, okay. Now that I inspect the video more closely, you may be running into something else.

We currently use the standard longpress timer as the multitap timeout as well. Thing is, that's half a second... long enough that what may feel like "separate multitaps" may not be as "separate" as you expect. I've had a few times where I unexpectedly continued a previous multitap because the time was short and I hadn't tapped anything else in the meantime.

The last taps in the video felt like they had a shorter interval than near the start - that could be the point at which the system decided "same multitap, not a new one."

So, instead of:

time: . . . . . . . . . .
tap:  | |     | |     | |

You may have had:

time: . . . . . . . . .
tap:  | |     | |   | |

... at which point the system may have said "one gap means it's not new - that's a continuation of the same multitap".

jahorton commented 4 months ago

BTW, this and other gesture timing issues are why I made sure to make the timings parameterizable. Obviously, we don't have the UI for this in 17.0, but the idea is that we could add UI in the mobile apps for 18.0 or later to allow customization of these timings so that users can choose what feels most intuitive timings-wise to them.

jahorton commented 4 months ago

The current definition of all gesture-related timeouts:

https://github.com/keymanapp/keyman/blob/7aa6b668ffa9f3a0891a24046a371eb61f7ce186/web/src/engine/osk/src/input/gestures/specsForLayout.ts#L102-L122

While the OSK's codebase is structured to allow someone to set specific values for some of those and have these fill in the blanks... the mobile apps don't leverage this yet, and so these are the true definitions.

Distance thresholds are updated separately elsewhere in the codebase for now, set to a percentage of row height during the OSK's layout-refresh:

https://github.com/keymanapp/keyman/blob/7aa6b668ffa9f3a0891a24046a371eb61f7ce186/web/src/engine/osk/src/visualKeyboard.ts#L1280-L1283

(The gesture models don't currently have live access to the current row height value.)

jahorton commented 4 months ago

I've just put together #11246 to hopefully provide more intuitive timings for multitaps, based on what the big vendors appear to use.