Summary of these changes:
Two targeted improvements; more optimization is possible but IMO this is
a significant enough improvement to go through test:
1. In oskView.ts, avoid calling `VisualKeyboard.refreshLayout` twice
from `OSKView.refreshLayout`. This roughly halves the time spent in
`VisualKeyboard.refreshLayout` for a keyboard switch.
2. In modelManager.ts, we avoid a very expensive `unloadModel` /
`loadModel` sequence from `registerModel` by checking to see if the
model spec we are passed is already registered. This avoids an
expensive callback to Keyman for Android which causes the banner to
'bounce'.
Longer notes:
So `VisualKeyboard.refreshLayout` is called 20+ times during a keyboard
switch. It is a very expensive call. It is the bulk of the time spent
when you press the globe key in Keyman for Android. This seems ripe for
optimization; see the following functions in keyboard.html:
* `setKeymanLanguage` -> `setActiveKeyboard` -> 6 calls
* `enableSuggestions` -> `registerModel` -> 8 calls
* `stateChange` -> 6+ calls
`OSKView.refreshLayout` always seems to call
`VisualKeyboard.refreshLayout` twice: first with `setSize`, and then
again itself.
Keyman for Android and KeymanWeb seem to fight over who is responsible
for selecting models (KMW first calls `loadModel`, then Keyman for
Android calls `unloadModel`, `loadModel`, through `enableSuggestions`).
The fix for rotation (`correctOSKTextSize()`), as called from
`stateChange()`, is expensive as well, because it rebuilds the entire
keyboard from scratch.
Along with that, we have the size of the webview changing as the model
is unloaded and reloaded and lots of back-and-forth between the
KeymanWeb and KMEA which seems unnecessary.
Shouldn't KeymanWeb be responsible for loading and unloading models,
once they are all registered? We should only need to register the models
once at page load time (when config changes, do we just reload the
page?).
Fixes#5950.
If a user starts a longpress gesture and then flicks up, that
immediately brings up the longpress menu, and the timeout for display of
the menu should be cancelled -- otherwise the end result is a key that
stays 'stuck' on.
Fixes#5831.
iOS 15 has a significant crashing bug whereby use of a canvas element
completely crashes the browser in some contexts. In particular, we have
observed this when using a WKWebView in a keyboard extension without
'Allow Full Access' switched on.
Keyman uses canvas element to draw a nice looking key preview (key tip)
on iPhones. This is a critical issue for Keyman for iPhone. Keyman for
iPad is not affected because the iPad version does not use key previews.
The resolution here is to remove use of the canvas drawing for key tips
and use a simplified pure HTML/CSS shape. I have not conditioned this
fix on platform; I have currently opted to apply this to all platforms.
This issue will be reported to Apple for resolution. The issue applies
so far to iOS 15.0, 15.1.
Fixes#5907.
The state machine for the Hide transition for the OSK was very complex,
and had some peculiarities which caused it to sometimes fail to
correctly hide. Once I simplified the state machine, it seems that those
edge cases have gone away, and the keyboard always hides correctly.
There is an unrelated issue with focus timeout which can be confusing
when testing this; see #5909.
Fixes three issues:
* longpress positioning for inlined OSK views where not all elements
may be in the offset hierarchy; impacts particularly where an inlined
OSK may be within a flex-box.
* Tweaks position of keytip, to take into account the offsetTop of the
key element.
* Inverts test for display of longpress callout, matching Keyman 14.