micku7zu / QuickCursor

Quick Cursor: One-Handed mode
https://play.google.com/store/apps/details?id=com.quickcursor
20 stars 1 forks source link

Keys on the side of the keyboard have a small delay with Quick Cursor #9

Open micku7zu opened 1 year ago

micku7zu commented 1 year ago

Issue was reported on Reddit here: https://www.reddit.com/r/androidapps/comments/105hc14/which_are_the_best_apps_to_try_in_2023/j3eztmu/

and the response is also available on Reddit here: https://www.reddit.com/r/androidapps/comments/105hc14/which_are_the_best_apps_to_try_in_2023/j3g0os0/

Issue

When off, I get "instant" response, in particular on the A key and the backspace key (and probably numlock and enter as well.) With QC active, there's a 0.1 - 0.2s of a lag -- in other words, hitting backspace has a noticeable (but minor) delay before activating.

Solution

TL;DR

Yes, the triggers over the keyboard adds a minor delay over the letters they cover ("Q", "A", "P", "Backspace", etc). There are workarounds and solutions for this, depending on personal preference:


Long answer

As you can see in this screenshot, the triggers overlaps some of the keyboard keys but this depends A LOT on many many variables: keyboard layout (keyboard app, android version, etc), screen size, personal "screen zoom" or "font size" adjusted from settings, curved display or not, etc.

So there are no two identical setups available, each one has a different trigger size that works for them which might overlap or not the keyboard. I tested it on many devices and sometimes a small trigger size works excellent on some devices but not so good on others, where you need to make it bigger, overlapping more of the keyboard.

So, when the app was first released 2-3 years ago, it didn't have many features, and one of the first feedback (example 1, example 2, example 3) was that they can't use the keyboard correctly because the triggers are triggered when they type.

I was surprised because on my device I could set the triggers small enough to not overlap but still to be triggered, then I discovered that this does not apply to all use cases and I had to implement some workarounds:

Pass trigger clicks delay

As you discovered yourself, the "pass trigger clicks" workaround is a hack, because this can't be achieved without a hack. It is an Android limitation or a security feature.

In Android only 1 app can "capture" a touch event, and that app can't be changed for the lifespan of that touch event, so I have two options in Quick Cursor:

It is clear that triggers needs to listen to touch events, which means that when the user touches the trigger, that touch is completely reserved for Quick Cursor app, it can't be passed to other app.

So, when a user touches the trigger (first 0-100ms), it is not clear yet what they want to do, because that touch can be a simple tap or a swipe, or a long tap, it is still not decided. Screenshot of some touch examples https://i.imgur.com/9kXVcBL.png. Here it also depends A LOT on the touchscreen sampling rate and touchscreen sensitivity, I personally experienced a huge difference in sensitivity between devices. There are some devices where I can't simply tap on the screen without triggering also a 'move' event, it's always: 'down', 'move', 'up'. In other devices it is always 'down' and 'up' for a tap.

First delay: So, the user touches the trigger and until the 'up' event (that he released the screen) or a certain amount has passed (300ms, 500ms, to be considered a long tap, not a simple tap), I can't decide if he wanted to press what's under the trigger (a letter) or he wants to grab a cursor.

Second delay: After the event was decided (tap, long tap, swipe, etc)(0-299ms delay), depending on how fast the tap was (it can be even under 20ms, this one depends on how the user taps and the touchscreen/device "performance"), I have to pass the click through the tracker to the letter behind the tracker, and this is not possible in Android in a normal way, but this app being an accessibility service, I can simulate a tap on the screen at the position the user clicked behind the tracker, which implies some kind of hack and it adds another delay (pretty hard to measure and extremely hard to check how much difference between devices is) but it shouldn't be that much.

The keyboard app receives the new fake touch event after (first delay + second delay)ms and process the touch event themselves.

There is also another Android limitation: there can't be two simultaneous touch events from different input devices. Example:

So I can't simulate the touch under the trigger until the real touch event has finished.

I hope everything is clear now, why it happens, what workarounds are available.

Of course, choosing the best workaround for this depends on what you prefer. I personally prefer to make the triggers as small as possible but still be usable AND to pass the clicks through the triggers. There are a lot of users with the triggers raised above the keyboard, and a lot with them completely disabled. It depends 😁