Bug 99410

Summary: Lenovo Yoga X1 touchpad unprecise
Product: Wayland Reporter: bjoern <wilecoyote2015>
Component: libinputAssignee: Peter Hutterer <peter.hutterer>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: peter.hutterer
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Bug Depends on: 98839    
Bug Blocks:    
Attachments: Attempt to draw a circle
0001-evdev-change-hysteresis-to-work-across-both-axes.patch

Description bjoern 2017-01-14 19:33:32 UTC
Hello All,
The touchpad of my Lenovo X1 Yoga behaves very unprecisely, which mainly consists  of two aspects:

1. The acceleration behavior feels sluggish: When stopping the finger, the cursor does not stop immediately, but decelerates for about a third of a second, so that it moves a bit further than intended. Precise movement is not possible on that way.

2. When moving horizontally or vertically, the cursor sticks to exact horizontal/vertical movement, so that a transition from that movement to a diagonal movement (or everything that is not strictly vertical of horizontal) happens with a jump in the moving direction.

I am using Arch Linux with Gnome 3.22 and the issue occurs on Wayland as well as Xorg.
Comment 1 bjoern 2017-01-14 20:39:10 UTC
I must add as a third point that the acceleration behavior at low speeds is also problematic: If the finger is moved very slowly, there is a treshold of a few millimeters until the cursor starts moving. When moving a bit faster, the relation between finger movement speed and cursor movement is linear for very small velocities, but then acceleration punches in very abruptly.
This all leads to a significant loss of control when working on small distances (like setting the cursor position accurately while editing texts or performing image editing).
Comment 2 Peter Hutterer 2017-01-15 23:20:28 UTC
what version of libinput do you have? the 1.6rc1/git master have a better acceleration than previous versions.

Also, please make sure that the touchpad-edge-detector tool agrees with what your touchpad announces. Sometimes if the whole thing is a few mm offset it can make the touchpad behave quite differently
Comment 3 bjoern 2017-01-16 11:31:21 UTC
Thank you, Peter.
I have checked the axes according to 
https://wayland.freedesktop.org/libinput/doc/latest/absolute_coordinate_ranges.html
and indeed, the physical dimension reported by the kernel were incorrect and I have opened a pull request at systemd. However, after testing the updated evdev rule locally, the problems described in this bug report remain.

I am using today's GIT master compiled from Arch User Repository

Best Regards,
Bjoern
Comment 4 bjoern 2017-01-17 11:36:38 UTC
Created attachment 128997 [details]
Attempt to draw a circle

In order to illustrate issue 2), this is the result of drawing with spiral-like finger movements.
Comment 5 bjoern 2017-01-24 10:36:24 UTC
Hello,
I have investigated the issue a bit further:

When Evdev is used as driver instead of libinput, Issue 1 is completely gone.

Issue two and three seem so be related: Using xev On each axis independently, with both libinput and evdev, on each axis a certain threshold of some millimeters must be exceeded in order to start a motion. 
So when the finger is resting and a slow motion is started, no changes of positions are reported to xev over the first few millimeters. Also, when moving the finger along only one axis a first and then beginning a curved motion so that there is a change of position on axis b, too, changes of axis b are only reported after the change in axis b exceeds a certain threshold.
This makes it very hard to predict motion and makes the touchpad feel rather unprecise. As the previously attached image demonstrates, it is hard to conduct controlled movements.
I have tried to set the Synaptics Noise Cancellation parameter to 0, 0 and the issue is gone completely. The touchpad is very precise now.
Disabling the noise cancellation that way did not introduce negative side effects to me because the touchpad does not seem to be prone to input noise at all.
Comment 6 Peter Hutterer 2017-01-30 23:18:34 UTC
Ok, this is related to bug 98839 then. Bugzilla doesn't have a "related" field, so I'll just add it as a blocker here.
Comment 7 Peter Hutterer 2017-01-31 01:58:34 UTC
ok, I've done an analysis on my T450p which in theory has the same touchpad as the X1 Yoga. Please attach your dmesg and an evemu-record sequence of such a circle though so I can verify a few things.

What I found in regards to issue 2 on my touchpad here:
Moving diagonally produces a wavy motion. I can't quite reproduce the circle here, can you reproduce the wavy motion?
On my device, this is caused by the problem described here:
https://who-t.blogspot.com.au/2016/09/libinput-and-lenovo-t450-and-t460.html

That wavy motion *may* exist on my T440 as well, but it's unclear whether there it is caused by my finger motion or any other issue. Either way, the same code and such a pronounced difference hints at a HW/FW bug, see the blog post. Changing the hysteresis did not have any effect.

The hysteresis is done on a per-axis basis, this could cause the issue you're seeing. That removing the hysteresis removes the issue verifies this.
Right now I'm assuming that the latest touchpads have a new FW version again that prevents that bug in the T450p series.

Please remove the call to tp_motion_hysteresis() in libinput's src/evdev-mt-touchpad.c and try with that version. The diff is:
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index e43a9ba..4bac610 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1037,7 +1037,6 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
                tp_thumb_detect(tp, t, time);
                tp_palm_detect(tp, t, time);
 
-               tp_motion_hysteresis(tp, t);
                tp_motion_history_push(t);
 
                tp_unpin_finger(tp, t);

If this works, we'll probably need a two-pronged approach: make the hysteresis work across both axes simultaneously and have some knob that exposes it, see bug 98839. Removing the hysteresis altogether does not work, see 48473994c8e60 and bug 94379.

I haven't looked at the pointer acceleration issue (1) yet.
Comment 8 Peter Hutterer 2017-02-01 03:08:41 UTC
Created attachment 129267 [details] [review]
0001-evdev-change-hysteresis-to-work-across-both-axes.patch

Please give this one a try. It removes the axis snapping you've been seeing but still keeps the hysteresis in place. So there is still a dead zone on initial finger movement but with the axis snapping gone it may not be as problematic anymore.
Comment 9 Peter Hutterer 2017-02-20 23:44:15 UTC
can you try the patch please?
Comment 10 Peter Hutterer 2017-03-17 01:47:46 UTC
a month in needinfo, can't fix things without feedback.
Comment 11 bjoern 2017-06-28 18:06:13 UTC
Hello all, sorry for the long abscence; life is keeping me quite busy.
I will be able to test it in the end of july. Currently, my Notebook is important for day-to-day use.

Best regards
Comment 12 bjoern 2017-08-24 10:29:19 UTC
Hello!
Finally, I have had some time to try the patch out. Unfortunately, although it reduces the tolerance to start motion, it also causes very jittery pointer motion, so that this configuration is not usable at all.
Comment 13 bjoern 2017-11-04 18:43:45 UTC
The issue is gone with the resolution of Bug 98839, so this issue is fixed. Thanke!
Comment 14 Peter Hutterer 2017-11-05 23:00:34 UTC
oh, glad to hear that, thanks for testing!
Comment 15 bjoern 2018-04-12 06:35:08 UTC
Hello,

unfortunately, the issue occurs again for some time. Has the automatic disabling of hysteresis been removed?
Comment 16 Peter Hutterer 2018-04-13 04:51:25 UTC
Yeah, it's been replaced with an approach where the hysteresis is (should be) off by default but it detects wobbles. See Bug 104828
Comment 17 Peter Hutterer 2018-05-29 05:02:45 UTC
please test libinput 1.11rc1 or later, that should have all the latest code. By default, no hysteresis is applied unless the device has an axis fuzz set. There's code to detect axis jitter in most cases and enable it on the fly, so far this code seems to have been working well.

I'm assuming this is all fixed now, if not please attach an evemu-record with a sequence that reproduces the issue.
Comment 18 bjoern 2018-05-29 06:38:06 UTC
Hello,

I've tested with git master now and I can confirm tbat the issue is fixed.

Best,
Björn
Comment 19 Peter Hutterer 2018-05-29 07:25:48 UTC
thanks, much appreciated

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.