From b15ca662c2329fd638cbf74b097988c1be477cc8 Mon Sep 17 00:00:00 2001 From: Jules Aguillon Date: Sun, 8 May 2022 16:38:44 +0200 Subject: [PATCH] Better handling of removed keys and swipe geture The "closest key" logic must be careful not to reveal keys removed by a modifier. Must check [_handler.onPointerSwipe] for every candidate values. [selected_value] is changed back to [selected_direction]. This adds a new bug: When the direction change, the selected value might not change but a vibration will be triggered anyway. --- srcs/juloo.keyboard2/Keyboard2View.java | 4 ++- srcs/juloo.keyboard2/KeyboardData.java | 24 +++---------- srcs/juloo.keyboard2/Pointers.java | 48 ++++++++++++++++++------- 3 files changed, 42 insertions(+), 34 deletions(-) diff --git a/srcs/juloo.keyboard2/Keyboard2View.java b/srcs/juloo.keyboard2/Keyboard2View.java index 9234366..3ae0fdf 100644 --- a/srcs/juloo.keyboard2/Keyboard2View.java +++ b/srcs/juloo.keyboard2/Keyboard2View.java @@ -108,9 +108,11 @@ public class Keyboard2View extends View public KeyValue onPointerSwipe(KeyValue k, int flags) { k = KeyModifier.handleFlags(k, flags); - invalidate(); if (k != null) + { + invalidate(); vibrate(); + } return k; } diff --git a/srcs/juloo.keyboard2/KeyboardData.java b/srcs/juloo.keyboard2/KeyboardData.java index 6274eb0..adbf790 100644 --- a/srcs/juloo.keyboard2/KeyboardData.java +++ b/srcs/juloo.keyboard2/KeyboardData.java @@ -195,7 +195,10 @@ class KeyboardData return new Key(key0, key1, key2, key3, key4, width * s, shift, edgekeys); } - private KeyValue getAtDirectionExact(int direction) + /* + * See Pointers.onTouchMove() for the represented direction. + */ + public KeyValue getAtDirection(int direction) { if (edgekeys) { @@ -229,25 +232,6 @@ class KeyboardData } return null; } - - /* - * Get the KeyValue at the given direction. In case of swipe (!= 0), get the - * nearest KeyValue that is not key0. See Pointers.onTouchMove() for the - * represented direction. - */ - public KeyValue getAtDirection(int direction) - { - if (direction == 0) - return key0; - KeyValue k; - for (int i = 0; i > -2; i = (~i>>31) - i) - { - k = getAtDirectionExact(Math.floorMod(direction + i - 1, 8) + 1); - if (k != null) - return k; - } - return null; - } } // Not using Function to keep compatibility with Android 6. diff --git a/srcs/juloo.keyboard2/Pointers.java b/srcs/juloo.keyboard2/Pointers.java index 1328d62..b4c1a6f 100644 --- a/srcs/juloo.keyboard2/Pointers.java +++ b/srcs/juloo.keyboard2/Pointers.java @@ -135,12 +135,37 @@ public final class Pointers implements Handler.Callback return; int mflags = getFlags(isOtherPointerDown()); KeyValue value = _handler.onPointerDown(key.key0, mflags); - Pointer ptr = new Pointer(pointerId, key, key.key0, value, x, y, mflags); + Pointer ptr = new Pointer(pointerId, key, value, x, y, mflags); _ptrs.add(ptr); if (value != null && (value.flags & KeyValue.FLAG_SPECIAL) == 0) startKeyRepeat(ptr); } + /* + * Get the KeyValue at the given direction. In case of swipe (!= 0), get the + * nearest KeyValue that is not key0. + * Take care of applying [_handler.onPointerSwipe] to the selected key, this + * must be done at the same time to be sure to treat removed keys correctly. + * Return [null] if no key could be found in the given direction or if the + * selected key didn't change. + */ + private KeyValue getKeyAtDirection(Pointer ptr, int direction) + { + if (direction == 0) + return _handler.onPointerSwipe(ptr.key.key0, ptr.modifier_flags); + KeyValue k; + for (int i = 0; i > -2; i = (~i>>31) - i) + { + int d = Math.floorMod(direction + i - 1, 8) + 1; + // Don't make the difference between a key that doesn't exist and a key + // that is removed by [_handler]. Triggers side effects. + k = _handler.onPointerSwipe(ptr.key.getAtDirection(d), ptr.modifier_flags); + if (k != null) + return k; + } + return null; + } + public void onTouchMove(float x, float y, int pointerId) { Pointer ptr = getPtr(pointerId); @@ -175,14 +200,11 @@ public final class Pointers implements Handler.Callback if (dy > 0) direction = 9 - direction; } - KeyValue newSelectedValue = ptr.key.getAtDirection(direction); - if (newSelectedValue != ptr.selected_value) + if (direction != ptr.selected_direction) { - ptr.selected_value = newSelectedValue; - // apply modifier flags and trigger vibration. - KeyValue newValue = - _handler.onPointerSwipe(ptr.selected_value, ptr.modifier_flags); - if (newValue != null) + ptr.selected_direction = direction; + KeyValue newValue = getKeyAtDirection(ptr, direction); + if (newValue != null && (ptr.value == null || newValue.name != ptr.value.name)) { int old_flags = ptr.flags; ptr.value = newValue; @@ -315,9 +337,9 @@ public final class Pointers implements Handler.Callback public int pointerId; /** The Key pressed by this Pointer */ public final KeyboardData.Key key; - /** The current seletected KeyValue in key (any one of key0 to key4). */ - public KeyValue selected_value; - /** selected_value with modifier_flags applied. */ + /** Current direction. */ + public int selected_direction; + /** Selected value with [modifier_flags] applied. */ public KeyValue value; public float downX; public float downY; @@ -332,11 +354,11 @@ public final class Pointers implements Handler.Callback /** ptrDist at the first repeat, -1 otherwise. */ public float repeatingPtrDist; - public Pointer(int p, KeyboardData.Key k, KeyValue sv, KeyValue v, float x, float y, int mflags) + public Pointer(int p, KeyboardData.Key k, KeyValue v, float x, float y, int mflags) { pointerId = p; key = k; - selected_value = sv; + selected_direction = 0; value = v; downX = x; downY = y;