mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-24 22:50:05 +01:00
evdev: use a different filter for low resolution touchpad on the Lenovo X230
Those touchpads presents an actual lower resolution that what is advertised. We see some jumps from the cursor due to the big steps in X and Y when we are receiving data. For instance, we receive: E: 13.471932 0003 0000 16366 # EV_ABS / ABS_X 16366 E: 13.471932 0003 0001 9591 # EV_ABS / ABS_Y 9591 E: 13.471932 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- E: 13.479924 0003 0000 16316 # EV_ABS / ABS_X 16316 E: 13.479924 0003 0001 9491 # EV_ABS / ABS_Y 9491 E: 13.479924 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- E: 13.487939 0003 0000 16271 # EV_ABS / ABS_X 16271 E: 13.487939 0003 0001 9403 # EV_ABS / ABS_Y 9403 E: 13.487939 0000 0000 0000 # ------------ SYN_REPORT (0) ---------- -> jumps of ~50 in X in each report, and ~100 for Y. Apply a factor to minimize those jumps at low speed, and try keeping the same feeling as regular touchpads at high speed. It still feels slower but it is usable at least Signed-off-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net> Tested-by: Vasily Khoruzhick <anarsoul@gmail.com> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
06b4d83c4a
commit
26ceea3e3b
6 changed files with 63 additions and 3 deletions
|
|
@ -998,6 +998,7 @@ static int
|
|||
tp_init_accel(struct tp_dispatch *tp, double diagonal)
|
||||
{
|
||||
int res_x, res_y;
|
||||
accel_profile_func_t profile;
|
||||
|
||||
res_x = tp->device->abs.absinfo_x->resolution;
|
||||
res_y = tp->device->abs.absinfo_y->resolution;
|
||||
|
|
@ -1021,9 +1022,16 @@ tp_init_accel(struct tp_dispatch *tp, double diagonal)
|
|||
tp->accel.y_scale_coeff = DEFAULT_ACCEL_NUMERATOR / diagonal;
|
||||
}
|
||||
|
||||
if (evdev_device_init_pointer_acceleration(
|
||||
tp->device,
|
||||
touchpad_accel_profile_linear) == -1)
|
||||
switch (tp->device->model) {
|
||||
case EVDEV_MODEL_LENOVO_X230:
|
||||
profile = touchpad_lenovo_x230_accel_profile;
|
||||
break;
|
||||
default:
|
||||
profile = touchpad_accel_profile_linear;
|
||||
break;
|
||||
}
|
||||
|
||||
if (evdev_device_init_pointer_acceleration(tp->device, profile) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -1429,6 +1429,7 @@ evdev_read_model(struct evdev_device *device)
|
|||
const char *property;
|
||||
enum evdev_device_model model;
|
||||
} model_map[] = {
|
||||
{ "LIBINPUT_MODEL_LENOVO_X230", EVDEV_MODEL_LENOVO_X230 },
|
||||
{ NULL, EVDEV_MODEL_DEFAULT },
|
||||
};
|
||||
const struct model_map *m = model_map;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ enum evdev_middlebutton_event {
|
|||
|
||||
enum evdev_device_model {
|
||||
EVDEV_MODEL_DEFAULT,
|
||||
EVDEV_MODEL_LENOVO_X230,
|
||||
};
|
||||
|
||||
struct mt_slot {
|
||||
|
|
|
|||
37
src/filter.c
37
src/filter.c
|
|
@ -345,3 +345,40 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
|
|||
|
||||
return speed_out * TP_MAGIC_SLOWDOWN;
|
||||
}
|
||||
|
||||
double
|
||||
touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time)
|
||||
{
|
||||
/* Keep the magic factor from touchpad_accel_profile_linear. */
|
||||
const double TP_MAGIC_SLOWDOWN = 0.4;
|
||||
|
||||
/* Those touchpads presents an actual lower resolution that what is
|
||||
* advertised. We see some jumps from the cursor due to the big steps
|
||||
* in X and Y when we are receiving data.
|
||||
* Apply a factor to minimize those jumps at low speed, and try
|
||||
* keeping the same feeling as regular touchpads at high speed.
|
||||
* It still feels slower but it is usable at least */
|
||||
const double TP_MAGIC_LOW_RES_FACTOR = 4.0;
|
||||
double speed_out;
|
||||
struct pointer_accelerator *accel_filter =
|
||||
(struct pointer_accelerator *)filter;
|
||||
|
||||
double s1, s2;
|
||||
const double max_accel = accel_filter->accel *
|
||||
TP_MAGIC_LOW_RES_FACTOR; /* unitless factor */
|
||||
const double threshold = accel_filter->threshold /
|
||||
TP_MAGIC_LOW_RES_FACTOR; /* units/ms */
|
||||
const double incline = accel_filter->incline * TP_MAGIC_LOW_RES_FACTOR;
|
||||
|
||||
speed_in *= TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
|
||||
|
||||
s1 = min(1, speed_in * 5);
|
||||
s2 = 1 + (speed_in - threshold) * incline;
|
||||
|
||||
speed_out = min(max_accel, s2 > 1 ? s2 : s1);
|
||||
|
||||
return speed_out * TP_MAGIC_SLOWDOWN / TP_MAGIC_LOW_RES_FACTOR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,4 +67,9 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
|
|||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
double
|
||||
touchpad_lenovo_x230_accel_profile(struct motion_filter *filter,
|
||||
void *data,
|
||||
double speed_in,
|
||||
uint64_t time);
|
||||
#endif /* FILTER_H */
|
||||
|
|
|
|||
|
|
@ -14,3 +14,11 @@
|
|||
|
||||
#
|
||||
# Sort by brand, model
|
||||
|
||||
##########################################
|
||||
# LENOVO
|
||||
##########################################
|
||||
|
||||
# X230 (Tablet)
|
||||
libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPadX230*
|
||||
LIBINPUT_MODEL_LENOVO_X230=1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue