Linux distro: openSUSE Tumbleweed libinput version: 1.7.0-2.1 This is a subtask/blocker of https://bugs.freedesktop.org/show_bug.cgi?id=98535 I thought I was happy enough with Libinput's touchpad behavior, but then I got to use a 5 year-old Mac laptop and was reminded of the much nicer feel of its trackpad software. One of the major differences was how naturally the cursor accelerated in response to medium-ish finger movements: much faster than current libinput does. I'd like to track that in this issue.
Peter- First off thanks for all your work with libinput. Really appreciate your contribution to the community. I also had a pretty bad experience with libinput on a Macbook Pro 8,2 using 1.8.4 and also in 1.9. Pointer acceleration felt really different from what I was used to on the machine under MacOS. Slow movements were two "jerky", medium were not fast enough, etc. (I had previously been using mtrack under xorg with mediocre results) I spent some time and created a mac app to profile the touchpad acceleration profiles used in MacOS. It was a course view, but provided some insight into what felt right for this machine. I then took a crack at modifying the acceleration code in libinput to best match this profile curve. After some tuning, it seems to be working really great for me on this machine. The basic acceleration is a power function. Copied below is the new touchpad_accel_profile function I am using. It is pretty sensitive (my desired speed setting is right in the middle), yet gives me a lot of room to adjust from slow to really fast using the normal speed slider. My apologies if this is not the right way to help share this information. This below plus a couple other small improvements has made libinput (and therefore Wayland) very enjoyable for me with an old macbook pro touchpad. The pointer acceleration has a really nice balance of slow speed accuracy and high speed capability. FWIW. Code below ---------- double touchpad_apple_accel_profile(struct motion_filter *filter, void *data, double speed_in, /* in device units/µs */ uint64_t time) { struct pointer_accelerator *accel_filter = (struct pointer_accelerator *)filter; const double max_accel = accel_filter->accel; /* unitless factor */ double factor; /* unitless */ /* Convert to mm/s because that's something one can understand */ speed_in = v_us2s(speed_in) * 25.4/accel_filter->dpi; // Convert into speed that my formula used which assumed 1 = distance of trackpad in X (103mm for my pad); should fix the formulas below to make this a function of the trackpad distance in mm instead. double norm_in = speed_in / 103.0; // X adjustment; range on Apple was .07 to .7 (fastest) double x_factor = 0.385 + 0.315 * filter->speed_adjustment; // Power adjustment; range on Apple was 1.1 to 1.5 (fastest) double power = 1.3 + 0.2 * filter->speed_adjustment; // first number is a magic number to get into the scale that is appropriate factor = 3.5 * pow(norm_in * x_factor, power); // Minimum factor for slow speeds if (factor < 0.20) { factor = 0.20; } /* Cap at the maximum acceleration factor */ factor = min(max_accel, factor); return factor; }
Correction above: that is too, not two. And coarse, not course. Yikes. To clarify above, the profiling and curve fitting I did on MacOS assumed input velocities with distance represented by 0-1 (1 = full width of trackpad) and time in seconds. Obviously, the formulas could be modified to eliminate this extra conversion. I left as shown to make adjustments easier vs the measured acceleration curves.
Greg, if you put that in patch form, I'd love to test it out.
Created attachment 135510 [details] [review] Patch for Macbook Pro 8,2 testing Patch from libinput 1.9.1 attached Changes: 1. Added thumb detection based on size, improves detection on MacbookPro 2. Raised height at which thumb detection is triggered (was 15%, now is 40% up from bottom). This better matches Apple and the mtrack driver. 3. Lower scroll lock distance threshold 4. New Apple MacbookPro acceleration profile based on MacOS profiling 5. Fixed two finger click to activate right mouse button instead of middle 6. Disabled some gestures that were causing problems 7. Slowed down scrolling speed slightly (may not be working) NOTE: The new acceleration profile is only triggered if the touch device registers as EVDEV_MODEL_APPLE_TOUCHPAD. This worked for my Macbook Pro 8,2. The new acceleration profile is pretty fast relative to the standard libinput settings. The normal mouse speed setting (for example in Gnome settings) can be used to adjust the speed. It adjusts both the speed and acceleration ramp up. All of the other changes are general and may cause problems for non-Apple products. I have only tested this on my MacbookPro 8,2.
Thank you so much for that patch, Greg. I'm not using an Apple touchpad, but with accel speed -0.85, your patch RADICALLY improves the feel anyway, both for cursor movement and scroll speed. It's a vast improvement over the Flat or Adaptive profiles. I would strongly support using the acceleration curve as the default, or adding it as an additional profile beyond Flat and Adaptive. If this ever gets made the default or incorporated somehow, the scaling of the accel speed setting would need to be tweaked, because anything higher than about -0.5 is unusably fast for me.
Your patch also implements/fixes the following issues that previously made libinput less than pleasant: https://bugs.freedesktop.org/show_bug.cgi?id=98800 https://bugs.freedesktop.org/show_bug.cgi?id=98801 Congrats, you just made libinput usable full-time for me.
Created attachment 135579 [details] [review] MacOS inspired touchpad acceleration patch Nate- Thanks for the testing and feedback. This new patch against 1.9.2 is slowed down slightly. This patch only includes the touchpad acceleration profile change. (Previous patch had several other smaller fixes for MacbookPro). It replaces the existing linear profile in libinput and therefore can be tested by people using various different laptops.
Greg, that's a pretty great patch. I've been using it for the past month. The default speed still feels too fast, though. I still need to set "libinput Accel Speed" to -0.75 to make it feel reasonable. Peter, minus the speed issues, this patch makes libinput's touchpad cursor movement profile feel *perfect* to me.
Thanks for the patch greg, sorry about the delay. I tried this on top of 43de03a08c7cdbe on the t440s that I have here and, well, it's almost unusable, sorry. On the default 0 setting it's way too fast, reducing it to -0.75 like Nate makes very slow to slow movements almost match the finger movements. but as soon as I go past that basic speed, the cursor is unpredictable and lands in the screen edges almost immediately. I printed the curve (./build/ptraccel-debug --filter=touchpad --mode=accel, then use the gnuplot commands at the top of the output) and it's no surprise that it feels fast. The max accel factor is 9 (vs ~3 in the current code) and the increase is sooner and much steeper than the current code. So at least the fast movement isn't some weird side-effect but the intention. So we definitely need some tuning here. Or am I missing something? I only applied the patch from comment 7 locally. And if that's it, I *really* wonder where the bug is because it's one thing to argue about a personal preference for pointer feel but another to see that code that *should* be device-independent behaves so different on different devices. There's a bug in the accel code somewhere but I don't know where.
Peter- Thanks for checking it out. I agree something strange is happening. The patch you mention is the same I am using on my Macbook Pro with very different results. Agree that this is not a preference / slight difference. (For reference, I am running with a setting of -0.3 and even relatively quick movements only get me about 1/2 way across the screen.) It sounds like something is very different in the end result between our two different pieces of hardware. I will dig in further and see what I can find.
Created attachment 136584 [details] Accel Profile Comparison at Zero Speed See next comment
Created attachment 136585 [details] Accel profile comparison patch at -0.75 vs nominal Hi Peter, After some further investigation, I think I have a better idea what is happening. The good news is that I don't think there is some bug causing a difference in performance between our machines. To start, I confirmed that my touchpad was not doing something odd like reporting a bad DPI or size. Everything looked good. (DPI is 92 device units/mm or about 2300 per inch). Did a bunch of verification and everything seemed to make sense. I then used your speed measuring tool and found something interesting to me. It turns out that my typical speeds for normal operation of the touchpad range from 0 to 200 (99th percentile). I then compared this to the nominal accel profiles (set at speed 0) and noticed that 99% of my operational speeds never even get to the part of the curve where accel ramps up in the libinput profile. This created what I felt was no acceleration and a "dead middle" to high end. I also felt that at very slow speeds, it did not have the accuracy I needed. If I cranked up the speed setting to pull in the threshold of the acceleration ramp, it made the low end speed even worse (meaning even harder to control). I then looked at the curve from the patch and noticed that within my operational range, it addressed both of these problems for me. The low end is slower and more accurate, and the acceleration starts at about the midpoint and ramps up. (Completely agree that at much higher speeds the raw accel factor gets crazy high in my patch, but it would seem I never get there with my touchpad speed.) I have attached plots that show both the nominal and the patched accel profile plots at a speed setting of zero. I also then did a comparision on the patch at the setting that Nate mentioned feeling good (-0.75). See attached graph that compares it to the zero speed setting of the nominal accel profile. It actually seems very close yet addresses the slow speed problem and also has a bit more acceleration early and smoothly from the middle to the high end. I will take another swing at a new profile / patch that moves the current patch's -0.75 setting and moves this up to 0 to slow things down overall. Thanks, Greg
Thanks for the investigation, Greg. That matches both my experience, and also libinput's as-designed acceleration curve (I know I've seen that curve displayed elsewhere, maybe even in the docs somewhere). The curve in your patch makes vastly more sense to me, both after experiencing it for real-world use, but also on a theoretical, conceptual basis: slow finger movements *should* trigger a usable slow speed, not the immediate jump to much higher speed that libinput currently has.
That 'dead' zone is intentional, see https://who-t.blogspot.com.au/2016/12/libinput-touchpad-pointer-acceleration.html for a few graphs. And the main motivation there was that for most slower-medium motions, the cursor should basically match the finger movement, so the acceleration should be flat. Cursor movement is actually slightly faster than finger movement but that's the reference point anyway. A 1cm circle with the finger on the touchpad gives me a ~3cm circle on the screen. Can you confirm this?
fwiw, I went through the touchpad acceleration code again and could not find anything obviously wrong. An important definition: a 'normalized' coordinate is one that's converted from device units to units equivalent to a 1000dpi standard mouse. * starting point: tp_gesture_post_pointer_motion() * tp_get_delta() returns a normalised delta * this delta is passed to tp_filter_motion(), where it is converted back to device units [the double-conversion is a leftover]. Only difference: the y axis is pushed to the same resolution as the x axis so we can assume a delta in a single coordinate system. That's the 'raw' variable. * 'raw', in units/mm, is passed to filter_dispatch() which calls accelerator_filter_post_normalized (see accelerator_interface_touchpad) * 'raw' is passed further to accelerator_filter_generic() and calculate_acceleration_factor(). * that calculates the velocity (in units/us) and passes it to calculate_acceleration() * that then calls the profile: touchpad_accel_profile_linear() * the profile converts the speed (in units/us) to mm/s for easier understanding and then applies the linear-ish accel function that calculates the accel factor. * that factor is passed back up and applied to the raw input delta (accelerator_filter_post_normalized) * the input delta is converted to 1000dpi normalized units and we finish filter_dispatch() and send the accelerated delta to the caller So aside from the slightly confusing conversions between systems, there is nothing bleedingly obviously wrong.
Peter- Thanks for your response. Agree that it does not look like there are any bugs that are causing this behavior. It may just come down to preference. On your earlier response, I understand the intention behind the flat zone. Yet, I think part of what I am experiencing is that this flat zone is not fixed at the 1:1 rate. It scales with the overall speed setting. Therefore, when I set the speed high enough to pull forward the threshold to get the acceleration profile I like in the middle, it is also bringing up the low speed floor to a too high level for me to accurately control the pointer. For reference, to make the middle and high end feel right, my speed setting is ~0.95. Yet, this has the low speed range too high. To get the low speed range to a level that enables precision, I need to have the overall speed setting down at about -0.8. (Might be that I have some poor fine muscle control..) On your question on the circle, at a speed setting of 0, a 1cm circle on my touchpad = about 3.5cm circle on screen. (My best attempt to measure, don't read too much into the accuracy of this.) I did try another approach. Instead of trying to emulate a power profile like in my earlier patch, I tried making the minimal amount of changes to the existing profiles to make it feel right at both low speed and high speed. I first eliminated the scaling on the flat portion and fixed it at a lower level. This really improved the low end accuracy for me. Yet, the middle was still flat and not accelerating enough. I then pulled forward the threshold for the acceleration ramp by 50%. (Effectively starting the acceleration ramp up earlier). With both of these and a speed setting of about +0.75, things feel really good to me. I have the mid and high speed acceleration that feels right and also the low speed precision. I have attached a patch for reference and also a graph of the resulting profiles. FWIW, I will probably stick with using this patch as it feels pretty good. I get for others, it may not make sense. I guess this is the beauty of open source software! Thanks for taking the time to look at this. (And thanks for all your work on libinput!) Greg
Created attachment 136627 [details] Accel profiles from lowclip.patch Per comment above
Created attachment 136628 [details] [review] Lowclip patch This is the patch mentioned above that attempts to minimally modify existing accel profile. Pulls forward beginning of acceleration ramp and also fixes slow speed at a lower acceleration for accuracy. End result for me is good low speed precision and improved mid range acceleration.
(In reply to Greg Reichow from comment #16) > On your question on the circle, at a speed setting of 0, a 1cm circle on my > touchpad = about 3.5cm circle on screen. (My best attempt to measure, don't > read too much into the accuracy of this.) close enough, thanks. This indicates at least that we're not talking about two completely reactions but rather preferences. fwiw, at the -0.8 setting with current master, 1cm on the touchpad maps to ~1cm on the screen and the screen cursor feels like it's just a tad slower than the finger, a movement not triggering any acceleration eventually has the finger overtake the cursor. While that's acceptable for something that close to the lower range limit of -1, it would be way too slow for anything above. At a speed setting of 0.9 the cursor is effectively uncontrollable. Any faster movement hits the edge, a fast ~2cm movement crosses the whole screen. Again, for 0.9 that's acceptable because it's the upper range. But I'm really curious that you want such a slow default speed and such a fast acceleration. I tried your curve and the pointer is almost uncontrollable for me. When acceleration kicks in it shoots to an edge way too quickly, I end up overshooting by 5-10cm on anything but fast movements. So what's going on here?
Given your description, there must be something wrong still. I really need to crank up the speed setting to make it feel like it is accelerating at all. I am wondering if there is not something weird happening on inbound events that are being used to calculate the initial (pre-acceleration) velocities. I measured a sample of my usage doing normal navigation around the screen. Attached below is the profile. It really seems to me this is likely skewed very low. Does this match your normal velocity profile? I am going to do more digging to see if I can figure out why I am getting such low initial velocities (if indeed these are truly low). It makes sense that I am having a problem with these velocities as even with the speed set to 0.5, 92% of my movements never even hit the beginning of the acceleration curve. # Number of data points: 4284 # Highest velocity: 315.338257387 mm/s # Starting with 32 buckets # Reducing to 24 buckets (5 required per bucket) # Left with 4273 data points (99.7% of data) percent nevents total-percent speed --------- --------- --------------- ------- 12.0056 513 12.0056 10 11.8184 505 23.824 20 11.1631 477 34.9871 30 14.3459 613 49.333 40 13.3864 572 62.7194 50 5.055 216 67.7744 60 0.234028 10 68.0084 70 2.01264 86 70.0211 80 2.5041 107 72.5252 90 3.01896 129 75.5441 100 4.68055 200 80.2247 110 4.16569 178 84.3904 120 3.15937 135 87.5497 130 3.01896 129 90.5687 140 2.34028 100 92.909 150 2.41048 103 95.3194 160 1.42757 61 96.747 170 0.93611 40 97.6831 180 0.819097 35 98.5022 190 0.655277 28 99.1575 200 0.25743 11 99.4149 210 0.280833 12 99.6958 220 0.140417 6 99.8362 230 0.163819 7 100 240
sigh, this is how quickly two months disappear. sorry about this, busy with a million other things but this is on my radar again now. So: a 5 min browsing session shows this: # Number of data points: 12378 # Highest velocity: 5692.05937231 mm/s # Starting with 570 buckets # Reducing to 31 buckets (5 required per bucket) # Left with 12359 data points (99.8% of data) percent nevents total-percent speed ---------- --------- --------------- ------- 43.2964 5351 43.2964 10 13.65 1687 56.9464 20 7.60579 940 64.5521 30 5.34833 661 69.9005 40 4.70912 582 74.6096 50 4.34501 537 78.9546 60 3.50352 433 82.4581 70 2.83194 350 85.2901 80 2.20892 273 87.499 90 2.00663 248 89.5056 100 1.87717 232 91.3828 110 1.59398 197 92.9768 120 1.27033 157 94.2471 130 1.13278 140 95.3799 140 0.962861 119 96.3427 150 0.736306 91 97.0791 160 0.687758 85 97.7668 170 0.453111 56 98.2199 180 0.38029 47 98.6002 190 0.347925 43 98.9481 200 0.226556 28 99.1747 210 0.226556 28 99.4012 220 0.250829 31 99.6521 230 0.0728214 9 99.7249 240 0.0323651 4 99.7573 250 0.0404563 5 99.7977 260 0.0323651 4 99.8301 270 0.0485476 6 99.8786 280 0.0566389 7 99.9353 290 0.0242738 3 99.9595 300 0.0404563 5 100 310 note how almost half the events are in the 10-20mm/s bucket. So I don't think your measurement is out of the ordinary. I realised after recording that this was with the synaptics driver. Since there is a positive feedback loop, here's another session with libinput. I think any differences are more due to different interactions than the two drivers. # Number of data points: 7033 # Highest velocity: 1669.01036276 mm/s # Starting with 167 buckets # Reducing to 37 buckets (5 required per bucket) # Left with 7005 data points (99.6% of data) percent nevents total-percent speed ---------- --------- --------------- ------- 37.8016 2648 37.8016 10 16.8879 1183 54.6895 20 3.88294 272 58.5724 30 2.55532 179 61.1278 40 6.8808 482 68.0086 50 4.75375 333 72.7623 60 4.0828 286 76.8451 70 2.75517 193 79.6003 80 2.18415 153 81.7844 90 2.14133 150 83.9258 100 1.68451 118 85.6103 110 1.54176 108 87.152 120 1.3419 94 88.4939 130 1.22769 86 89.7216 140 1.18487 83 90.9065 150 1.01356 71 91.9201 160 1.02784 72 92.9479 170 0.913633 64 93.8615 180 0.842256 59 94.7038 190 0.813704 57 95.5175 200 0.770878 54 96.2884 210 0.6995 49 96.9879 220 0.613847 43 97.6017 230 0.342612 24 97.9443 240 0.399714 28 98.344 250 0.28551 20 98.6296 260 0.271235 19 98.9008 270 0.256959 18 99.1577 280 0.171306 12 99.3291 290 0.157031 11 99.4861 300 0.157031 11 99.6431 310 0.0856531 6 99.7288 320 0.0713776 5 99.8001 330 0.028551 2 99.8287 340 0.028551 2 99.8572 350 0.0713776 5 99.9286 360 0.0713776 5 100 370
Some notes after another afternoon of playing around with this: The script that produces the output above measures *physical* movements on the touchpad, thus the 'speed' on the right column represent 10mm/s physical movement, not pointer movement. IMO it makes sense that the majority comes in at below 20mm/s. Slow movements generate more events, fast movements are *short* movements with few events. I played around with a bunch of acceleration curves similar to attachment 136584 [details]. I used a linear curve instead for simplicity with varying inclines, starting acceleration at 40mm/s, inclines from 'roughly parallel to current' to 'roughly like attachment 136584 [details]'. They showed the same thing every time: the pointer is uncontrollable once we hit accel factor 3 [1] at anything but very low speeds. The fast pointer movement is multiplied by a high factor, resulting in ridiculous deltas and unpredictable pointers. A fixed factor 3 is just about controllable but would cause RSI after 5 min. I have in front of me: Lenovo T440s, Lenovo T450s, Dell XPS 13 9365, Asus E402S. All with Fedora 27, up-to-date (libinput 1.10.1). The touchpad behaviour is effectively identical [2] on all four machines. Bug 105375 is the next step here, once that's implemented we can at least compare full output. But right now, I know just as much as before :( All that aside, please confirm that you do *not* have a hidpi screen though. [1] factor 3 not accounting for the TP_MAGIC_SLOWDOWN, so effective factor 3 * 0.37 [2] The XPS has a hidpi screen and is slow under X, GNOME on wayland makes up for this but that's not a libinput issue.
Peter, do you happen to have access to a Mac running macOS? IMHO that's the benchmark of A+ touchpad experience. Yes, a lot of this is the good hardware, but a lot of it is also the acceleration curve; I continue to find libinput unusable with the default curve, but a joy using Greg's that patch mimics the macOS acceleration curve. With this, I have been able to finally switch from synaptics and use libinput full-time.
I do, a 2015 macbook air. And while I admit there are differences, I don't think they're that big. And that's the biggest puzzle, I can switch between the air and the t440 and notice a bit of a difference but it's not massive. Whereas the patch above that makes things useful for you makes the cursor absolutely uncontrollable - and with that I don't mean "i don't like it" but "i cannot hit a 200x200 size target with it" as soon as I'm going beyond crawling speed. So, *something* is off and I still have not yet identified what it is. Again: "please confirm that you do *not* have a hidpi screen"
Funny, I notice a MASSIVE difference (all Mac touchpads feel the same; there's no moderl/year difference in touchpad feel). I'm the kind of person who wants a touchpad so good that I don't feel the urge to use a mouse, so maybe I'm just picky. But I really really really do notice the difference. With Greg's patch, I have to use a -0.75 accel value, and it feels perfect. But there may be hardware-specific factors at play. My touchpad hardware is definitely not the highest quality in the world. I'm not married to Greg's patch per se; my issue with libinput's default acceleration curve is pretty simple to articulate: it accelerates too much at slow and slow-medium speeds. Check out the graph attached at https://bugs.freedesktop.org/attachment.cgi?id=136584: Up to 50 mm/s, the default acceleration is faster than with Greg's patch, and there's a very abrupt cliff where the acceleration increases. Aside from technical matters, I'm just not sure what the justification is for accelerating small movements that much. It makes precise control very difficult. I do not have a HiDPI screen (didn't know it was directed at me, sorry). Regular old 1920x1080 @ 13". Not sure it's relevant now since I'm using KDE Plasma with KWin, not GNOME with Mutter.
And here's the thing - libinput's acceleration works in physical distances. So the hw shouldn't really matter because a speed of 10mm/s is always that, regardless of the hardware. As long as touchpad-edge-detector and you agree on the ranges/dimensions on the hardware, there shouldn't be much difference. That acceleration in the attachment is actually a slowdown, we multiply the calculated input speed by a magic constant (0.37) so that a physical delta of 10mm should end up in a delta of 3.7mm [1], give or take with the changing screen resolution. Greg's patch just slows things down even further and a -0.75 should then make this even slower. The question was directed at anyone btw, sorry, should've made that clear. If you have a compositor that doesn't support hidpi, you'd see a slowdown because with twice the pixel density (which libinput knows nothing about) your delta is half as fast - but that's something the compositor has to take care of (mutter already does). It would be good if you could attach an evemu recording from a finger movement. Close your eyes, put your finger down and move from left to right at about 20mm/s - hard to guess I know but it's basically a medium movement. Then I can try to reproduce this here, maybe, hopefully. For reference: here's a video of me moving the finger and the corresponding cursor movement in the libinput debug-gui: https://photos.app.goo.gl/BTED3UdQwYqw5iW22 [1] having said that, I'm now wondering what's going on there, because if I move 10mm, it moves by ~10mm on the screen, not 3.7
> [1] having said that, I'm now wondering what's going on there, because if I move 10mm, it moves by ~10mm on the screen, not 3.7 And that, I think, is exactly the bug we're trying to get to the bottom of.
Couple comments to answer above: 1. Not using a Hi-dpi display. Reported resolution is 1680 x 1050. 2. Exact machine is a 2011 MacBook Pro 8,2 3. Agree the earlier patch was too fast. I also found I did not like the exponential acceleration from my first patch and have since switched full time to the last patch I submitted (lowclip_patch) which has a simple linear accel curve yet starts slower to enable precision at low speeds. For reference, my comfortable setting is 0. 4. I will try to get some similar video with the slow finger movement and share back with you. Is there a utility you have that records both physical input speed and also resulting cursor speed on screen? I wonder if something is not happening further up the stack from libinput and causing the differences in resulting pointer movement? (As I keep going through the libinput code and do not understand why we are seeing such different results from similar input speeds as you have shown above.)
https://github.com/whot/libinput/tree/wip/evemu-v3 is the closest I have so far. It's still WIP so the output format isn't stable. Run with: sudo ./build/libinput-record --with-libinput /dev/input/eventX (for the touchpad device). That will print the evdev events along with the libinput events. It's not evemu in that I don't have the python wrappers to process the data but that'll come eventually. I tested the lowclip patch - the base speed is too slow for my liking but I can accept how this could be a preference. The acceleration is still too fast with the pointer shooting off as soon as I move a bit faster than the speed in the video from comment #26
See video attached. This was using the lowclip patch I mentioned with accel @ 0. For reference, the physical trackpad distance covered in the video is about 90mm in 3 seconds. So roughly 30mm/sec. I roughly measured the distance covered on the screen, it is about 110mm-120mm. https://www.dropbox.com/s/g32jmah45so38ck/IMG_6781.MOV?dl=0 I then did another video with far faster movements, see below: https://www.dropbox.com/s/9yytyaydw26u5xt/IMG_6782.MOV?dl=0 Even with these movements at a significantly higher speed, I am still only covering about 50-75% of the screen width. Greg
Hooray. The good news: based on these videos, I don't think we have a libinput *bug*, this does appear to be just a different preference. AFAICT, the movement matches what I got with the lowclip patch, at least considering the finger motion speed etc. The bad news: to accommodate for this, we'd need some new pointer acceleration profile because if *that* is your preferred behaviour, it's going to be difficult to find a middle ground between the current and your patch. Because I consider the fast pointer motion (like in your second video) to be uncontrollable, I don't even get near any target when moving fast. Adding a new profile is relatively trivial, but it opens us up to a few things: once you have two profiles, the floodgates are open for N profiles. Anyone not happy with the current profile will be pushing for another profile slightly different and that's a situation I really want to avoid. fwiw, my macos at default speed is a lot faster than the lowclip patch. And given that we have the accel range, I think the first thing to look at is moving that baseline. From what I can tell, the macos accel doesn't have that same unaccelerated plateau that we have, it seems to almost contineously linear.
doh, sorry, hit the wrong button. Continued: More experimenting with the lowclip patch is needed, and it needs to be compared to the original touchpad pointer accel (for which I got a lot of complaints for, so let's not go back to that). I think macos may also use pressure values (well, touch sizes) for acceleration, but I'm not 100% of that. What it definitely has is deceleration at low speeds, that bit is missing from the lowclip patch. So the things to do to get closer to macos (from git master): * keep deceleration at super-low speed * shorten the plateau * experiment with the incline a bit more * verify max accel is still useful once the above is there * slightly reduce the baseline lowclip does 2 and 5 of these already, but the baseline is too low for a default setting. If you want it that low, you can reduce your speed in the config. The rest, well, we'll have to experiment to see if we come to some agreement :)
Created attachment 138012 [details] [review] 0001-filter-match-accel-roughly-with-macos.patch This patch matches the macos pointer acceleration, afaict, at least at speed 0 and the min/max ranges sort-of match as well. +1.0 is more controllable than macos IMO. The negative ranges close to -1.0 have a tendency to shoot off too much, I think we need some lower max-accel caps here. Anyway, give this one a try please and let me know what you think.
Thanks, I'll give that a whirl later today!
Preliminary impressions: Feels quite nice at 0.0 "libinput accel speed" (i.e with no configuration). Definitely an improvement over the current profile. It does still feel like there's an abrupt jump in acceleration between medium and fast movements, but I think I could live with it.
The jump is probably caused by the angle between flat and actual acceleration which still looks like this: _/ (ascii-art! :) Smoothing this out to be more of a curve may or may not help. Or the jump is caused by the incline being too steep and acceleration kicking in too quickly, if you could play around with that that'd be much appreciated.
I think it's both. If you think about it; they're two sides of the same coin: a shallower initial acceleration starts to look like a smooth curve the more segments are added. Since it's a definite improvement in my book, it might be worth committing and then we can continue to tweak it later. Or should we shoot for fully resolving the issue in one fell swoop?
For the archives, I've done a visual comparison to the synaptics driver, basically by running Xorg with synaptics and libinput debug-gui with libinput (without the patch above, just git master at a59ce1c) and looking at the two cursors. Tests done with libinput acceleration 0 and synaptics' default acceleration without any changed settings. 1) at really slow motion libinput applies deceleration, cursor speed is approx the same for both. That's for things like slowly rolling the finger. 2) at slow motion libinput has a much higher acceleration factor than synaptics, possibly twice as high. Thats for slowly moving the finger across the touchpad. 3) at some medium speeds, libinput acceleration is still the same baseline but synaptics starts to accelerate already. This is where synaptics gets faster than libinput. 4) at high speeds, the acceleration rate is roughly the same but the maximum acceleration differs. When jerking the finger between two positions, sometimes the cursors move in parallel, sometimes the libinput cursor moves further than the synaptics one. Despite my best efforts so far, I have yet to figure out how to print the synaptics acceleration curves for analysis. I've tried a few things but none of them match the perceived movements. There are too many factors and they are hard to calculate (e.g. screen resolution plays a part). Specifically, once the cursor is at the edges the behaviour changes and separating that is difficult.
I forgot: to do the above test, #if 0 around gdk_window_set_cursor() in tools/libinput-debug-gui.c, otherwise the system cursor is not visible.
Can I get you to try a84e79b4aee3563a37485de13c9448981afa4f7c on https://github.com/whot/libinput/tree/wip/touchpad-pointer-accel-v5 This one has a more adjusted curve, close to the macos one but with less harsh kick-in. That happens earlier too, combined with a lower baseline.
(In reply to Peter Hutterer from comment #40) > Can I get you to try a84e79b4aee3563a37485de13c9448981afa4f7c on > https://github.com/whot/libinput/tree/wip/touchpad-pointer-accel-v5 > > This one has a more adjusted curve, close to the macos one but with less > harsh kick-in. That happens earlier too, combined with a lower baseline. I tested it some this morning and find it to be a good improvement. I am still having a small amount of lack of precision with small movements and a little too slow when trying to move quickly. That said, it is far better than the baseline I was testing and commenting on earlier. Thanks for your work on this. This would definitely be usable for me. As another reference for profiling, I have been back in the land of Xorg lately as I am using i3. The mtrack driver performs very nicely with my hardware and might be another baseline for comparison. Yet I assume it suffers from the same complexity that you described with the Synaptics driver.
Awesome, thanks. I hope Nathan can chime in too with some testing comments, I'll work on getting the range of the acceleration right (or at least big enough that it should cover most cases). that should, hopefully, improve the remaining issues. mtrack is a tricky beast. It's GPL which means I can't look at it for ideas for libinput without it getting problematic (libinput is MIT). So I don't know if it has a custom acceleration function but if it does similar initialization to the synaptics driver than most is handled in the server. but yeah, for testing and comparison I should probably start using it...
Still not quite perfect, but definitely better than the status quo! Feels best for me at around accel value -0.1. I can still feel that jarring hard "jump" when the acceleration curve changes. And it is still a bit (but now only a bit, not a lot) too fast for slow movements. I'll try to keep using it for a few days. Also hysteresis turned itself back on... :/ I really, really dislike how it keeps turning itself back on every time I re-compile and deploy libinput. It's incredibly frustrating.
Created attachment 138716 [details] synaptics-libinput-comparison.svg Please keep this bug on-topic, the hysteresis issues are not for this bug. Attaching my best efforts to compare synaptics and libinput for archival purposes. The libinput curve is printed directly with the ptraccel-debug tool (this is git master without the patches above). For the synaptics curve, I created a uinput device that moves a touch from left to right at decreasing time intervals and eventually gets to the maximum speeds shown. The various values were printed as YAML to the xorg.log and extracted from there with custom python scripts. Since the server uses device coordinates everywhere, I divided the velocity for synaptics values by the resolution I used in the uinput device. This should give us mm. The curves shown in the diagram are: "synaptics" - the accelfct as returned from SynapticsAccelerationProfile for a given speed. Notice how the curve isn't too dissimilar to the libinput curve in shape, albeit the libinput curve includes the final accel factor. "mult" - the multiplier used in the server's acceleratePointerPredictable(), after taking constant deceleration and the synaptics acceleration factor into account. This mult factor is then applied to the input deltas (these are in device coordinates) and the closest match to the 'accel factor' that libinput uses (but see below). "libinput" - libinput accel factor applied to a delta at any given speed. Constant deceleration in synaptics is 1/2.5 (0.4), and quite similar to the MAGIC we use in libinput (0.37). That latter one was found by trial and error but having those two similar indicates this is a good value. I haven't even tried to change synaptics acceleration options, this makes it even harder... To the best of my knowledge, the curves are correct. But honestly, this is all so convoluted that it's hard to be sure. And note that after applying the acceleration factor, the device coordinates are scaled into screen coordinates which depends on the screen resolution. IOW, different results for larger screens (or screens with different aspect ratios). And for all I know, this may change the curve significantly but this is even harder to test because the rescaling will clip at screen edges and my testing approach hit those very quickly. Also, neither libinput nor synaptics are that simple, there is some analysis of previous events to adjust the acceleration curve (e.g. on directional changes).
In 90-libinput-model-quirks.hwdb the two current rules end with a colon I don't know the syntax of this file, but there is no other example of this pattern in the file when I made a separate P50 rule, I did not use a colon at the end, and it worked. we do see :* at the end of a few rules. libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??50*: libinput:name:SynPS/2 Synaptics TouchPad:dmi:*svnLENOVO:*:pvrThinkPad??60*:
sorry wrong bug report
Ok, another version to test please: https://github.com/whot/libinput/tree/wip/touchpad-pointer-accel-v6 Still feels roughly like the macOS one though there are some differences that tbh I can't quite put my finger on. Either way, it feels precise enough, especially at -0.1 (for me).
That feels *fantastic* to me. I'd be very happy to see that in a real release. I've been living with v5 and it was already pretty good. I got used to it fairly quickly. This one is even better.
Patch (squashed and polished) is on the list now: https://lists.freedesktop.org/archives/wayland-devel/2018-May/038172.html The speed range has significantly increased, so this should cover more use-cases.
Being someone who prefers the macOS touchpad acceleration curve, that patch radically improves things for my hardware and motion preferences. Bug thumbs up from me!
patch is on master now, thanks for testing! commit d6e531349745ff38ae457169d5089ea61297accf Author: Peter Hutterer <> Date: Mon Mar 12 15:24:07 2018 +1000 filter: improve touchpad acceleration
Yep, this is fixed for me. Many thanks for all your hard work, Peter!
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.