keymanapp / keyman

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

bug(web): blank key keypress handling leads to unexpected output #5736

Open darcywong00 opened 3 years ago

darcywong00 commented 3 years ago

While investigating #5301 on an Android 5.0 emulator, I noticed this behavior on the "currency" layer of sil_euro_latin

Longpressing on the blank keys seem output the key from the neighboring key (fat-finger algorithm).

Shouldn't the blank keys block fat-fingering output?

Steps to repro:

  1. Load Keyman for Android with the default sil_eruro_latin keyboard
  2. Go to "numeric" layer and then "currency" layer
  3. Longpress on ฿
  4. Verify ฿ is output
  5. Longpress on the blank key next to ฿
  6. See the longpress above the ฿ key
  7. Select the ฿ longpress
  8. See ฿ output again
  9. I noticed the blank key next to backspace will also backspace a character.

Screenshot_1632282138

Configuration

Windows 10 Keyman for Android (master branch) Keyboard: sil_euro_latin version 1.9.5

jahorton commented 3 years ago

Please refer to https://github.com/keymanapp/keyman/blob/3eda9dd3a10071fcf76a3b7ffab6280902358f14/web/source/osk/visualKeyboard.ts#L839-L848

There is intended behavior in KMW that can have this effect. If the styling of those keys isn't set to be literally blank, that function is likely active here.

https://github.com/keymanapp/keyman/blob/3eda9dd3a10071fcf76a3b7ffab6280902358f14/web/source/osk/visualKeyboard.ts#L871-L875

Those checks simply say not to consider the key, not to block the touch outright.

darcywong00 commented 3 years ago

If the styling of those keys isn't set to be literally blank, that function is likely active here.

In this particular case for sil_euro_latin, the touch layout defines the 4 keys (between Baht and backspace)

              {
                "id": "U_0E3F",
                "text": "฿"
              },
              {
                "id": "T_new_2725",
                "text": "",
                "sp": "9"
              },
              {
                "id": "T_new_2726",
                "text": "",
                "sp": "9"
              },
              {
                "id": "K_BKSP",
                "text": "*BkSp*",
                "width": "100",
                "sp": "1"
              }

Are you saying in order for the keys not to output anything, there needs to be keyboard rules to define the following?

+ [T_new_2725] > ''  c or context beep
+ [T_new_2726] > ''
jahorton commented 3 years ago

Note that bit in the first codeblock's comment:

but return null more than about 0.6 key width from the nearest key. 

That 0.6 of a key's width is feeling too generous to you. Try pressing between the two blank keys - if I'm right, nothing should output because you'll be more than 60% of a non-blank key's width away from output keys on the same row.

If my prediction above is right, then if we lowered that to, say, 0.25, it'd probably feel a lot more reasonable. Or maybe something like 0.3 on a phone, but 0.15 on a tablet... something like that.

Alternatively, we could create a custom check for blank keys that says "if the touchpoint is less than (say) 70% of the key's 'radius' away from its center, just return null." So something on the edge could still "fat-finger" correct to the nearest key, but anything "on target" for a blank key gets blocked. There are a few different angles we could take here.

That said, the actual fat-finger algorithm has nothing to do with the issue. It's an entirely different mechanism.