touchscreen: Kinetic scrolling v3

Tune accel/decel/press coefficients and add a braking force which
kicks in when swiping in the opposite direction of scrolling. This
is instead of the usual acceleration force.

Change-Id: I2b220c98674933a6957d6982020406342cd019bd
This commit is contained in:
Aidan MacDonald 2022-11-27 01:48:10 +00:00 • committed by Solomon Peachy
parent c93c7bfdcb
commit 0e0982cb29
4 changed files with 52 additions and 29 deletions

View file

@ -561,22 +561,31 @@ struct kinetic {
static struct kinetic kinetic;
static struct gesture_vel list_gvel;
/*
* NOTE: defaults were chosen for the Shanling Q1, and may need
* tuning for other devices
*/
const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default = {
.a0 = 1000 << LIST_KINETIC_FRACBITS,
.a1 = 1 << (LIST_KINETIC_FRACBITS - 1),
/* delay is ignored for this one */
.a0 = 200 << LIST_KINETIC_FRACBITS, /* 200.0 */
.a1 = (6 << LIST_KINETIC_FRACBITS) / 5, /* 1.2 */
};
const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default = {
.a0 = 200 << LIST_KINETIC_FRACBITS, /* 200.0 */
.a1 = (1 << LIST_KINETIC_FRACBITS) / 2, /* 0.5 */
};
const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default = {
.a0 = 3000 << LIST_KINETIC_FRACBITS,
.a1 = 1 << (LIST_KINETIC_FRACBITS - 1),
.delay = 125 * HZ / 1000,
.a0 = 2000 << LIST_KINETIC_FRACBITS, /* 2000.0 */
.a1 = (1 << LIST_KINETIC_FRACBITS) / 2, /* 0.5 */
.delay = 125 * HZ / 1000, /* 125 ms */
};
const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default = {
.a0 = 35000 << LIST_KINETIC_FRACBITS,
.a1 = 4 << LIST_KINETIC_FRACBITS,
.delay = 250 * HZ / 1000,
.a0 = 35000 << LIST_KINETIC_FRACBITS, /* 35000.0 */
.a1 = 4 << LIST_KINETIC_FRACBITS, /* 4.0 */
.delay = 250 * HZ / 1000, /* 250 ms */
};
static void kinetic_stop_scrolling(struct kinetic *k, struct gui_synclist *list)
@ -683,22 +692,26 @@ static bool kinetic_start_scrolling(struct kinetic *k, struct gui_synclist *list
return false;
long yvel_fp = yvel << LIST_KINETIC_FRACBITS;
int vel_sgn = SIGN(k->cb_data.velocity);
if (list->scroll_mode == SCROLL_KINETIC)
{
long accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
&global_settings.kinetic_scroll_accel);
accel = fp_mul(accel, RELOAD_INTERVAL_FP, LIST_KINETIC_FRACBITS);
/* the acceleration is in the direction of the swipe */
if (SIGN(accel) != SIGN(yvel_fp))
accel = -accel;
long accel;
if (SIGN(yvel) == vel_sgn)
accel = kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
&global_settings.kinetic_scroll_accel);
else
accel = -kinetic_calc_accel(k->cb_data.velocity, LONG_MAX,
&global_settings.kinetic_scroll_brake);
yvel_fp += accel;
}
k->cb_data.list = list;
k->cb_data.velocity += yvel_fp;
if (list->scroll_mode != SCROLL_KINETIC)
/* also reset distance & scroll duration after a direction change */
if (list->scroll_mode != SCROLL_KINETIC ||
vel_sgn != SIGN(k->cb_data.velocity))
{
k->cb_data.distance = 0;
k->cb_data.scroll_duration = 0;

View file

@ -203,20 +203,25 @@ struct list_kinetic_scroll_settings
long delay;
};
/* Acceleration applied to the scroll velocity when a swipe occurs during
* kinetic scrolling. This is needed to counteract the deceleration term
* for high scrolling speeds, since the user can only input a low constant
* acceleration from swiping alone. Delay is ignored. */
/*
* accel: Extra impulse applied when swiping in the direction of scrolling,
* proportional to the current velocity. This is what allows for high
* scroll speeds. Delay is ignored.
*
* brake: Braking impulse applied when swiping in the opposite direction of
* scrolling, which helps to change direction quickly even at high
* speed. Delay is ignored.
*
* decel: Deceleration applied during scrolling. The delay is measured from
* the start of scrolling or last change of direction.
*
* press: Deceleration applied while the screen is pressed (motion is not
* needed to trigger). Additive with "decel". The delay is measured
* from the start of the press.
*/
extern const struct list_kinetic_scroll_settings list_kinetic_scroll_accel_default;
/* Deceleration applied to the scroll velocity during kinetic scrolling.
* The delay occurs right at the beginning of scrolling, eg. a delay of
* 1 second means deceleration starts 1 second after scrolling. */
extern const struct list_kinetic_scroll_settings list_kinetic_scroll_brake_default;
extern const struct list_kinetic_scroll_settings list_kinetic_scroll_decel_default;
/* Deceleration applied during kinetic scrolling when the screen is
* pressed for longer than the delay interval (motion is not required).
* This is additive with list_kinetic_scroll_decel. */
extern const struct list_kinetic_scroll_settings list_kinetic_scroll_press_default;
#endif

View file

@ -801,6 +801,7 @@ struct user_settings
int touch_mode;
struct touchscreen_parameter ts_calibration_data;
struct list_kinetic_scroll_settings kinetic_scroll_accel;
struct list_kinetic_scroll_settings kinetic_scroll_brake;
struct list_kinetic_scroll_settings kinetic_scroll_decel;
struct list_kinetic_scroll_settings kinetic_scroll_press;
#endif

View file

@ -2429,6 +2429,10 @@ const struct settings_list settings[] = {
&list_kinetic_scroll_accel_default, "kinetic scroll accel",
list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,
list_kinetic_is_default, list_kinetic_set_default),
CUSTOM_SETTING(0, kinetic_scroll_brake, -1,
&list_kinetic_scroll_brake_default, "kinetic scroll brake",
list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,
list_kinetic_is_default, list_kinetic_set_default),
CUSTOM_SETTING(0, kinetic_scroll_decel, -1,
&list_kinetic_scroll_decel_default, "kinetic scroll decel",
list_kinetic_load_from_cfg, list_kinetic_write_to_cfg,