Commit ac91d8df authored by Peter Hutterer's avatar Peter Hutterer

touchpad: disable jump detection on the Lenovo X1 Gen6 touchpad

This touchpad has firmware that seems to buffer events. In the words of the

  In usage, it feels like motions vary between smooth and choppy; slow
  movements are smooth and quick movements are choppy. It's as if the
  touchpad aggregates quick movements and sends one big movement instead
  of sending discrete events. To make the movement more natural, the
  events preceding the jump should be of higher magnitude and the jump
  less pronounced, but that's just not how the touchpad works, it seems.

In the actual event data this looks exactly like a pointer jump: small
movements, one big one, then small ones again. If we filter that large
movement out we prevent the user from moving quickly.

There's no way to detect this or work around this, so let's add a quirk that
disables the jump detection for this device.

Fixes #506Signed-off-by: Peter Hutterer's avatarPeter Hutterer <>
parent d6c6c40f
Pipeline #178608 passed with stages
in 31 minutes and 51 seconds
......@@ -136,6 +136,7 @@ AttrTrackpointMultiplier=1.25
MatchName=Synaptics TM3288-011
[Lenovo X41 Tablet]
MatchName=AT Translated Set 2 keyboard
......@@ -1499,6 +1499,13 @@ tp_detect_jumps(const struct tp_dispatch *tp,
* were measured from */
unsigned int reference_interval = ms2us(12);
/* On some touchpads the firmware does funky stuff and we cannot
* have our own jump detection, e.g. Lenovo Carbon X1 Gen 6 (see
* issue #506)
if (tp->jump.detection_disabled)
return false;
/* We haven't seen pointer jumps on Wacom tablets yet, so exclude
* those.
......@@ -3628,6 +3635,14 @@ tp_init(struct tp_dispatch *tp,
/* Lenovo X1 Gen6 buffers the events in a weird way, making jump
* detection impossible. See
if (evdev_device_has_model_quirk(device,
tp->jump.detection_disabled = true;
device->seat_caps |= EVDEV_DEVICE_POINTER;
if (tp->gesture.enabled)
device->seat_caps |= EVDEV_DEVICE_GESTURE;
......@@ -295,6 +295,7 @@ struct tp_dispatch {
unsigned int fake_touches;
struct {
bool detection_disabled;
struct ratelimit warning;
} jump;
......@@ -244,6 +244,7 @@ quirk_get_name(enum quirk q)
case QUIRK_MODEL_LENOVO_T450_TOUCHPAD: return "ModelLenovoT450Touchpad";
case QUIRK_MODEL_LENOVO_T480S_TOUCHPAD: return "ModelLenovoT480sTouchpad";
case QUIRK_MODEL_LENOVO_T490S_TOUCHPAD: return "ModelLenovoT490sTouchpad";
case QUIRK_MODEL_LENOVO_X1GEN6_TOUCHPAD: return "ModelLenovoX1Gen6Touchpad";
case QUIRK_MODEL_LENOVO_X230: return "ModelLenovoX230";
case QUIRK_MODEL_SYNAPTICS_SERIAL_TOUCHPAD: return "ModelSynapticsSerialTouchpad";
case QUIRK_MODEL_SYSTEM76_BONOBO: return "ModelSystem76Bonobo";
......@@ -77,6 +77,7 @@ enum quirk {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment