[PATCH input-synaptics] Added "friction physics" so coasting can stop on its own.

Patrick Curran pjcurran at wisc.edu
Fri Jul 9 06:44:02 PDT 2010


When you are coasting (but not corner coasting) you might want the
scrolling to slow down and stop on its own.  This also lets you
start coasting while using a two finger scroll (starting with two
fingers only works for vertical and I can't figure out why it
doesn't work for horizontal).  I couldn't figure out how to edit
the man pages so I didn't include anything there.  The diff is
against the  xf86-input-synaptics-1.2.2 tarball.

Signed-off-by: Patrick Curran <pjcurran at wisc.edu>
---
 INSTALL                        |    1 +
 include/synaptics-properties.h |    3 +++
 src/properties.c               |    3 +++
 src/synaptics.c                |   28 +++++++++++++++++++++++-----
 src/synapticsstr.h             |    1 +
 tools/synclient.c              |    1 +
 6 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/INSTALL b/INSTALL
index 47d2913..2a0da9b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -48,6 +48,7 @@ Section "InputDevice"
   Option	"MinSpeed"		"0.09"
   Option	"MaxSpeed"		"0.18"
   Option	"AccelFactor"		"0.0015"
+  Option	"CoastingFriction"		"45"
 EndSection
 
 Change the Identifier to the same name as in the ServerLayout section.
diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index cf330d8..28c4905 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -133,6 +133,9 @@
 /* FLOAT */
 #define SYNAPTICS_PROP_COASTING_SPEED "Synaptics Coasting Speed"
 
+/* FLOAT */
+#define SYNAPTICS_PROP_COASTING_FRICTION "Synaptics Coasting Friction"
+
 /* 32 bit, 2 values, min, max */
 #define SYNAPTICS_PROP_PRESSURE_MOTION "Synaptics Pressure Motion"
 
diff --git a/src/properties.c b/src/properties.c
index 4366034..638a057 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -244,6 +244,9 @@ InitDeviceProperties(LocalDevicePtr local)
     fvalues[0] = para->coasting_speed;
     prop_coastspeed = InitFloatAtom(local->dev, SYNAPTICS_PROP_COASTING_SPEED, 1, fvalues);
 
+    fvalues[0] = para->coasting_friction;
+    prop_coastspeed = InitFloatAtom(local->dev, SYNAPTICS_PROP_COASTING_FRICTION, 1, fvalues);
+
     values[0] = para->press_motion_min_z;
     values[1] = para->press_motion_max_z;
     prop_pressuremotion = InitAtom(local->dev, SYNAPTICS_PROP_PRESSURE_MOTION, 32, 2, values);
diff --git a/src/synaptics.c b/src/synaptics.c
index 9997674..a43d3be 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -536,6 +536,7 @@ static void set_default_parameters(LocalDevicePtr local)
     pars->tap_and_drag_gesture = xf86SetBoolOption(opts, "TapAndDragGesture", TRUE);
     pars->resolution_horiz = xf86SetIntOption(opts, "HorizResolution", horizResolution);
     pars->resolution_vert = xf86SetIntOption(opts, "VertResolution", vertResolution);
+    pars->coasting_friction = xf86SetRealOption(opts, "CoastingFriction", 0);
 
     /* Warn about (and fix) incorrectly configured TopEdge/BottomEdge parameters */
     if (pars->top_edge > pars->bottom_edge) {
@@ -1753,7 +1754,7 @@ start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type ed
 	if (vertical) {
 	    double dy = estimate_delta(HIST(0).y, HIST(1).y, HIST(2).y, HIST(3).y);
 	    int sdelta = para->scroll_dist_vert;
-	    if ((edge & RIGHT_EDGE) && pkt_time > 0 && sdelta > 0) {
+        if (para->scroll_twofinger_vert || (edge & RIGHT_EDGE) && pkt_time > 0 && sdelta > 0) {
 		double scrolls_per_sec = dy / pkt_time / sdelta;
 		if (fabs(scrolls_per_sec) >= para->coasting_speed) {
 		    priv->autoscroll_yspd = scrolls_per_sec;
@@ -1763,7 +1764,7 @@ start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type ed
 	} else {
 	    double dx = estimate_delta(HIST(0).x, HIST(1).x, HIST(2).x, HIST(3).x);
 	    int sdelta = para->scroll_dist_horiz;
-	    if ((edge & BOTTOM_EDGE) && pkt_time > 0 && sdelta > 0) {
+        if (para->scroll_twofinger_horiz || (edge & BOTTOM_EDGE) && pkt_time > 0 && sdelta > 0) {
 		double scrolls_per_sec = dx / pkt_time / sdelta;
 		if (fabs(scrolls_per_sec) >= para->coasting_speed) {
 		    priv->autoscroll_xspd = scrolls_per_sec;
@@ -1859,8 +1860,11 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	}
     }
     {
-	Bool oldv = priv->vert_scroll_edge_on || (priv->circ_scroll_on && priv->circ_scroll_vert);
-	Bool oldh = priv->horiz_scroll_edge_on || (priv->circ_scroll_on && !priv->circ_scroll_vert);
+    Bool oldv = priv->vert_scroll_twofinger_on || priv->vert_scroll_edge_on || 
+                    (priv->circ_scroll_on && priv->circ_scroll_vert);
+    Bool oldh = priv->horiz_scroll_twofinger_on || priv->horiz_scroll_edge_on || 
+                    (priv->circ_scroll_on && !priv->circ_scroll_vert);
+
 	if (priv->circ_scroll_on && !finger) {
 	    /* circular scroll locks in until finger is raised */
 	    DBG(7, ErrorF("cicular scroll off\n"));
@@ -1901,7 +1905,8 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	 * and are no longer scrolling, then start coasting */
 	if ((oldv || oldh) && !para->scroll_edge_corner &&
 	    !(priv->circ_scroll_on || priv->vert_scroll_edge_on ||
-	      priv->horiz_scroll_edge_on)) {
+          priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on || 
+          priv->vert_scroll_twofinger_on)) {
 	    start_coasting(priv, hw, edge, oldv);
 	}
     }
@@ -2008,6 +2013,7 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 
     if (priv->autoscroll_yspd) {
 	double dtime = (hw->millis - HIST(0).millis) / 1000.0;
+    double ddy = para->coasting_friction * dtime;
 	priv->autoscroll_y += priv->autoscroll_yspd * dtime;
 	delay = MIN(delay, 20);
 	while (priv->autoscroll_y > 1.0) {
@@ -2018,9 +2024,16 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	    sd->up++;
 	    priv->autoscroll_y += 1.0;
 	}
+    if (abs(priv->autoscroll_yspd)<ddy) {
+        stop_coasting(priv);
+    } else {
+        priv->autoscroll_yspd += (priv->autoscroll_yspd < 0 ? ddy : -1*ddy);
+    }
     }
+
     if (priv->autoscroll_xspd) {
 	double dtime = (hw->millis - HIST(0).millis) / 1000.0;
+    double ddx = para->coasting_friction * dtime;
 	priv->autoscroll_x += priv->autoscroll_xspd * dtime;
 	delay = MIN(delay, 20);
 	while (priv->autoscroll_x > 1.0) {
@@ -2031,6 +2044,11 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
 	    sd->left++;
 	    priv->autoscroll_x += 1.0;
 	}
+    if (abs(priv->autoscroll_xspd)<ddx) {
+        stop_coasting(priv);
+    } else {
+        priv->autoscroll_xspd += (priv->autoscroll_xspd < 0 ? ddx : -1*ddx);
+    }
     }
 
     return delay;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index 2986173..2962522 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -149,6 +149,7 @@ typedef struct _SynapticsParameters
     unsigned int resolution_horiz;          /* horizontal resolution of touchpad in units/mm */
     unsigned int resolution_vert;           /* vertical resolution of touchpad in units/mm */
     int area_left_edge, area_right_edge, area_top_edge, area_bottom_edge; /* area coordinates absolute */
+    double coasting_friction;           /*add friction so coasting stops on its own*/
 } SynapticsParameters;
 
 
diff --git a/tools/synclient.c b/tools/synclient.c
index 032b129..ee15adf 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -133,6 +133,7 @@ static struct Parameter params[] = {
     {"PalmMinWidth",          PT_INT,    0, 15,    SYNAPTICS_PROP_PALM_DIMENSIONS,	32,	0},
     {"PalmMinZ",              PT_INT,    0, 255,   SYNAPTICS_PROP_PALM_DIMENSIONS,	32,	1},
     {"CoastingSpeed",         PT_DOUBLE, 0, 20,    SYNAPTICS_PROP_COASTING_SPEED,	0 /* float*/,	0},
+    {"CoastingFriction",      PT_DOUBLE, 0, 200,   SYNAPTICS_PROP_COASTING_FRICTION,	0 /* float*/,	0},
     {"PressureMotionMinZ",    PT_INT,    1, 255,   SYNAPTICS_PROP_PRESSURE_MOTION,	32,	0},
     {"PressureMotionMaxZ",    PT_INT,    1, 255,   SYNAPTICS_PROP_PRESSURE_MOTION,	32,	1},
     {"PressureMotionMinFactor", PT_DOUBLE, 0, 10.0,SYNAPTICS_PROP_PRESSURE_MOTION_FACTOR,	0 /*float*/,	0},
-- 
1.7.1.1



More information about the xorg-devel mailing list