Improve modulated key repeat

Change the formula: don't use an external constant, add a state.
It's now the ratio between where the finger is at the first repeat and
where it is now.

Keep the repeat going when swiping into an other key. Currently only for
arrows: It's now possible to go from an arrow to an other without
waiting again for the key repeat timeout.

The backspace and delete keys don't work well with this.
This commit is contained in:
Jules Aguillon 2022-02-21 00:24:57 +01:00
parent 51ff795be4
commit c85e9a91d1
2 changed files with 31 additions and 11 deletions

View File

@ -245,8 +245,8 @@ class KeyValue
addEventKey("page_down", "", KeyEvent.KEYCODE_PAGE_DOWN);
addEventKey("home", "", KeyEvent.KEYCODE_MOVE_HOME);
addEventKey("end", "", KeyEvent.KEYCODE_MOVE_END);
addEventKey("backspace", "", KeyEvent.KEYCODE_DEL, FLAG_PRECISE_REPEAT);
addEventKey("delete", "", KeyEvent.KEYCODE_FORWARD_DEL, FLAG_PRECISE_REPEAT);
addEventKey("backspace", "", KeyEvent.KEYCODE_DEL);
addEventKey("delete", "", KeyEvent.KEYCODE_FORWARD_DEL);
addEventKey("insert", "Ins", KeyEvent.KEYCODE_INSERT);
addEventKey("f1", "F1", KeyEvent.KEYCODE_F1);
addEventKey("f2", "F2", KeyEvent.KEYCODE_F2);

View File

@ -135,14 +135,22 @@ public final class Pointers implements Handler.Callback
}
if (newValue != null && newValue != ptr.value)
{
stopKeyRepeat(ptr);
int old_flags = (ptr.value != null) ? ptr.value.flags : 0;
ptr.value = newValue;
ptr.flags = newValue.flags;
if ((old_flags & newValue.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
{
// Keep the keyrepeat going between modulated keys.
}
else
{
stopKeyRepeat(ptr);
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
startKeyRepeat(ptr);
_handler.onPointerSwipe(newValue);
}
}
}
// Pointers management
@ -192,12 +200,9 @@ public final class Pointers implements Handler.Callback
if (ptr.timeoutWhat == msg.what)
{
long nextInterval = _config.longPressInterval;
if (_config.preciseRepeat && (ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
{
// Modulate repeat interval depending on the distance of the pointer
float accel = Math.min(4.f, Math.max(0.3f, ptr.ptrDist / (_config.swipe_dist_px * 15.f)));
nextInterval = (long)((float)nextInterval / accel);
}
if (_config.preciseRepeat && (ptr.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
nextInterval = (long)((float)nextInterval / modulatePreciseRepeat(ptr));
_keyrepeat_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
_handler.onPointerHold(ptr.value);
return (true);
@ -221,9 +226,21 @@ public final class Pointers implements Handler.Callback
{
_keyrepeat_handler.removeMessages(ptr.timeoutWhat);
ptr.timeoutWhat = -1;
ptr.repeatingPtrDist = -1.f;
}
}
private float modulatePreciseRepeat(Pointer ptr)
{
if (ptr.repeatingPtrDist < 0.f)
ptr.repeatingPtrDist = ptr.ptrDist; // First repeat
if (ptr.ptrDist > ptr.repeatingPtrDist * 2.f)
ptr.repeatingPtrDist = ptr.ptrDist / 2.f; // Large swipe, move the middle point
float left = ptr.repeatingPtrDist / 2.f;
float accel = (ptr.ptrDist - left) / (ptr.repeatingPtrDist - left);
return Math.min(4.f, Math.max(0.1f, accel));
}
private final class Pointer
{
/** -1 when latched. */
@ -237,6 +254,8 @@ public final class Pointers implements Handler.Callback
public int flags;
/** Identify timeout messages. */
public int timeoutWhat;
/** ptrDist at the first repeat, -1 otherwise. */
public float repeatingPtrDist;
public Pointer(int p, KeyboardData.Key k, KeyValue v, float x, float y)
{
@ -248,6 +267,7 @@ public final class Pointers implements Handler.Callback
ptrDist = 0.f;
flags = (v == null) ? 0 : v.flags;
timeoutWhat = -1;
repeatingPtrDist = -1.f;
}
}