[PATCH libinput] filter: improve touchpad acceleration

Peter Hutterer peter.hutterer at who-t.net
Mon May 14 05:10:49 UTC 2018


This seems to give me roughly the same behaviour as macos does on the default
0 speed setting.

* Default speed is lower than before by around 30% [1]
* Acceleration kicks in much sooner (130mm/s vs 250mm/s before)
* Acceleration kicks in slower at lower speeds, so the change from 130mm/s to
  150mm/s is less than that of 320mm/s to 350mm/s
* The effect of the speed setting is a wide-range constant (de|ac)celeration
  [2], which means:
  * The unaccelerated baseline up until the threshold now changes with the
    speed setting
  * The threshold is now the same for all speeds
  * The range of the speed setting should now easily cover all desired device
    speeds.
  * Acceleration is steeper at higher speeds
* Deceleration was left as-is.

[1] This may or may not fix the jumping pointer issues caused by the previous
high defaults. When you have high default acceleration you move the finger
slower. This slow movement caused some touchpads (mostly seen on Lenovos) to
create pointer jumps. These weren't seen on synaptics previously because of a
combination of higher user finger speed (thus not triggering the bug) or just
not being as obvious (2px jump vs 10 px jump).

[2] The speed setting is actually a curve, the closer you get to 1.0 the more
difference you see between two different values. The curve's points are:
-1/0, 0/1, 1/5, so the resolution is closer for slow speeds. We still have
double resolution on the setting though so you'll find what you want.

https://bugs.freedesktop.org/show_bug.cgi?id=101139

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
As the comments say, it's a lot of trial-and-error. When testing give
yourself a bit of time to adjust, it's different and muscle memory takes a
while (20min or more) to catch up.

The branch is available here for testing.
https://github.com/whot/libinput/tree/wip/touchpad-pointer-accel-v7

Somewhat related reading:
https://who-t.blogspot.com.au/2018/05/x-server-pointer-acceleration-analysis-part1.html
https://who-t.blogspot.com.au/2018/05/x-server-pointer-acceleration-analysis-part2.html
https://who-t.blogspot.com.au/2018/05/x-server-pointer-acceleration-analysis-part3.html
https://who-t.blogspot.com.au/2018/05/x-server-pointer-acceleration-analysis-part4.html
Especially part 4.

 doc/svg/ptraccel-trackpoint.svg | 141 +++++++++-------------------------------
 src/filter-touchpad.c           | 110 ++++++++++++++++++-------------
 2 files changed, 95 insertions(+), 156 deletions(-)

diff --git a/doc/svg/ptraccel-trackpoint.svg b/doc/svg/ptraccel-trackpoint.svg
index 59eec520..47078733 100644
--- a/doc/svg/ptraccel-trackpoint.svg
+++ b/doc/svg/ptraccel-trackpoint.svg
@@ -77,23 +77,33 @@
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='black'  d='M185.2,422.4 L185.2,413.4 M185.2,16.7 L185.2,25.7  '/>	<g transform="translate(185.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
-		<text><tspan font-family="Arial" > 5</tspan></text>
+	<path stroke='black'  d='M141.9,422.4 L141.9,413.4 M141.9,16.7 L141.9,25.7  '/>	<g transform="translate(141.9,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
+		<text><tspan font-family="Arial" > 0.0005</tspan></text>
+	</g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+	<path stroke='black'  d='M228.5,422.4 L228.5,413.4 M228.5,16.7 L228.5,25.7  '/>	<g transform="translate(228.5,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
+		<text><tspan font-family="Arial" > 0.001</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<path stroke='black'  d='M315.2,422.4 L315.2,413.4 M315.2,16.7 L315.2,25.7  '/>	<g transform="translate(315.2,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
-		<text><tspan font-family="Arial" > 10</tspan></text>
+		<text><tspan font-family="Arial" > 0.0015</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='black'  d='M445.1,422.4 L445.1,413.4 M445.1,16.7 L445.1,25.7  '/>	<g transform="translate(445.1,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
-		<text><tspan font-family="Arial" > 15</tspan></text>
+	<path stroke='black'  d='M401.8,422.4 L401.8,413.4 M401.8,16.7 L401.8,25.7  '/>	<g transform="translate(401.8,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
+		<text><tspan font-family="Arial" > 0.002</tspan></text>
+	</g>
+</g>
+<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
+	<path stroke='black'  d='M488.4,422.4 L488.4,413.4 M488.4,16.7 L488.4,25.7  '/>	<g transform="translate(488.4,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
+		<text><tspan font-family="Arial" > 0.0025</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<path stroke='black'  d='M575.0,422.4 L575.0,413.4 M575.0,16.7 L575.0,25.7  '/>	<g transform="translate(575.0,444.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
-		<text><tspan font-family="Arial" > 20</tspan></text>
+		<text><tspan font-family="Arial" > 0.003</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
@@ -107,139 +117,48 @@
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<g transform="translate(315.1,471.3)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="middle">
-		<text><tspan font-family="Arial" >delta (units)</tspan></text>
+		<text><tspan font-family="Arial" >speed in units/us</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 </g>
-	<g id="gnuplot_plot_1" ><title>-1</title>
+	<g id="gnuplot_plot_1" ><title>linear (mouse)</title>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<g transform="translate(507.9,38.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >-1</tspan></text>
+		<text><tspan font-family="Arial" >linear (mouse)</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(148,   0, 211)'  d='M516.2,34.7 L558.4,34.7 M55.3,422.4 L60.5,418.5 L65.7,414.6 L70.9,410.7 L76.1,406.8 L81.3,402.9
-		L86.5,399.0 L91.7,395.1 L96.9,391.2 L102.1,387.3 L107.3,383.5 L112.5,379.6 L117.7,375.7 L122.9,371.8
-		L128.1,367.9 L133.3,364.0 L138.5,360.1 L143.6,356.2 L148.8,352.3 L154.0,348.4 L159.2,344.5 L164.4,340.6
-		L169.6,336.7 L174.8,332.8 L180.0,328.9 L185.2,325.0 L190.4,321.1 L195.6,317.2 L200.8,313.3 L206.0,310.0
-		L211.2,310.0 L216.4,310.0 L221.6,310.0 L226.8,310.0 L232.0,310.0 L237.2,310.0 L242.4,310.0 L247.6,310.0
-		L252.8,310.0 L258.0,310.0 L263.2,310.0 L268.4,310.0 L273.6,310.0 L278.8,310.0 L284.0,310.0 L289.2,310.0
-		L294.4,310.0 L299.6,310.0 L304.8,310.0 L310.0,310.0 L315.2,310.0 L320.3,310.0 L325.5,310.0 L330.7,310.0
-		L335.9,310.0 L341.1,310.0 L346.3,310.0 L351.5,310.0 L356.7,310.0 L361.9,310.0 L367.1,310.0 L372.3,310.0
-		L377.5,310.0 L382.7,310.0 L387.9,310.0 L393.1,310.0 L398.3,310.0 L403.5,310.0 L408.7,310.0 L413.9,310.0
-		L419.1,310.0 L424.3,310.0 L429.5,310.0 L434.7,310.0 L439.9,310.0 L445.1,310.0 L450.3,310.0 L455.5,310.0
-		L460.7,310.0 L465.9,310.0 L471.1,310.0 L476.3,310.0 L481.5,310.0 L486.7,310.0 L491.8,310.0 L497.0,310.0
-		L502.2,310.0 L507.4,310.0 L512.6,310.0 L517.8,310.0 L523.0,310.0 L528.2,310.0 L533.4,310.0 L538.6,310.0
-		L543.8,310.0 L549.0,310.0 L554.2,310.0 L559.4,310.0 L564.6,310.0 L569.8,310.0 L575.0,310.0  '/></g>
+	<path stroke='rgb(148,   0, 211)'  d='M516.2,34.7 L558.4,34.7 M55.3,398.1 L575.0,398.0  '/></g>
 	</g>
-	<g id="gnuplot_plot_2" ><title>-0.75</title>
+	<g id="gnuplot_plot_2" ><title>const accel 1</title>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<g transform="translate(507.9,56.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >-0.75</tspan></text>
+		<text><tspan font-family="Arial" >const accel 1</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(  0, 158, 115)'  d='M516.2,52.7 L558.4,52.7 M55.3,422.4 L60.5,415.3 L65.7,408.1 L70.9,401.0 L76.1,393.8 L81.3,386.7
-		L86.5,379.6 L91.7,372.4 L96.9,365.3 L102.1,358.1 L107.3,351.0 L112.5,343.9 L117.7,336.7 L122.9,329.6
-		L128.1,322.4 L133.3,315.3 L138.5,308.2 L143.6,301.0 L148.8,293.9 L154.0,286.7 L159.2,279.6 L164.4,272.5
-		L169.6,270.7 L174.8,270.7 L180.0,270.7 L185.2,270.7 L190.4,270.7 L195.6,270.7 L200.8,270.7 L206.0,270.7
-		L211.2,270.7 L216.4,270.7 L221.6,270.7 L226.8,270.7 L232.0,270.7 L237.2,270.7 L242.4,270.7 L247.6,270.7
-		L252.8,270.7 L258.0,270.7 L263.2,270.7 L268.4,270.7 L273.6,270.7 L278.8,270.7 L284.0,270.7 L289.2,270.7
-		L294.4,270.7 L299.6,270.7 L304.8,270.7 L310.0,270.7 L315.2,270.7 L320.3,270.7 L325.5,270.7 L330.7,270.7
-		L335.9,270.7 L341.1,270.7 L346.3,270.7 L351.5,270.7 L356.7,270.7 L361.9,270.7 L367.1,270.7 L372.3,270.7
-		L377.5,270.7 L382.7,270.7 L387.9,270.7 L393.1,270.7 L398.3,270.7 L403.5,270.7 L408.7,270.7 L413.9,270.7
-		L419.1,270.7 L424.3,270.7 L429.5,270.7 L434.7,270.7 L439.9,270.7 L445.1,270.7 L450.3,270.7 L455.5,270.7
-		L460.7,270.7 L465.9,270.7 L471.1,270.7 L476.3,270.7 L481.5,270.7 L486.7,270.7 L491.8,270.7 L497.0,270.7
-		L502.2,270.7 L507.4,270.7 L512.6,270.7 L517.8,270.7 L523.0,270.7 L528.2,270.7 L533.4,270.7 L538.6,270.7
-		L543.8,270.7 L549.0,270.7 L554.2,270.7 L559.4,270.7 L564.6,270.7 L569.8,270.7 L575.0,270.7  '/></g>
+	<path stroke='rgb(  0, 158, 115)'  d='M516.2,52.7 L558.4,52.7 M55.3,422.4 L575.0,422.1  '/></g>
 	</g>
-	<g id="gnuplot_plot_3" ><title>-0.5</title>
+	<g id="gnuplot_plot_3" ><title>const accel 2</title>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<g transform="translate(507.9,74.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >-0.5</tspan></text>
+		<text><tspan font-family="Arial" >const accel 2</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb( 86, 180, 233)'  d='M516.2,70.7 L558.4,70.7 M55.3,422.4 L60.5,412.0 L65.7,401.6 L70.9,391.2 L76.1,380.9 L81.3,370.5
-		L86.5,360.1 L91.7,349.7 L96.9,339.3 L102.1,328.9 L107.3,318.5 L112.5,308.2 L117.7,297.8 L122.9,287.4
-		L128.1,277.0 L133.3,266.6 L138.5,256.2 L143.6,245.8 L148.8,235.5 L154.0,225.1 L159.2,217.6 L164.4,217.6
-		L169.6,217.6 L174.8,217.6 L180.0,217.6 L185.2,217.6 L190.4,217.6 L195.6,217.6 L200.8,217.6 L206.0,217.6
-		L211.2,217.6 L216.4,217.6 L221.6,217.6 L226.8,217.6 L232.0,217.6 L237.2,217.6 L242.4,217.6 L247.6,217.6
-		L252.8,217.6 L258.0,217.6 L263.2,217.6 L268.4,217.6 L273.6,217.6 L278.8,217.6 L284.0,217.6 L289.2,217.6
-		L294.4,217.6 L299.6,217.6 L304.8,217.6 L310.0,217.6 L315.2,217.6 L320.3,217.6 L325.5,217.6 L330.7,217.6
-		L335.9,217.6 L341.1,217.6 L346.3,217.6 L351.5,217.6 L356.7,217.6 L361.9,217.6 L367.1,217.6 L372.3,217.6
-		L377.5,217.6 L382.7,217.6 L387.9,217.6 L393.1,217.6 L398.3,217.6 L403.5,217.6 L408.7,217.6 L413.9,217.6
-		L419.1,217.6 L424.3,217.6 L429.5,217.6 L434.7,217.6 L439.9,217.6 L445.1,217.6 L450.3,217.6 L455.5,217.6
-		L460.7,217.6 L465.9,217.6 L471.1,217.6 L476.3,217.6 L481.5,217.6 L486.7,217.6 L491.8,217.6 L497.0,217.6
-		L502.2,217.6 L507.4,217.6 L512.6,217.6 L517.8,217.6 L523.0,217.6 L528.2,217.6 L533.4,217.6 L538.6,217.6
-		L543.8,217.6 L549.0,217.6 L554.2,217.6 L559.4,217.6 L564.6,217.6 L569.8,217.6 L575.0,217.6  '/></g>
+	<path stroke='rgb( 86, 180, 233)'  d='M516.2,70.7 L558.4,70.7 M55.3,422.4 L575.0,422.1  '/></g>
 	</g>
-	<g id="gnuplot_plot_4" ><title>-0.25</title>
+	<g id="gnuplot_plot_4" ><title>const accel 3</title>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
 	<g transform="translate(507.9,92.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >-0.25</tspan></text>
+		<text><tspan font-family="Arial" >const accel 3</tspan></text>
 	</g>
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(230, 159,   0)'  d='M516.2,88.7 L558.4,88.7 M55.3,422.4 L60.5,408.8 L65.7,395.1 L70.9,381.5 L76.1,367.9 L81.3,354.2
-		L86.5,340.6 L91.7,327.0 L96.9,313.3 L102.1,299.7 L107.3,286.1 L112.5,272.5 L117.7,258.8 L122.9,245.2
-		L128.1,231.6 L133.3,217.9 L138.5,204.3 L143.6,190.7 L148.8,177.0 L154.0,163.4 L159.2,149.8 L164.4,145.9
-		L169.6,145.9 L174.8,145.9 L180.0,145.9 L185.2,145.9 L190.4,145.9 L195.6,145.9 L200.8,145.9 L206.0,145.9
-		L211.2,145.9 L216.4,145.9 L221.6,145.9 L226.8,145.9 L232.0,145.9 L237.2,145.9 L242.4,145.9 L247.6,145.9
-		L252.8,145.9 L258.0,145.9 L263.2,145.9 L268.4,145.9 L273.6,145.9 L278.8,145.9 L284.0,145.9 L289.2,145.9
-		L294.4,145.9 L299.6,145.9 L304.8,145.9 L310.0,145.9 L315.2,145.9 L320.3,145.9 L325.5,145.9 L330.7,145.9
-		L335.9,145.9 L341.1,145.9 L346.3,145.9 L351.5,145.9 L356.7,145.9 L361.9,145.9 L367.1,145.9 L372.3,145.9
-		L377.5,145.9 L382.7,145.9 L387.9,145.9 L393.1,145.9 L398.3,145.9 L403.5,145.9 L408.7,145.9 L413.9,145.9
-		L419.1,145.9 L424.3,145.9 L429.5,145.9 L434.7,145.9 L439.9,145.9 L445.1,145.9 L450.3,145.9 L455.5,145.9
-		L460.7,145.9 L465.9,145.9 L471.1,145.9 L476.3,145.9 L481.5,145.9 L486.7,145.9 L491.8,145.9 L497.0,145.9
-		L502.2,145.9 L507.4,145.9 L512.6,145.9 L517.8,145.9 L523.0,145.9 L528.2,145.9 L533.4,145.9 L538.6,145.9
-		L543.8,145.9 L549.0,145.9 L554.2,145.9 L559.4,145.9 L564.6,145.9 L569.8,145.9 L575.0,145.9  '/></g>
+	<path stroke='rgb(230, 159,   0)'  d='M516.2,88.7 L558.4,88.7 M55.3,422.4 L575.0,422.1  '/></g>
 	</g>
-	<g id="gnuplot_plot_5" ><title>0</title>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<g transform="translate(507.9,110.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >0</tspan></text>
-	</g>
-</g>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(240, 228,  66)'  d='M516.2,106.7 L558.4,106.7 M55.3,422.4 L60.5,405.5 L65.7,388.6 L70.9,371.8 L76.1,354.9 L81.3,338.0
-		L86.5,321.1 L91.7,304.3 L96.9,287.4 L102.1,270.5 L107.3,253.6 L112.5,236.8 L117.7,219.9 L122.9,203.0
-		L128.1,186.1 L133.3,169.2 L138.5,152.4 L143.6,135.5 L148.8,118.6 L154.0,101.7 L159.2,84.9 L164.4,68.0
-		L169.6,51.1 L174.8,49.2 L180.0,49.2 L185.2,49.2 L190.4,49.2 L195.6,49.2 L200.8,49.2 L206.0,49.2
-		L211.2,49.2 L216.4,49.2 L221.6,49.2 L226.8,49.2 L232.0,49.2 L237.2,49.2 L242.4,49.2 L247.6,49.2
-		L252.8,49.2 L258.0,49.2 L263.2,49.2 L268.4,49.2 L273.6,49.2 L278.8,49.2 L284.0,49.2 L289.2,49.2
-		L294.4,49.2 L299.6,49.2 L304.8,49.2 L310.0,49.2 L315.2,49.2 L320.3,49.2 L325.5,49.2 L330.7,49.2
-		L335.9,49.2 L341.1,49.2 L346.3,49.2 L351.5,49.2 L356.7,49.2 L361.9,49.2 L367.1,49.2 L372.3,49.2
-		L377.5,49.2 L382.7,49.2 L387.9,49.2 L393.1,49.2 L398.3,49.2 L403.5,49.2 L408.7,49.2 L413.9,49.2
-		L419.1,49.2 L424.3,49.2 L429.5,49.2 L434.7,49.2 L439.9,49.2 L445.1,49.2 L450.3,49.2 L455.5,49.2
-		L460.7,49.2 L465.9,49.2 L471.1,49.2 L476.3,49.2 L481.5,49.2 L486.7,49.2 L491.8,49.2 L497.0,49.2
-		L502.2,49.2 L507.4,49.2 L512.6,49.2 L517.8,49.2 L523.0,49.2 L528.2,49.2 L533.4,49.2 L538.6,49.2
-		L543.8,49.2 L549.0,49.2 L554.2,49.2 L559.4,49.2 L564.6,49.2 L569.8,49.2 L575.0,49.2  '/></g>
-	</g>
-	<g id="gnuplot_plot_6" ><title>0.5</title>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<g transform="translate(507.9,128.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >0.5</tspan></text>
-	</g>
-</g>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(  0, 114, 178)'  d='M516.2,124.7 L558.4,124.7 M55.3,422.4 L60.5,399.0 L65.7,375.7 L70.9,352.3 L76.1,328.9 L81.3,305.6
-		L86.5,282.2 L91.7,258.8 L96.9,235.5 L102.1,212.1 L107.3,188.7 L112.5,165.3 L117.7,142.0 L122.9,118.6
-		L128.1,95.2 L133.3,71.9 L138.5,48.5 L143.6,25.1 L145.5,16.7  '/></g>
-	</g>
-	<g id="gnuplot_plot_7" ><title>1</title>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<g transform="translate(507.9,146.6)" stroke="none" fill="black" font-family="Arial" font-size="12.00"  text-anchor="end">
-		<text><tspan font-family="Arial" >1</tspan></text>
-	</g>
-</g>
-<g fill="none" color="black" stroke="currentColor" stroke-width="1.00" stroke-linecap="butt" stroke-linejoin="miter">
-	<path stroke='rgb(229,  30,  16)'  d='M516.2,142.7 L558.4,142.7 M55.3,422.4 L60.5,392.5 L65.7,362.7 L70.9,332.8 L76.1,303.0 L81.3,273.1
-		L86.5,243.2 L91.7,213.4 L96.9,183.5 L102.1,153.7 L107.3,123.8 L112.5,93.9 L117.7,64.1 L122.9,34.2
-		L125.9,16.7  '/></g>
-	</g>
-<g fill="none" color="#FFFFFF" stroke="rgb(229,  30,  16)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
+<g fill="none" color="#FFFFFF" stroke="rgb(230, 159,   0)" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
 </g>
 <g fill="none" color="black" stroke="currentColor" stroke-width="2.00" stroke-linecap="butt" stroke-linejoin="miter">
 </g>
diff --git a/src/filter-touchpad.c b/src/filter-touchpad.c
index 8b40b6e7..cfad1968 100644
--- a/src/filter-touchpad.c
+++ b/src/filter-touchpad.c
@@ -40,13 +40,7 @@
  * technically correct but subjectively wrong, we expect a touchpad to be a
  * lot slower than a mouse. Apply a magic factor to slow down all movements
  */
-#define TP_MAGIC_SLOWDOWN 0.37 /* unitless factor */
-
-/* Touchpad acceleration */
-#define TOUCHPAD_DEFAULT_THRESHOLD 254		/* mm/s */
-#define TOUCHPAD_THRESHOLD_RANGE 184		/* mm/s */
-#define TOUCHPAD_ACCELERATION 9.0		/* unitless factor */
-#define TOUCHPAD_INCLINE 0.011			/* unitless factor */
+#define TP_MAGIC_SLOWDOWN 0.2968 /* unitless factor */
 
 struct touchpad_accelerator {
 	struct motion_filter base;
@@ -60,9 +54,10 @@ struct touchpad_accelerator {
 
 	double threshold;	/* units/us */
 	double accel;		/* unitless factor */
-	double incline;		/* incline of the function */
 
 	int dpi;
+
+	double speed_factor;    /* factor based on speed setting */
 };
 
 /**
@@ -147,6 +142,30 @@ accelerator_filter_post_normalized(struct motion_filter *filter,
 	return normalize_for_dpi(&accelerated, accel->dpi);
 }
 
+/* Maps the [-1, 1] speed setting into a constant acceleration
+ * range. This isn't a linear scale, we keep 0 as the 'optimized'
+ * mid-point and scale down to 0 for setting -1 and up to 5 for
+ * setting 1. On the premise that if you want a faster cursor, it
+ * doesn't matter as much whether you have 0.56789 or 0.56790,
+ * but for lower settings it does because you may lose movements.
+ * *shrug*.
+ *
+ * Magic numbers calculated by MyCurveFit.com, data points were
+ *  0.0 0.0
+ *  0.1 0.1 (because we need 4 points)
+ *  1   1
+ *  2   5
+ *
+ *  This curve fits nicely into the range necessary.
+ */
+static inline double
+speed_factor(double s)
+{
+	s += 1; /* map to [0, 2] */
+	return 435837.2 + (0.04762636 - 435837.2)/(1 + pow(s/240.4549,
+							   2.377168));
+}
+
 static bool
 touchpad_accelerator_set_speed(struct motion_filter *filter,
 		      double speed_adjustment)
@@ -156,15 +175,8 @@ touchpad_accelerator_set_speed(struct motion_filter *filter,
 
 	assert(speed_adjustment >= -1.0 && speed_adjustment <= 1.0);
 
-	/* Note: the numbers below are nothing but trial-and-error magic,
-	   don't read more into them other than "they mostly worked ok" */
-
-	/* adjust when accel kicks in */
-	accel_filter->threshold = TOUCHPAD_DEFAULT_THRESHOLD -
-		TOUCHPAD_THRESHOLD_RANGE * speed_adjustment;
-	accel_filter->accel = TOUCHPAD_ACCELERATION;
-	accel_filter->incline = TOUCHPAD_INCLINE;
 	filter->speed_adjustment = speed_adjustment;
+	accel_filter->speed_factor = speed_factor(speed_adjustment);
 
 	return true;
 }
@@ -214,9 +226,8 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
 {
 	struct touchpad_accelerator *accel_filter =
 		(struct touchpad_accelerator *)filter;
-	const double max_accel = accel_filter->accel; /* unitless factor */
 	const double threshold = accel_filter->threshold; /* units/us */
-	const double incline = accel_filter->incline;
+	const double baseline = 0.9;
 	double factor; /* unitless */
 
 	/* Convert to mm/s because that's something one can understand */
@@ -229,20 +240,21 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
 
 	  accel
 	 factor
-	   ^
-	   |        /
-	   |  _____/
+	   ^         ______
+	   |        )
+	   |  _____)
 	   | /
 	   |/
 	   +-------------> speed in
 
-	   The two inclines are linear functions in the form
+	   Except the second incline is a curve, but well, asciiart.
+
+	   The first incline is a linear function in the form
 		   y = ax + b
 		   where y is speed_out
 		         x is speed_in
 			 a is the incline of acceleration
 			 b is minimum acceleration factor
-
 	   for speeds up to the lower threshold, we decelerate, down to 30%
 	   of input speed.
 		   hence 1 = a * 7 + 0.3
@@ -250,37 +262,47 @@ touchpad_accel_profile_linear(struct motion_filter *filter,
 		   deceleration function is thus:
 			y = 0.1x + 0.3
 
+	   The first plateau is the baseline.
+
+	   The second incline is a curve up, based on magic numbers
+	   obtained by trial-and-error.
+
+	   Above the second incline we have another plateau because
+	   by then you're moving so fast that extra acceleration doesn't
+	   help.
+
 	  Note:
 	  * The minimum threshold is a result of trial-and-error and
-	    has no other intrinsic meaning.
+	    has no other special meaning.
 	  * 0.3 is chosen simply because it is above the Nyquist frequency
 	    for subpixel motion within a pixel.
 	*/
+
 	if (speed_in < 7.0) {
-		factor = 0.1 * speed_in + 0.3;
+		factor = min(baseline, 0.1 * speed_in + 0.3);
 	/* up to the threshold, we keep factor 1, i.e. 1:1 movement */
 	} else if (speed_in < threshold) {
-		factor = 1;
+		factor = baseline;
 	} else {
-	/* Acceleration function above the threshold:
-		y = ax' + b
-		where T is threshold
-		      x is speed_in
-		      x' is speed
-	        and
-			y(T) == 1
-		hence 1 = ax' + 1
-			=> x' := (x - T)
+
+	/* Acceleration function above the threshold is a curve up
+	   to four times the threshold, because why not.
+
+	   Don't assume anything about the specific numbers though, this was
+	   all just trial and error by tweaking numbers here and there, then
+	   the formula was optimized doing basic maths.
+
+	   You could replace this with some other random formula that gives
+	   the same numbers and it would be just as correct.
+
 	 */
-		factor = incline * (speed_in - threshold) + 1;
+		const double upper_threshold = threshold * 4.0;
+		speed_in = min(speed_in, upper_threshold);
+
+		factor = 0.0025 * (speed_in/threshold) * (speed_in - threshold) + baseline;
 	}
 
-	/* Cap at the maximum acceleration factor */
-	factor = min(max_accel, factor);
-
-	/* Scale everything depending on the acceleration set */
-	factor *= 1 + 0.5 * filter->speed_adjustment;
-
+	factor *= accel_filter->speed_factor;
 	return factor * TP_MAGIC_SLOWDOWN;
 }
 
@@ -306,9 +328,7 @@ create_pointer_accelerator_filter_touchpad(int dpi,
 
 	trackers_init(&filter->trackers);
 
-	filter->threshold = TOUCHPAD_DEFAULT_THRESHOLD;
-	filter->accel = TOUCHPAD_ACCELERATION;
-	filter->incline = TOUCHPAD_INCLINE;
+	filter->threshold = 130;
 	filter->dpi = dpi;
 
 	filter->base.interface = &accelerator_interface_touchpad;
-- 
2.14.3



More information about the wayland-devel mailing list