From ae45b69b5f3cd433b7f5cf55257217359496c7b1 Mon Sep 17 00:00:00 2001 From: Marc Durdin Date: Mon, 25 Jul 2022 08:03:02 +1000 Subject: [PATCH] fix(android): rework longpress movement trigger Fixes #6981. Longpress menus were being triggered on any detected movement on keys on Android. This would cause rapid typing to periodically fail as the user would make a single-pixel movement while typing, which would then block subsequent key events. This issue was introduced in #6637, which resolved a somewhat related problem with sticky longpress menus. The fix is in three parts: 1. Remove the touch movement detection which caused the primary problem 2. Address some logic issues around visibility of `subkeysWindow` 3. Introduce a new 'scroll' gesture handler which detects a negative-y movement above a 5px threshold, to open the longpress menu. The 5px threshold is the minimum default used by Keyman Engine for Web. However, it may not be ideal, and we should consider moving to using the 0.25 x row height value that Keyman Engine for Web uses in a future update. However, I do not consider this to be a reason to block this fix, as it would require significant extra engineering. --- android/KMEA/.idea/.gitignore | 3 +++ .../java/com/tavultesoft/kmea/KMKeyboard.java | 20 ++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) create mode 100644 android/KMEA/.idea/.gitignore diff --git a/android/KMEA/.idea/.gitignore b/android/KMEA/.idea/.gitignore new file mode 100644 index 0000000000..26d33521af --- /dev/null +++ b/android/KMEA/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboard.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboard.java index b84332b866..1c1dfb5a6a 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboard.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KMKeyboard.java @@ -187,10 +187,21 @@ final class KMKeyboard extends WebView { return true; } + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + if(e2.getY() - e1.getY() < -5) { // TODO: get better threshold value from KMW + if (subKeysList != null && (subKeysWindow == null || !subKeysWindow.isShowing())) { + showSubKeys(context); + return true; + } + } + return false; + } + @Override public void onLongPress(MotionEvent event) { // This is also called for banner longpresses! Need a way to differentiate the sources. - if (subKeysList != null && subKeysWindow != null && !subKeysWindow.isShowing()) { + if (subKeysList != null && (subKeysWindow == null || !subKeysWindow.isShowing())) { showSubKeys(context); return; } else if (KMManager.getGlobeKeyState() == KMManager.GlobeKeyState.GLOBE_KEY_STATE_DOWN) { @@ -286,17 +297,12 @@ final class KMKeyboard extends WebView { // Come to think of it, I wonder if suggestionMenuWindow was work being done to link with // suggestion banner longpresses - if so, it's not yet ready for proper integration... // and would need its own rung in this if-else ladder. - if (subKeysWindow != null && suggestionMenuWindow == null) { + if (subKeysWindow != null && suggestionMenuWindow == null && subKeysWindow.isShowing()) { // Passes KMKeyboard (subclass of WebView)'s touch events off to our subkey window // if active, allowing for smooth, integrated gesture control. subKeysWindow.getContentView().findViewById(R.id.grid).dispatchTouchEvent(event); } else { - //handleTouchEvent(event); gestureDetector.onTouchEvent(event); - if (action == MotionEvent.ACTION_MOVE && subKeysList != null && subKeysWindow == null) { - // Display subkeys during move - showSubKeys(context); - } } if (action == MotionEvent.ACTION_UP) {