Bug 93503

Summary: Add support for disabling hysteresis
Product: Wayland Reporter: Cyril B. <lagoon42>
Component: libinputAssignee: Wayland bug list <wayland-bugs>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: medium CC: peter.hutterer, wberrier
Version: unspecified   
Hardware: Other   
OS: All   
Whiteboard:
i915 platform: i915 features:
Bug Depends on:    
Bug Blocks: 93504    
Attachments: Finger rolling to move the cursor a bit
Several taps/physical clicks
0001-touchpad-drop-motion-hysteresis.patch

Description Cyril B. 2015-12-25 14:59:33 UTC
Created attachment 120684 [details]
Finger rolling to move the cursor a bit

Hysteresis makes small/precise moves much more difficult. I often "roll" my finger to move the cursor just a bit (say, less than 10 pixels). A typical scenario is after I've tried moving the cursor over an Web link, but I've missed it and I need to move the cursor just a bit more. My finger is still on the trackpad, so I roll it.

I understand the whole point of hysteresis is to eliminate such small moves, most specifically undesired moves when tapping or clicking. However, after I've disabled hysteresis (by commenting the only call to tp_motion_hysteresis in evdev-mt-touchpad.c), I've found that on my system, the cursor didn't move at all when tapping or clicking.

I'm using a Dell XPS 13 9350 with libinput 1.1.3 + Xorg. I've attached 2 evemu recording: one where I roll my finger but the cursor doesn't move due to hysteresis (on an unpatched libinput). On the second recording I did several taps or clicks, but the cursor didn't move, on a patched libinput with hysteresis disabled.
Comment 1 Cyril B. 2015-12-25 15:00:46 UTC
Created attachment 120685 [details]
Several taps/physical clicks
Comment 2 Peter Hutterer 2016-01-05 05:36:44 UTC
Indeed, I see only a few motion events on my T440 where I can hold the finger still and get few events. The hysteresis was originally added to the synaptics driver because just holding down a finger on a device would wobble the cursor by a couple of pixels, looks like recent hardware has that in check. I'll have to test a few older devices again.

Which means that rather than having an option to disable this, we can just enable it on a per-device basis where it is needed.

Note that we do subpixel motion from libinput though, so it's not enough to just look at the cursor. Run sudo libinput-debug-events with the hysteresis disabled, do you see motion events there?
Comment 3 Cyril B. 2016-01-09 17:59:42 UTC
I do have motion events occasionally, but it's rather rare. On most of my clicks or taps, I have no motion event at all.

However, I definitely still have hysteresis after a physical click. Rolling my finger after a physical click (without lifting my finger) doesn't move the cursor. Does libinput handles hysteresis differently right after a click?

evemu-record still generates position events in that case, so I assume it comes from libinput, and that my patch doesn't disable hysteresis in all cases.

However, I don't really mind hysteresis right after a click (or even a tap), to be honest.
Comment 4 Peter Hutterer 2016-01-10 23:10:55 UTC
yeah, we have a 1.5mm motion threshold for button clicks, see tp_unpin_finger()

note that the hysteresis atm is just 0.5mm, so like bug 93504 let's see fist if your resolution is wrong. If the resolution is accurate, then we can look into a fix here, I suspect the biggest problem is simply that the hysteresis center is moving with the touch input. try disabling the hysteresis_center assignments in tp_motion_hysteresis and see if that helps. you'll probably get jumps that way though, it's just a quickfix for testing.
Comment 5 Cyril B. 2016-01-11 21:17:03 UTC
I've disabled the hysteresis_center assignments, and indeed the cursor jumps/moves in pretty much all directions (it's completely unusable).

However, it does remove the hysteresis for me: rolling my finger on the touchpad does move the cursor (well, it jumps) even if I move just a bit.
Comment 6 Peter Hutterer 2016-01-12 03:12:09 UTC
I ran some analysis on attachment 120684 [details] and it worries me a bit:
Touchpad dimensions: 101x56mm
Touchpad diagonal: 1393.22 (0.25 == 348.30)
Touchpad diagonal: 116.10mm (0.25 == 29.03mm)
48 deltas, average 0.12, max 0.12, total distance 5.66 in mm
... x: average 0.08mm, max 0.08mm, total distance 4.00mm
... y: average 0.08mm, max 0.08mm, total distance 4.00mm
Maximum recorded delta: 0.12mm
... x: 0.08mm
... y: 0.08mm

source:
https://github.com/whot/input-data-analysis/tree/master/touchpad-max-delta

So while you move just over 5mm in total, your average delta is 0.12mm which is 1 device unit in any direction. I'm very hesitant to disable the hysteresis for a movement of that extent, because we're dealing with motions so small that it's impossible to tell intentional movement from accidental movement or hw sensor inefficiency.
Comment 7 Peter Hutterer 2016-01-29 06:32:38 UTC
Created attachment 121379 [details] [review]
0001-touchpad-drop-motion-hysteresis.patch

Patch to drop the hysteresis by default. Turns out synaptics has a hysteresis of 0 by default (though the code suggests otherwise) and after playing around with this for a bit it does feel a lot better on tiny motions.

Still waiting on feedback on a reporter to a related bug to check if other devices need a hysteresis.
Comment 8 Cyril B. 2016-01-29 19:39:57 UTC
Thanks, it works fine for me.
Comment 9 Peter Hutterer 2016-01-31 23:47:56 UTC
link to the bug with the touchpad that probably requires a hysteresis:
https://bugzilla.redhat.com/show_bug.cgi?id=1230462
Comment 11 Peter Hutterer 2016-02-04 23:30:08 UTC
commit f6c2d4b8b5e1968411568d81b47488a655ba47a1
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Fri Jan 29 16:25:31 2016 +1000

    touchpad: drop motion hysteresis by default

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.