Bug 98839 - Somehow conditionalize hysteresis (hardware black/whitelist, device property introspection, user-exposed setting, etc)
Summary: Somehow conditionalize hysteresis (hardware black/whitelist, device property ...
Alias: None
Product: Wayland
Classification: Unclassified
Component: libinput (show other bugs)
Version: 1.5.0
Hardware: Other All
: medium normal
Assignee: Wayland bug list
QA Contact:
: 100752 101428 102883 103619 (view as bug list)
Depends on:
Blocks: 97355 98535 98845 99000 99410 103594 104533 104788
  Show dependency treegraph
Reported: 2016-11-24 03:04 UTC by Nate Graham
Modified: 2018-05-25 14:54 UTC (History)
15 users (show)

See Also:
i915 platform:
i915 features:

Pivoting my finger around the tip but not getting appropriate precise cursor movement (230.69 KB, text/plain)
2016-11-24 03:04 UTC, Nate Graham
Nate Graham - single finger held still for 10s (121.74 KB, text/plain)
2017-10-25 04:58 UTC, Nate Graham
Nate Graham - slow movements left then up (400.93 KB, text/plain)
2017-10-25 05:01 UTC, Nate Graham
x1carbongen4_results.zip (24.73 KB, application/zip)
2017-10-25 05:37 UTC, Daniel van Vugt
x1carbongen5_results.zip (30.09 KB, application/zip)
2017-10-25 05:49 UTC, Daniel van Vugt
Still can't draw small circles using the conditional hysteresis branch (191.10 KB, text/plain)
2017-11-01 03:33 UTC, Nate Graham
evemu recordings on Dell XPS L502X (49.10 KB, application/gzip)
2017-12-19 13:51 UTC, James Cowgill

Note You need to log in before you can comment on or make changes to this bug.
Description Nate Graham 2016-11-24 03:04:09 UTC
Created attachment 128175 [details]
Pivoting my finger around the tip but not getting appropriate precise cursor movement

With the patch from https://bugs.freedesktop.org/show_bug.cgi?id=90735, trackpad cursor movement is much improved for fast and medium-speed movements. But it's still sluggish and imprecise for very slow movements. To move the cursor 5-10 pixels should ideally be accomplishable with very subtle, precise finger movement--such as pivoting your finger around the very tip without actually moving the tip. Pivoting your finger like this right now generally results in no cursor movement at all, or jerky, erratic movement.

I've attached an evemu recording of me pivoting my finger around its tip, expecting to get very precise cursor movement, but instead getting either nothing, or erratic, jerky movements.
Comment 1 Peter Hutterer 2016-12-01 05:08:19 UTC
Do you have tapping enabled and if so do you notice a difference when you disable it?
Comment 2 Nate Graham 2016-12-01 05:46:27 UTC
No, I keep it disabled, but I notice no difference when I enable it.
Comment 3 Nate Graham 2016-12-19 20:52:15 UTC
I just tried out the patches you posted recently: https://lists.freedesktop.org/archives/wayland-devel/2016-December/032326.html

The result is generally better, especially at medium speeds (yay!) but does not address the issue brought up here: the cursor's stickiness and lack of movement when pivoting and rolling the fingertip, or moving it in a very small circle. It's like at very slow speeds and distances, the cursor only wants to move horizontally or vertically, not both.

I can now successfully move the cursor with pixel-level precision vertically or horizontally, but any kind of both-vertical-and-horizontal movement (diagonal motion, making circles, etc.) is sluggish, jerky, and feels unnecessarily constrained to the X and Y axes.
Comment 4 Peter Hutterer 2016-12-20 07:31:59 UTC
Have we checked the size of your touchpad yet? 105x97mm - is that accurate? If not, please run the touchpad-edge-detector tool (check that the axis ranges are correct anyway please).

From what I can tell, the issue is that your touchpad's deltas for this particular recording are extremely small - in the 1-4 device unit range. At the device's x/y resolutions that's 0.027/0.016mm precision. Our hysteresis code uses 0.5mm to avoid pointer wobble, so most of your movements fall into that code.

This is even further amplified by the issue that the hysteresis works ok while moving in the same direction, but whenever you change directions the margin takes effect. so rolling a finger left/right would show the worst effect, continuing in one direction should be fine. And indeed the delta shows a lot of back/forth movement at the device-unit level.

Either way, I think this also explains why the movement feels like it snaps to one axis, the hysteresis is calculated separately so you can get one axis suppressed back and the other axis move on normally. *maybe* this could be fixed by changing the hysteresis to use hypot() but that's quite expensive to run over every delta. Feel free to try this though locally.

We tried removing the hysteresis but it caused pointer wobbles for a lot of people. Did you ever use synaptics on this touchpad? Did that behave better?
Comment 5 Nate Graham 2016-12-20 16:50:02 UTC
I ran touchpad-edge-detector for https://bugs.freedesktop.org/show_bug.cgi?id=99000:

$ sudo touchpad-edge-detector 118x58 /dev/input/event4
Touchpad SynPS/2 Synaptics TouchPad on /dev/input/event4
Move one finger around the touchpad to detect the actual edges
Kernel says:	x [1302..5640], y [1116..4740]
Touchpad sends:	x [1302..5641], y [1115..4740] |^C

Touchpad size as listed by the kernel: 117x56mm
User-specified touchpad size: 118x58mm
Calculated ranges: 4339/3625

I've tried the Synaptics driver and it's a *little* better that libinput, but not much. The same basic problem remains.

I can play around with the hysteresis and see if that makes a difference.

After recompiling libinput and installing it to /, is there an easier way or reloading the driver than restarting?
Comment 6 Nate Graham 2016-12-20 17:31:40 UTC
Turning off the hysteresis entirely definitely has an effect, but it doesn't resolve the issue.

It doesn't feel like an event rate issue either; with my touchpad, I can make medium-sized circles as fast as I can move my finger. As I reduce the size of the circles though, at about 1 cm diameter, the cursor stops moving in a circle and sort of wobbles awkwardly around its current location.
Comment 7 Peter Hutterer 2016-12-21 00:21:14 UTC
(In reply to Nate Graham from comment #5)
> Touchpad size as listed by the kernel: 117x56mm
> User-specified touchpad size: 118x58mm

close enough, I'd say

> After recompiling libinput and installing it to /, is there an easier way or
> reloading the driver than restarting?

I'm going to assume you didn't install to / given that you notice an effect but there are a few things to watch out for: use --prefix=/usr and on fedora also add --libdir=/usr/lib64. libinput master has a lower soname than 1.5.3, so you may be installing it correctly but things are still picking up the other one. Make sure to remove libinput.so.10.10.4, as master will currently install 10.10.3
Once installed, you need to restart X only (or the compositor if you're under wayland), no need to actually reboot.

For local testing, use the ./tools/event-gui app. It's not exactly the same and affected by lag but good enough to get an idea before having to restart the session.

(In reply to Nate Graham from comment #6)
> Turning off the hysteresis entirely definitely has an effect, but it doesn't
> resolve the issue.
> It doesn't feel like an event rate issue either; with my touchpad, I can
> make medium-sized circles as fast as I can move my finger. As I reduce the
> size of the circles though, at about 1 cm diameter, the cursor stops moving
> in a circle and sort of wobbles awkwardly around its current location.

I think what you're seeing is an effect of the firmware skipping data, most likely to avoid pointer wobbles. The problem is simply that the interaction you want to have is very similar to someone holding the finger still but still getting changing sensor readings. This effect is particularly bad on the Lenovo T450 [1] In that case, there isn't much we can do though.

[1] https://who-t.blogspot.com.au/2016/09/libinput-and-lenovo-t450-and-t460.html

You could try the RMI4 patchset to see if it makes a difference: http://lkml.iu.edu/hypermail/linux/kernel/1612.2/00646.html
Comment 8 Nate Graham 2016-12-22 03:26:06 UTC
Thanks for those instructions. Turns out I hadn't actually applied the patch before and my observations were just the placebo effect. Oops. Removing libinput.so.10.10.4 and jiggling a symlink made the new one apply properly, and what a difference! It *is* better for the use case described in this problem report--not good enough to close it out, but it's definitely better. I can now draw smaller circles with the touchpad than I could before, but still not small enough. I'll play with the hysteresis again now that I'm actually able to test code changes locally.
Comment 9 Nate Graham 2016-12-22 03:35:49 UTC
Oh my god, with hysteresis off, it's PERFECT.

I understand that some hardware needs this. But for my hardware, it's night-and-day, the difference between almost unusable and perfect. It makes me think that applying hysteresis needs to be either user-configurable, or we should maintain a list of hardware that needs hysteresis and only enable it for only those pads.

I simply can't imagine using libinput with hysteresis again.
Comment 10 Peter Hutterer 2017-01-04 05:00:06 UTC
Have you tried the RMI4 patches yet by any chance? Would be interesting to know if that changes things.
Comment 11 Nate Graham 2017-01-04 15:04:46 UTC
Yes, I'm running with a version of the 4.10 kernel which has the RMI4 patches applied. I tried turning hysteresis back on and I'm sorry to say it's still awful. Might be a *little* better than with the 4.9.x kernel series, but with hysteresis on, I still can't draw tiny circles.

I really think we need to be able to turn hysteresis off entirely for certain hardware, whether via a user-exposed setting, a hardware blacklist/whitelist, or something else. For my touchpad, it's simply not needed--an anti-feature--and having it off has been a singularly more pleasant experience.
Comment 12 Peter Hutterer 2017-01-06 03:45:15 UTC
Have a look at commit afdcaf50157c0a76389740885bed3719b758dc37, that provides a blueprint for the patch required to mark your touchpad as one that doesn't require hysteresis. I'm willing to give in here to see whether we'll see any pushback (see 27078b2). Happy to review and merge a patch for this.

I think long-term we may need a "make cursor precise" vs "stabilize cursor" option or something, but let's see how long we can avoid that.
Comment 13 Frank 2017-01-07 23:14:06 UTC
I gave libinput a try on ArchLinux (libinput-1.5.3). I experience similar symptoms as described by Nate.

I'm not sure how Nate turned off the hysteresis but I assume that this is done by setting hysteresis_margin.x/y to 0 in tp_init_hysteresis().

So I gave this a try and fixed the sources for libinput-1.5.3 and I can say that this improves the situation for me as well.

My hardware is a HP Elitebook 8540p and I fixed the touchpad (Synaptics) ranges as described here beforehand: https://wayland.freedesktop.org/libinput/doc/latest/absolute_coordinate_ranges.html

Although the pointer is very sensitive now (almost too much), I prefer this setting to what it was before.
Comment 14 Peter Hutterer 2017-01-09 04:20:52 UTC
Is there some hysteresis value that seems to make things useful? The default should be 0.5mm (which is tiny, you'd think). Is there some other value where the hysteresis still keeps the pointer from being sensitive but at the same time it doesn't prevent small movement?
Comment 15 Nate Graham 2017-01-09 04:24:40 UTC
I tried a bunch of different very small values, but honestly, for my hardware none of them were better than simply having it off entirely. Since the feature itself is essentially a workaround for lousy hardware, it would seem preferable to just be able to turn it off. Or--horror of horrors :)--have the value be adjustable so people can dial it into their own hardware.
Comment 16 Frank 2017-01-10 03:26:51 UTC
I have the hysteresis value at 1/10mm atm. I'll probably keep playing with the value a little bit to find the best balance for me.
Comment 17 corebots 2017-01-27 09:44:07 UTC
not sure if this is the same but I'd like to add that on a Wacom Intuos 5 S the touch sensitivity at small finger movements is very 'rough', like when trying to draw a small circle with a diameter of ±1cm, I get a square. all small and precise movements seem to result in horizontal and vertical movements only. This is especially noticeable when you're trying to hit the 'X' of a browser tab - you get to the area of the tab with the cursor very fast and then spend more time trying to hit that small 'X' sign. to me it seems like a combination of delayed cursor with together with the restriction of small movements to the vertical and horizontal axis only. (very different to how the touch registration behaves on the same tablet connected to my work mac with the official wacom drivers installed)
Comment 18 Nate Graham 2017-01-27 15:44:03 UTC
Yup, that's hysteresis. There's currently no UI switch to turn it off, unfortunately so. The issue will disappear if you re-compile the code with it disabled (comment out "tp_motion_hysteresis(tp, t);" in src/evdev-mt-touchpad.c).
Comment 19 corebots 2017-01-28 20:17:29 UTC
thank you, that seems to improve things indeed! the cursor doesn't stick to the horizontal and vertical axis anymore and is more precise. might be worth to note that there is still a bit of lag, and by very small movements the cursor doesn't move much, drawing small circles quickly makes the cursor to stay in the midddle.
Comment 20 Tom Vincent 2017-04-03 15:57:17 UTC
I'm experiencing the same issue as described here with hysteresis. In the long term, a knob per bug 94379, comment 29 is needed. In the meantime, I've been having a look at restoring the "PRECISE_TOUCHPAD" flag to disable hysteresis.

(In reply to Peter from comment #12)

> Have a look at commit afdcaf50157c0a76389740885bed3719b758dc37, that provides > a blueprint for the patch required to mark your touchpad as one that doesn't > require hysteresis. I'm willing to give in here to see whether we'll see any > pushback (see 27078b2). Happy to review and merge a patch for this.

I'd be interested to hear your thoughts on: https://github.com/tlvince/libinput/compare/tlvince:7272696...tlvince:9259143

Note, this doesn't restore the tag on Apple and Lenovo *40 devices. I'm aware hysteresis has been enabled/reverted a few times (e.g. 48473994c8e60189356feae7b7eae25288e5ac28) and I agree maintaining a list of device-specific flags is unscalable, but this is a real issue[1] for some users and this seems the easiest way to do it _right now_ (it could be again removed once suitable user-facing configuration is in place).

[1]: https://www.reddit.com/r/archlinux/comments/52makr/fyi_libinput_works_much_better_than_synaptics_on/dadogfd/?st=j12aqwqi&sh=ec733a11
Comment 21 Peter Hutterer 2017-04-27 05:07:02 UTC
sorry, only just starting to catch up with bug mail again.

the archlinux post suggests that for some users removing the hysteresis makes it worse again. As said above in comment #12, we may need a toggle for that, but rather than a config option for all users to set, I'd rather have a 'precise' vs 'lenient' choice (or whatever it'll be called). This would allow us to set other bits as well depending on the choice. Not 100% sure on all this yet though, mostly because there are so many complaints about touchpad acceleration open that I'm wondering whether this one here will go away once we fix most of those.

but the main thing: here I can get pixel-granularity movement by rolling my finger (or moving it). The hysteresis applies only for the first **0.5mm** of movement, though it applies to the axes separately. So I'd really really like to see a proper analysis by someone who experiences the problem instead of just "let's disable it", because that's just papering over the issue.
Comment 22 Nate Graham 2017-04-27 14:13:00 UTC
Acceleration and hysteresis are different problem spaces. I sincerely doubt that hysteresis-related complaints will disappear if you improve the acceleration.

I experience the problem and confirm that rolling my finger half a millimeter results in no cursor motion at slow speed, and ad moderate speed the cursor seems constrained to the X or Y axis exclusively. 0.5mm threshold or no, I can tell you that this happens, and that disabling hysteresis makes the problem disappear.
Comment 23 Tom Vincent 2017-04-27 16:29:10 UTC
> So I'd really really like to see a proper analysis by someone who experiences the problem instead of just "let's disable it", because that's just papering over the issue.

This makes sense. What information do you need? Would another evemu recording be useful?
Comment 24 Peter Hutterer 2017-04-28 06:17:48 UTC
(In reply to Nate Graham from comment #22)
> Acceleration and hysteresis are different problem spaces. I sincerely doubt
> that hysteresis-related complaints will disappear if you improve the
> acceleration.

not all of them, but some of them may.

> I experience the problem and confirm that rolling my finger half a
> millimeter results in no cursor motion at slow speed, and ad moderate speed
> the cursor seems constrained to the X or Y axis exclusively.

that bit needs to be fixed then. but really, half a mm is.. tiny, I'm not sure how much movement you'd expect there.

> I can tell you that this happens, and that disabling hysteresis makes
> the problem disappear.

yeah, then we need someone (you :) to look into how to fix this. I still don't think just removing the hysteresis is a good idea, especially when it's clear that there's some other bug that snaps it to the axes. Let's fix it first so it works as intended, then we can look at it again.

(In reply to Tom Vincent from comment #23)
> This makes sense. What information do you need? Would another evemu
> recording be useful?

not really, especially because ETIME. I need someone to look at this and figure out what's going on and how to fix it.
Comment 25 corebots 2017-06-02 16:00:09 UTC
how about adding a switch for disabling histerisis until things are sorted out? Cause now the situation is recompiling libinput after every update :/ Anyways, thanks for your work on this.
Comment 26 Peter Hutterer 2017-06-06 23:16:50 UTC
see comment #24, I'm not adding a temporary option. It adds quite a bit to my already full workload and pretty much guarantees that we can't remove it in the future.
Comment 27 Daniel van Vugt 2017-06-21 03:57:25 UTC
I would like to help with this problem when I find time myself...

It appears some common laptops like Lenovo X1 Carbon (gen4 and gen5) need at lot of work and are borderline unusable (https://bugs.launchpad.net/ubuntu/+source/libinput/+bug/1696929)

However having used the Xorg synaptics driver in the past I know half the problem is hysteresis, which needs to be turned off. The other half the problem seems to be a regression in Synaptics hardware/firmware after the gen3 X1 Carbon. Frankly, it's still laggy even without hysteresis, but at least becomes usable.

Also, regarding "there's some other bug that snaps it to the axes"; yes, that's a visible problem. Drawing circles (not even tiny ones) on the touchpad results in the cursor moving in a square. It sounds to me like hysteresis has been implemented per-axis, when actually it might be better implemented in an omnidirectional fashion (one threshold, not one threshold per axis) using simple Pythagoras.
Comment 28 Peter Hutterer 2017-06-27 00:34:31 UTC
(In reply to Daniel van Vugt from comment #27)
> It sounds to me like
> hysteresis has been implemented per-axis, when actually it might be better
> implemented in an omnidirectional fashion (one threshold, not one threshold
> per axis) using simple Pythagoras.

yeah, it's per axis atm. I had a patch for this in 
https://bugs.freedesktop.org/show_bug.cgi?id=99410 which was ignored and eventually closed. Feel free to give that one a try or improve on it.
Comment 29 synthead1 2017-07-04 02:15:06 UTC
I have this same problem with a Thinkpad P50.  I used recordmydesktop to get a recording of what the "jumping" looks like: https://www.youtube.com/watch?v=EJFd2IWHCWw
Comment 30 Nate Graham 2017-10-12 03:51:47 UTC
*** Bug 102883 has been marked as a duplicate of this bug. ***
Comment 31 Aleix Vidal Gaya 2017-10-12 10:28:56 UTC
(In reply to Peter Hutterer from comment #4)
> Did you ever use synaptics on this touchpad? Did that behave better?

Until I've updated from Debian Stretch to Testing, the combination of X.org and Synaptics was perfect and my touchpad (Acer Aspire V5 notebook) works like a charm. The problems began with wayland and libinput.

Any workarounds?

Comment 32 Chris Billington 2017-10-15 22:07:42 UTC
I too get a much more pleasant experience with zero hysteresis on a Dell Precision 5520, which is similar hardware to a Dell XPS 15 or Dell XPS 13. With hysteresis, I can't make small movements easily, and when I can they are likely to be snapped to purely horizontal or purely vertical movement. Targeting small things is needlessly tricky - the hysteresis is definitely a hindrance on this hardware, I find it hard to imagine anyone on this hardware would prefer it to remain enabled. Disabling it is like night and day.

Here's how I'm working around the problem on Ubuntu at the moment by applying a patch from an Arch Linux AUR package in a way that is friendly to Ubuntu/Debian packaging (and thus cleanly reversible using dpkg etc):

(replace 1.8.2 below with whatever version is the latest in your repos)
* Add "source code" to software sources in software and updates settings

* Then do all this to get the source, get the patch, apply the patch, rebuild and install (existing libinput will be replaced)

    cd ~/tmp
    apt-get source libinput10 devscripts
    cd libinput-1.8.2
    wget https://aur.archlinux.org/cgit/aur.git/plain/disable-hysteresis.patch?h=libinput-no-hysteresis
    patch -p1 < disable-hysteresis.patch
    sudo apt-get build-dep libinput10
    sudo apt-get install devscripts
    dch -i # enter a changelog message like "apply patch to disable hysteresis"
    debuild -us -uc -b
    sudo dpkg -i ../libinput10_1.8.2-1ubuntu3_amd64.deb ../libinput-bin_1.8.2-1ubuntu3_amd64.deb ../libinput-tools_1.8.2-1ubuntu3_amd64.deb

If you're using more than those three libinput packages you may need to tell dpkg to install more than

Then logout and login to use the newly built and installed libinput10

I also like making these changes for a more responsive touchpad, but YMMV:

in src/evdev.c:
    // Set the scroll thresholds to zero for instant scrolling:
    device->scroll.threshold = 0.0; /* Default may be overridden */
    device->scroll.direction_lock_threshold = 0.0; /* Default may be overridden */
in src/evdev-mt-touchpad.c in tp_unpin_finger():
    // Remove the surrounding if statement to unpin a
    // finger immediately after a click instead of only after 1.5mm:
    t->pinned.is_pinned = false;
Comment 33 Nate Graham 2017-10-15 22:18:20 UTC
I do the same thing.

Peter, if you're still reading along, I hope all these anecdotes offer some proof that we need at least one more more setting here ("Smooth small movements"?). I know you don't want too many options, and I agree with you, but this is getting to be a pretty common request, and I don't think that adding it will reduce us to xf86-input-synaptics' "random number generator" territory.
Comment 34 Daniel van Vugt 2017-10-16 01:50:00 UTC
I've got a plan to devote Ubuntu Desktop Team time (myself) to it starting early next year. Of course it would be great if someone else committed improvements earlier than that.

In my case I find many laptops don't respond to finger movement for almost the first 5.0mm or so (not 0.5mm :). Comparing to macOS or a good Chromebook (like a Dell 7310) it appears those devices with a great touchpad experience don't really employ noticeable hysteresis at all.

Forgive me if I missed it, by why do we have hysteresis?.. As I understand it, if one finger is touching then you want maximum precision (zero hysteresis). And if multiple fingers are touching then the cursor should simply stop moving as gestures take over. So I don't yet understand why hysteresis is there at all. Although I can also see ways to improve it if we can't remove it.
Comment 35 Daniel van Vugt 2017-10-16 02:01:22 UTC
Sorry, I should have both read more and remembered more. I now recall the ThinkPad X220 really needed hysteresis for single finger clicks. Due to high touchpad precision and small touchpad size, the cursor would move during the click. Lenovo "fixed" this in the X230 by making the touchpad hardware just much less precise.

OK, it sounds like we've got another simple math problem somewhere. If Peter says the intended hysteresis is 0.5mm but I'm often seeing 5.0mm then that sounds like a simple bug.
Comment 36 Peter Hutterer 2017-10-16 04:01:41 UTC
we tried to remove the hysteresis a while ago and got so many complaints about the fingers still wobbling that we had to re-instate it. It was largely whack-a-mole with the various touchpads. Search for LIBINPUT_MODEL_WOBBLY_TOUCHPAD in the log, f6c2d4b and 27078b2 mark the range that is interesting.
Things *may* be better now with SMBus/RMI4 being more common, but I don't know.

The reason we have it is that a large portion of all touchpads wobble when you hold the finger still on the touchpad. That wobbling is hard to/impossible to determine from real finger movement, the hysteresis is the only solution here.

tp_init_hysteresis() is the function here, the margins are set to res/2, so 0.5mm each direction (i.e. the whole hysteresis area is 1mm wide). The way it's implemented means that the hysteresis doesn't take effect after the first 0.5mm of movement though because continuously moving in one direction will keep moving the edge. See the comment at evdev_hysteresis().
Comment 37 Daniel van Vugt 2017-10-16 04:05:43 UTC
I wonder how it interacts with touchpads that have hysteresis built into the hardware/firmware?

I mean the distances are the same, but some touchpads (like the X1 Carbon gen 4 vs gen 3) seem to be doing some hysteresis themselves. Even when disabled in software.
Comment 38 Peter Hutterer 2017-10-16 06:25:42 UTC
well, it always applies on top of the hardware hysteresis. having said that, if the hw hysteresis exceeds the 0.5mm, it should never trigger, so the hysteresis applied should always be the maximum of 0.5mm and the hw hysteresis value.
Comment 39 Nate Graham 2017-10-16 12:45:15 UTC
Since some touchpads are unusable without hysteresis in its current form, and some are unusable with it, that implies to me that this needs to be configurable, either by the user (preferred), or by device property introspection so we can let libinput determine based on the hardware when hysteresis needs to be on.
Comment 40 Peter Hutterer 2017-10-18 05:20:58 UTC
I don't think we can use the device properties, because there's at least one touchpad that was supposed to be non-wobbly and at least one user complained about cursor wobbles when the hysteresis was removed.

the issue is still what configuration option to intruduce. A simple "hysteresis on/off" is not good enough. we'd likely still need some hardware-specifics on top. And there are some other issues that are related to this behaviour like the pointer moving before/after a click or release.
Comment 41 Daniel van Vugt 2017-10-18 05:23:04 UTC
I was thinking hysteresis should eventually be a GUI slider from the user's perspective. Just configure a distance from 0 (off) to N.
Comment 42 Peter Hutterer 2017-10-18 08:52:07 UTC
What exactly would the slider configure though? Think of it as a formal specification, so you have to specify units, behaviour, etc. And then assume you can't ever change this in the future :)
Comment 43 Daniel van Vugt 2017-10-18 08:56:26 UTC
Units could be millimetres (or fractions thereof). But a simple on/off switch would be fine too. I don't mind, so long as _something_ is done.
Comment 44 Nate Graham 2017-10-18 15:28:30 UTC
The GUI to control Synaptics in KDE Plasma's system settings exposes a slider that does just that: it lets the user determine the small movement smoothing threshold in millimeters. I know  I know, "random number generator" and all that--but such a slider is basically what we're are asking for here. Being able to set a smoothing threshold that goes from 0mm to, say, 5mm, in increments of 0.1mm, seems like it would solve this problem.

There is some urgency here because technological progress being what it is, the percentage of laptops with really low-quality touchpads of the sort that hysteresis improves is likely to drop over time. Without the ability to configure or turn off software hysteresis, libinput will become almost unusable for a larger and larger share of our users' hardware.

And it really is almost unusable for touchpads that don't need libinput's additional hysteresis: it destroys slow-speed precision for those touchpads, and using it is a truly maddening experience. An unchangeable default that renders the touchpad frustrating for those with decent quality hardware isn't likely to generate a neverending stream of appreciation for libinput in the Linux community. :)
Comment 45 Peter Hutterer 2017-10-25 02:18:15 UTC
I need from *all* of you that want the hysteresis changed two evemu-recordings, as separate *attachments*:

start evemu-record, put a single finger down on the touchpad, hold the finger still for ~10s, then lift it.

start evemu-record, put the finger down on the tochpad, move as slow as you can to horiztonally to the left for ~2cm, lift the finger. Repeat, moving vertically up for ~2cm.
Comment 46 Daniel van Vugt 2017-10-25 03:10:26 UTC
It sounds like you're not testing a major use case that's most annoying: changing directions without lifting fingers. By that I mean moving right then left, or up then down. Hysteresis seemingly breaks this use case the most. Is that intentional?

As I understand it, this relates to the observation that drawing small circles results in the cursor moving in a square. Because that demonstrates both axes changing directions. This use case I suggest also directly relates to trying to target a button with your finger.

So I feel your request might miss the issue...?
Comment 47 Peter Hutterer 2017-10-25 03:17:47 UTC
yes, it's intentional. the data this gives me is 1) if the firmware does motion filtering, a static finger should not generate pointer events and 2) the minimal delta the firmware will give me on slow movements. both help to calibrate the hysteresis.

I know what the software does, what I need to know is what the hardware does. or some of it anyway...
Comment 48 Nate Graham 2017-10-25 04:58:27 UTC
Created attachment 135028 [details]
Nate Graham - single finger held still for 10s
Comment 49 Nate Graham 2017-10-25 05:01:07 UTC
Created attachment 135029 [details]
Nate Graham - slow movements left then up

Attaching the requested files.

Hardware: HP Spectre x360
Distro: Kubuntu 17.04
Kernel: 4.10.0
Session: X, not Wayland
libinput version: compiled from git master as of about 30 minutes ago
Comment 50 Daniel van Vugt 2017-10-25 05:37:17 UTC
Created attachment 135030 [details]

Test results from ThinkPad X1 Carbon gen 4.

Lots of pressure events for small finger movements. Not so many position events...
Comment 51 Daniel van Vugt 2017-10-25 05:49:27 UTC
Created attachment 135031 [details]

Results from ThinkPad X1 Carbon gen 5.
Comment 52 Peter Hutterer 2017-10-26 04:18:42 UTC
Give this branch a try please, thanks:
Comment 53 Daniel van Vugt 2017-10-26 10:02:18 UTC
I like the ideas I'm seeing in your git branch.

Unfortunately that branch made zero improvement on either X1 Carbon gen 4 or 5.
Comment 54 Daniel van Vugt 2017-10-26 10:04:04 UTC

+	if (!tp->hysteresis.enabled)
+		tp_maybe_disable_hysteresis(tp);

should be:

+	if (tp->hysteresis.enabled)
+		tp_maybe_disable_hysteresis(tp);
Comment 55 Daniel van Vugt 2017-10-26 10:13:39 UTC
After I fixed the typo, the fix was good but not perfect. On both X1 Carbon gen 4 and 5.

The system doesn't see long enough periods of a stationary finger in reality to learn to disable hysteresis soon enough. But if I held my finger still for a short while it would switch over properly.

While I like your thinking with that heuristic, and it should probably stay, I still think some defaults (of off) need to be hardcoded for the problematic touchpad models.
Comment 56 Nate Graham 2017-10-26 12:51:45 UTC
I tried out that branch on my hardware (after applying Daniel's fix) but it didn't make any difference for me, even after holding a finger stationary for 30 seconds to try to get it to learn.

Maybe my hardware does less filtering than Daniel's. Still, it's a night-and-day difference without hysteresis, and I don't see any jumpiness at all when it's off.
Comment 57 Peter Hutterer 2017-10-27 01:51:41 UTC
doh, I thought I had pushed the !enabled fixed, done now and force-pushed so the branch is up-to-date and ready for testing. Thanks for spotting that. Commit is currently 1b251c2676130 but I may need to push more later.

The current event count of 5 means holding the finger stationary for ~60ms on most touchpads. That's short enough that I can trigger it here even when trying not to, usually it triggers before I even start moving the fingers, right after I place it on the touchpad for the first time. That's on a T440 which is equivalent to the X1 3rd iirc, so an older touchpad.

I recommend testing with sudo ./build/libinput-debug-events --verbose, that prints a message when the hysteresis is disabled. If the message appears, then hysteresis is ignored.

Nate: attachment 135028 [details] has several non-moving event streams that last a second or even longer. So it should definitely activate on your touchpad. I tested all the attachments above (still and moving) and they all disable the hysteresis within the first fraction of a second, before the first events come out of the device.

The only case where the period may be significantly longer than 60ms would be if the touchpad firmware filters pressure and you don't get *any* events before the next motion event some time later. That can happen, see E 1.557756 in Nate's attachment 135029 [details] which is 119ms after the previous one. But that is the exception. Needs fixing, sure, but a very niche issue.
Comment 58 Daniel van Vugt 2017-10-27 06:53:32 UTC
It feels like the tests you asked us to record are not indicative of normal use. Under normal laptop use there is apparently not a period of 5 pressure change events early enough. You start using the laptop and it feels awful - can't put the cursor anywhere you want it to go. Hysteresis is at least 5mm and the cursor refuses to move in natural curves -- only vertically or horizontally. Only by staying still for a short while does it switch over. Although it _should_ theoretically by the time you get to the first button click. Maybe we need to spend more time testing the branch...

On that note, I'm still suspicious as to why hysteresis is so large -- around 5mm on multiple different machines. The only theory we have that explains that is hardware hysteresis having an additive effect, because you say it should be less than 1mm. Actually I have a second theory that weird unsmooth acceleration curves [1] also contribute to the unnatural feel and poor pointer control but that's a different bug. Perhaps also default acceleration curves are decelerating for minimal velocities, which changes the hysteresis distance??

Long term I feel the only reliable options for hysteresis are to:
  (a) Hard code hysteresis off for some hardware; and
  (b) Make it a user-visible option.

I've spent more time using a Macbook and Chromebooks and they are dramatically better, for various reasons. There is no noticeable hysteresis there -- the tiniest finger movement is responded to.

P.S. X1 Carbon gen 3 is very different to gen 4 and 5. Gen 3's touchpad is just wonderful and amazing (although also works best without software hysteresis). I can provide stats from that one too if you are curious.

[1] https://wayland.freedesktop.org/libinput/doc/latest/pointer-acceleration.html
Comment 59 Peter Hutterer 2017-10-27 10:43:06 UTC
Try the branch again, I changed it to a timeout-based approach in case the other events get swallowed. commit fd96be761e53. That one is at a fixed 80ms but that *has* to be short enough. It's less than our tap timeout, iirc...

Please do test this more, especially with the --verbose flag I mentioned above to check if the hysteresis is in fact disabled on the fly. And of course the usual checks that the new version is actually being used, etc.

As for the other commments: I don't know why the hysteresis is so large. It's initialized as res/2 which is 0.5mm in physical dimensions. even if the hw hysteresis is larger than that, ours wouldn't do that much because you'd always be exceeding the margin anyway.

Also, fwiw, the hysteresis is applied before pointer acceleration, the deltas fed into acceleration have the hysteresis applied to them already. If that affects the acceleration it'd be easy to figure out - simply printf the accelerated coordinates (src/filter.c) for a recorded event sequence and compare them with/witout hysteresis.

IIRC the T450 has the same touchpad as the gen4, the below may matter. Though it wouldn't explain why it works with the hysteresis disabled. 

I have a t450 but I'm moving house atm and it's in a box already. Should be able to test it next week. I don't remember it being that awful though and I had been using that device for testing for a while.
Comment 60 Daniel van Vugt 2017-10-30 09:55:09 UTC
Confirmed the new branch headed at fd96be761e538ef53ef67ef49c6b37407a948492 is great (always seems responsive, no obvious delay).

Tested on both X1 Carbon gen 4 and 5 using Ubuntu 17.10 (Gnome Shell 3.26.1). Ship it :)

I never needed any logging. It was a night and day difference just watching the cursor move in gdm and gnome-shell.
Comment 61 Peter Hutterer 2017-10-31 05:38:36 UTC
Thanks for the tests, much appreciated. Patchset is on the list:

Comment 62 Nate Graham 2017-11-01 03:33:49 UTC
Created attachment 135200 [details]
Still can't draw small circles using the conditional hysteresis branch

I'm still not seeing any improvement with this branch. I've verified that's it's being installed properly:

$ ls  /usr/lib/libin*
ls: cannot access '/usr/lib/libin*': No such file or directory

 ls -la /usr/lib/x86_64-linux-gnu/libinput*
lrwxrwxrwx 1 root root     19 Oct 31 21:27 /usr/lib/x86_64-linux-gnu/libinput.so -> libinput.so.10.13.0                                                                             
lrwxrwxrwx 1 root root     19 Oct 31 21:09 /usr/lib/x86_64-linux-gnu/libinput.so.10 -> libinput.so.10.13.0                                                                          
-rwxrwxr-x 1 root root 731328 Oct 31 21:09 /usr/lib/x86_64-linux-gnu/libinput.so.10.13.0

Still, hysteresis doesn't seem to turn off like it probably should. I still can't draw small circles. I'm attaching an evemu recording.
Comment 63 Nate Graham 2017-11-01 03:40:27 UTC
(And yes, the branch was up-to-date: the latest commit was fd96be761e538ef53ef67ef49c6b37407a948492)
Comment 64 Peter Hutterer 2017-11-01 05:15:20 UTC
With your recording:

$ sudo ./build/libinput-debug-events --verbose
-event21  DEVICE_ADDED     SynPS/2 Synaptics TouchPad        seat0 default group21 cap:pg  size 106x98mm tap(dl off) left scroll-nat scroll-2fg-edge click-buttonareas-clickfinger dwt-on
event21 - hysteresis disabled
event21 - pressure: begin touch
event21 - thumb state: THUMB_STATE_MAYBE → THUMB_STATE_NO
event21 - button state: from BUTTON_STATE_NONE, event BUTTON_EVENT_IN_AREA to BUTTON_STATE_AREA
 event21  POINTER_MOTION    +2.44s	 -0.22/ -0.12
 event21  POINTER_MOTION    +2.45s	 -0.38/  0.21
 event21  POINTER_MOTION    +2.49s	 -0.45/ -0.25
 event21  POINTER_MOTION    +2.50s	 -0.98/ -1.81
 event21  POINTER_MOTION    +2.51s	 -1.07/ -2.36

So the hysteresis is disabled before the first motion event is sent, right after putting the finger down.
Comment 65 Nate Graham 2017-11-01 15:29:36 UTC
But it still doesn't feel right. When using the branch, I still can't draw tiny circles with small finger movements the way I can when I disable hysteresis by simply commenting out tp_motion_hysteresis(tp, t); in src/evdev-mt-touchpad.c. With that change, it feels perfect.

I'm attaching an evemu recording of me successfully drawing small circles with tiny finger movements when using libinput what that single change.
Comment 66 Nate Graham 2017-11-01 15:49:16 UTC
Never mind, I forgot to remove Synaptics that time.

Comparing your branch with master where I've permanently turned off  hysteresis hysteresis, they are the same. So I approve this patch; it does make a difference. The precision with very small movements is still not as good as it was with Synaptics, but we can track with with another bug. Feel free to mark this as RESOLVED whenever the patch is merged to master.
Comment 67 Daniel van Vugt 2017-11-02 01:34:21 UTC
Nate: For extra precision, maybe try the "flat" pointer acceleration profile if you can find a way to enable it:
Interesting for future experimentation, but now off-topic for this bug.
Comment 68 Peter Hutterer 2017-11-03 03:19:14 UTC
pushed to master, thanks for testing.

commit 50daa7b30fd1e13545944540a0ad3794bbf2ef09
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Thu Oct 26 13:56:44 2017 +1000

    touchpad: automatically disable the hysteresis where not required
Comment 69 Daniel van Vugt 2017-11-03 03:26:27 UTC
Nice work. I am pleasantly surprised to see we have a solution that will work for other arbitrary touchpad models too.
Comment 70 Nate Graham 2017-11-03 04:13:13 UTC
Comment 71 Tomas Janousek 2017-11-11 13:17:18 UTC
I recently applied this hysteresis autodisable patch (https://github.com/wayland-project/libinput/commit/50daa7b30fd1e13545944540a0ad3794bbf2ef09) on my T25 and it worked brilliantly, so I applied it on my wife's T440p and experienced wobble for a second after the finger(s) stopped moving. After that second, the wobble stops. This was apparently good enough for libinput to disable its hysteresis, but it makes two-finger scrolling very annoying.

Fortunately I fixed this by upgrading the touchpad firmware: https://support.lenovo.com/cz/cs/downloads/ds121241 (it says L540, but it works with T440p as well). So I'm just writing this here in case anyone else happens to have an old touchpad firmware and the patch gives them wobbles.

(Anyway, thanks a lot for this patch. It was the final missing piece that let me switch from synaptics to libinput.)
Comment 72 Daniel van Vugt 2017-12-12 05:38:18 UTC
I naively thought this fix would be in libinput 1.9.2 but it's still not in 1.9.3. The fix is only in master. I guess we're waiting for libinput 2.0 on this one...?
Comment 73 Peter Hutterer 2017-12-13 04:09:26 UTC
yeah, it'll be in 1.10, not adding that to the 1.9. branch we have enough problems there as it is
Comment 74 Daniel van Vugt 2017-12-18 10:25:16 UTC
Seems Debian+Ubuntu accepted this as a patch, then reverted it because someone said it was too twitchy:


Is there a right way to approach this now that will satisfy everyone, other than a configuration option?
Comment 75 Peter Hutterer 2017-12-18 11:13:59 UTC
I'll need an evemu from that device please
Comment 76 James Cowgill 2017-12-19 13:51:46 UTC
Created attachment 136276 [details]
evemu recordings on Dell XPS L502X

I'm the person which filed the Debian bug and was complaining about the touchpad being twitchy with the patch applied.

I've attached some evemu recordings as described in comment #45.
Comment 77 Peter Hutterer 2018-01-08 02:39:51 UTC
https://lists.freedesktop.org/archives/wayland-devel/2018-January/036475.html fixes the issue with the current code, but it doesn't fully address James' issue. That however requires a separate bug because that touchpad may need special handling, see Bug 104533
Comment 78 Daniel van Vugt 2018-01-08 02:57:39 UTC
Back on the topic of this bug in particular, I have recently seen that both Dell XPS 13 and Apple Macbook airs also require this fix. Although they have really nice touchpad hardware, the hysteresis in libinput ruins it, making them unresponsive to precise movements. And drawing a circle moves the cursor in a square.

I was surprised to see that even great touchpads need the same fix. Although I haven't had the opportunity yet to test this fix on those.
Comment 79 Peter Hutterer 2018-01-08 03:17:55 UTC
which fix? the one in comment #68? then, well, yeah, that's the whole reason for this bug report to begin with.
Comment 80 Daniel van Vugt 2018-01-08 03:41:24 UTC
Put another way, I haven't yet seen any touchpad that didn't need hysteresis turned off (or reduced, or redesigned). I just made that comment because I was surprised to see even the best touchpads I know of are also affected.

So in my mind this fix is just about the single most important fix we need to get into Ubuntu 18.04. It eclipses other bugs because there's little need for other fixes if the user can't move the cursor and therefore chooses not to use the desktop at all. That's not an exaggeration, just a fact that I am experiencing myself and want to make sure it doesn't remain so going into Ubuntu 18.04.

So when is libinput 1.10 due? :)
Comment 81 Daniel van Vugt 2018-01-08 04:27:24 UTC
More good news: This fix works like magic on the Dell XPS 13. It's wonderful now.
Comment 82 Peter Hutterer 2018-01-08 04:29:21 UTC
we had turned the hysteresis off once and re-enabled it because of a whack-a-mole game with touchpads that needed it. look up the history between f6c2d4b8b5e1968411568d81b47488a655ba47a1 and 27078b2667def4ecde1f47b8258d510a576c8bb1 and you'll find how many exceptions we had to put in because too many touchpads have wobbly cursors without the hysteresis.
Comment 83 Peter Hutterer 2018-01-08 04:37:52 UTC
huh? what fix, the one from comment #77? did the XPS have pointer wobbles before?
Comment 84 Daniel van Vugt 2018-01-08 04:43:02 UTC
No, the original fix from comment #68, I think. Or more precisely - libinput version 1.9.4-1 from Debian/Ubuntu does the trick (reverted in 1.9.4-2 due to James' issue unfortunately).

The XPS 13 never had wobbles, it's the opposite. Libinput refused to move the cursor at all in response to anything other than large finger movements. And drawing a circle made the cursor move in a square. So the fix for this bug in general is working a treat on the XPS 13.
Comment 85 Daniel van Vugt 2018-01-10 08:52:40 UTC
I have done more hardware testing today with four different laptops and three different versions of libinput. The laptops are X1 Carbon gen 4, X1 Carbon gen 5, Dell XPS 13 (4th/5th?) and Apple Macbook Air 11 (2015). The results for all machines were the same:

libinput 1.9.4-2 (Debian/Ubuntu): Terrible, unresponsive to small movements

libinput master HEAD: Great, always

libinput master HEAD + patch from comment #77: Good, but terrible in the beginning. I have to consciously hold a finger still at first before hysteresis turns off. Then it's good.
Comment 86 Peter Hutterer 2018-01-10 11:18:58 UTC
thanks for testing, basically matches my expectations. Note that you are fine-tuned to notice this bug at the moment. The timeout is 80ms and it only needs to be triggered once during the lifetime of the libinput context (i.e. only once until you log out/reboot). I don't consider that as a massive problem, in the vast majority of use-cases it will be disabled before you even click the login button or at least shortly thereafter.
Comment 87 Daniel van Vugt 2018-01-11 01:29:29 UTC
I am happy to wait and see how the patch in comment #77 goes in the wild but I'm slightly less optimistic about it only taking 80ms.

Starting on a login screen I find myself swiping the touchpad to move the cursor. So since the cursor is moving the 80ms timeout wouldn't be reached in those early seconds. Because it's always moving and not the requisite stationary for a short period. But yeah I guess it would probably happen after a while. And if you're aware of it you can trigger it immediately.
Comment 88 Peter Hutterer 2018-01-11 02:18:42 UTC
(In reply to Daniel van Vugt from comment #87)
> I am happy to wait and see how the patch in comment #77 goes in the wild but
> I'm slightly less optimistic about it only taking 80ms.

Comment in the code:
  If the finger is down for 80ms without seeing motion events,
  the firmware filters and we don't need a software hysteresis

The solution isn't perfect, but that's the best heuristic we have so far. And it beats having a config option through 3 layers of stack that users have to enable or disable manually. And then me having to handle bugs because of broken configuration files 3 years down the track.
Comment 89 Daniel van Vugt 2018-01-11 02:46:05 UTC
I mostly agree, and was already aware of the 3 layers of stack issue. This is certainly worth the effort before resorting to that.

If a config option was to ever be created though, we might want to present it at the top layer as "Sensitivity" so users could understand what they're changing. Below that the hysteresis would be the inverse of the sensitivity value.
Comment 90 Daniel van Vugt 2018-01-18 07:44:21 UTC
Peter, can we assume the patch from comment #77 will land?

I'm trying to get an idea of everything to backport.
Comment 91 Peter Hutterer 2018-01-18 08:39:30 UTC
commit f5a9e38c90380741adaf3ae38642d30f7564e922
Author: Peter Hutterer <peter.hutterer@who-t.net>
Date:   Mon Jan 8 10:39:48 2018 +1000

    touchpad: don't disable the hysteresis unless a finger is down

I planned to do 1.10rc1 this week, but it got pushed back and I generally try to avoid releasing stuff on a Friday :) Expect the rc1 on Monday
Comment 92 Nate Graham 2018-02-20 01:32:07 UTC
*** Bug 103619 has been marked as a duplicate of this bug. ***
Comment 93 Nate Graham 2018-02-20 01:42:26 UTC
*** Bug 105022 has been marked as a duplicate of this bug. ***
Comment 94 Peter Hutterer 2018-03-06 04:32:42 UTC
*** Bug 100752 has been marked as a duplicate of this bug. ***
Comment 95 Krasi 2018-03-06 07:22:47 UTC
after using 1.10.0 for a while  I can say that it behaves a bit differently but certainly it is not better than 1.9 , small objects and text are very difficult to select and click as the mouse still jumps when I make small movements on Lenovo P50

do you need anymore info to find the culprit?
Comment 96 Daniel van Vugt 2018-03-06 07:25:41 UTC

Most touchpad bugs are model-specific. Please log your own new bug along with an evemu recording of you holding your finger still.
Comment 97 Krasi 2018-03-06 07:29:39 UTC
thanks, I already did a while back and it was marked as duplicate of this one.
Comment 98 Daniel van Vugt 2018-03-12 05:30:01 UTC
*** Bug 101428 has been marked as a duplicate of this bug. ***
Comment 100 Daniel van Vugt 2018-04-30 05:35:46 UTC
Excellent, thanks.

I had actually forgotten to report that hysteresis was breaking the X1 Carbon G5 again...
Comment 101 Peter Hutterer 2018-05-01 05:50:12 UTC
For the record, the patches in Comment 99 change things around again. First version was to disable the hysteresis after a series of events that looks like the touchpad is reliable. That didn't work, because touchpads are terrible.

Second version (current in git master) changed to enable the hysteresis if wobble is detected. That didn't work but it's unclear if that's a bug, patches 1-3 of the patchset may eliminate that issue. Nate, can you please test this?

Third version, i.e. comment #99 now simply doesn't touch the hysteresis and the wobble detection merely warns the user that something is up. We then have to add a device-specific hwdb entry to set the fuzz for the value the device needs and libinput can pick it up on the next run. I'd rather avoid this because it's reasonably insane, so it mostly depends on whether patches 1-3 are enough.
Comment 102 Nate Graham 2018-05-02 02:48:01 UTC
Patches 1-3 in that patch series seem to do the trick for me. I haven't had Hysteresis inappropriately turn on.

FWIW, I definitely read "aydunno" in a Homer Simpson voice.
Comment 103 Peter Hutterer 2018-05-25 05:39:45 UTC
Closing again based on comment 102, git commit is 49a8bd3ca76d11b1ec604df741f5c4fdccf0b9d3 which merges patches 1-3. Thanks for testing!
Comment 104 Nate Graham 2018-05-25 14:54:30 UTC
Thanks for implementing! It's working flawlessly for me.

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.