summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--include/synaptics-properties.h2
-rw-r--r--man/synaptics.man11
-rw-r--r--src/properties.c13
-rw-r--r--src/synaptics.c45
-rw-r--r--src/synapticsstr.h2
-rw-r--r--tools/synclient.c6
7 files changed, 55 insertions, 26 deletions
diff --git a/configure.ac b/configure.ac
index 078335f..cf3bf21 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@
# Initialize Autoconf
AC_PREREQ([2.60])
AC_INIT([xf86-input-synaptics],
- [1.2.99.1],
+ [1.3.0],
[https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
[xf86-input-synaptics])
AC_CONFIG_SRCDIR([Makefile.am])
diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
index cf330d8..9c6a2ee 100644
--- a/include/synaptics-properties.h
+++ b/include/synaptics-properties.h
@@ -130,7 +130,7 @@
/* 32 bit, 2 values, width, z */
#define SYNAPTICS_PROP_PALM_DIMENSIONS "Synaptics Palm Dimensions"
-/* FLOAT */
+/* FLOAT, 2 values, speed, friction */
#define SYNAPTICS_PROP_COASTING_SPEED "Synaptics Coasting Speed"
/* 32 bit, 2 values, min, max */
diff --git a/man/synaptics.man b/man/synaptics.man
index 590a380..3f1ca9d 100644
--- a/man/synaptics.man
+++ b/man/synaptics.man
@@ -397,10 +397,17 @@ Minimum finger pressure at which touch is considered a palm. Property:
"Synaptics Palm Dimensions"
.TP
.BI "Option \*qCoastingSpeed\*q \*q" float \*q
-Coasting threshold scrolling speed.
+Your finger needs to produce this many scrolls per second in order to start
+coasting. The default is 20 which should prevent you from starting coasting
+unintentionally.
.
0 disables coasting. Property: "Synaptics Coasting Speed"
.TP
+.BI "Option \*qCoastingFriction\*q \*q" float \*q
+Number of scrolls/secondĀ² to decrease the coasting speed. Default
+is 50.
+Property: "Synaptics Coasting Speed"
+.TP
.BI "Option \*qSingleTapTimeout\*q \*q" integer \*q
Timeout after a tap to recognize it as a single tap. Property: "Synaptics Tap
Durations"
@@ -853,7 +860,7 @@ right, right + bottom, bottom, bottom + left, left, left + top.
.TP 7
.BI "Synaptics Coasting Speed"
-FLOAT.
+FLOAT, 2 values, speed, friction.
.TP 7
.BI "Synaptics Pressure Motion"
diff --git a/src/properties.c b/src/properties.c
index 9e850d6..5400928 100644
--- a/src/properties.c
+++ b/src/properties.c
@@ -243,7 +243,8 @@ InitDeviceProperties(InputInfoPtr pInfo)
prop_palm_dim = InitAtom(pInfo->dev, SYNAPTICS_PROP_PALM_DIMENSIONS, 32, 2, values);
fvalues[0] = para->coasting_speed;
- prop_coastspeed = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_COASTING_SPEED, 1, fvalues);
+ fvalues[1] = para->coasting_friction;
+ prop_coastspeed = InitFloatAtom(pInfo->dev, SYNAPTICS_PROP_COASTING_SPEED, 2, fvalues);
values[0] = para->press_motion_min_z;
values[1] = para->press_motion_max_z;
@@ -600,14 +601,14 @@ SetProperty(DeviceIntPtr dev, Atom property, XIPropertyValuePtr prop,
para->palm_min_z = dim[1];
} else if (property == prop_coastspeed)
{
- float speed;
+ float *coast_speeds;
- if (prop->size != 1 || prop->format != 32 || prop->type != float_type)
+ if (prop->size != 2 || prop->format != 32 || prop->type != float_type)
return BadMatch;
- speed = *(float*)prop->data;
- para->coasting_speed = speed;
-
+ coast_speeds = (float*)prop->data;
+ para->coasting_speed = coast_speeds[0];
+ para->coasting_friction = coast_speeds[1];
} else if (property == prop_pressuremotion)
{
float *press;
diff --git a/src/synaptics.c b/src/synaptics.c
index 3030a98..eae48d2 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -465,7 +465,7 @@ static void set_default_parameters(InputInfoPtr pInfo)
tapMove = diag * .044;
edgeMotionMinSpeed = 1;
edgeMotionMaxSpeed = diag * .080;
- accelFactor = 50.0 / diag;
+ accelFactor = 200.0 / diag; /* trial-and-error */
range = priv->maxp - priv->minp;
@@ -585,7 +585,8 @@ static void set_default_parameters(InputInfoPtr pInfo)
pars->accl = xf86SetRealOption(opts, "AccelFactor", accelFactor);
pars->trackstick_speed = xf86SetRealOption(opts, "TrackstickSpeed", 40);
pars->scroll_dist_circ = xf86SetRealOption(opts, "CircScrollDelta", 0.1);
- pars->coasting_speed = xf86SetRealOption(opts, "CoastingSpeed", 0.0);
+ pars->coasting_speed = xf86SetRealOption(opts, "CoastingSpeed", 20.0);
+ pars->coasting_friction = xf86SetRealOption(opts, "CoastingFriction", 50);
pars->press_motion_min_factor = xf86SetRealOption(opts, "PressureMotionMinFactor", 1.0);
pars->press_motion_max_factor = xf86SetRealOption(opts, "PressureMotionMaxFactor", 1.0);
pars->grab_event_device = xf86SetBoolOption(opts, "GrabEventDevice", TRUE);
@@ -1026,9 +1027,9 @@ DeviceInit(DeviceIntPtr dev)
* 100 packet/s by default. */
pVel->corr_mul = 12.5f; /*1000[ms]/80[/s] = 12.5 */
- xf86Msg(X_CONFIG, "%s: MaxSpeed is now %.1f\n",
+ xf86Msg(X_CONFIG, "%s: MaxSpeed is now %.2f\n",
dev->name, priv->synpara.max_speed);
- xf86Msg(X_CONFIG, "%s: AccelFactor is now %.1f\n",
+ xf86Msg(X_CONFIG, "%s: AccelFactor is now %.3f\n",
dev->name, priv->synpara.accl);
prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
@@ -1748,7 +1749,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
if (inside_area && moving_state && !priv->palm &&
!priv->vert_scroll_edge_on && !priv->horiz_scroll_edge_on &&
!priv->vert_scroll_twofinger_on && !priv->horiz_scroll_twofinger_on &&
- !priv->circ_scroll_on) {
+ !priv->circ_scroll_on && priv->prevFingers == hw->numFingers) {
/* FIXME: Wtf?? what's with 13? */
delay = MIN(delay, 13);
if (priv->count_packet_finger > 3) { /* min. 3 packets */
@@ -1818,6 +1819,7 @@ ComputeDeltas(SynapticsPrivate *priv, const struct SynapticsHwState *hw,
} else { /* reset packet counter */
priv->count_packet_finger = 0;
}
+ priv->prevFingers = hw->numFingers;
*dxP = dx;
*dyP = dy;
@@ -1840,20 +1842,21 @@ start_coasting(SynapticsPrivate *priv, struct SynapticsHwState *hw, edge_type ed
if ((priv->scroll_packet_count > 3) && (para->coasting_speed > 0.0)) {
double pkt_time = (HIST(0).millis - HIST(3).millis) / 1000.0;
- if (vertical) {
+ if (para->scroll_twofinger_vert || 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;
priv->autoscroll_y = (hw->y - priv->scroll_y) / (double)sdelta;
}
}
- } else {
+ }
+ if (para->scroll_twofinger_horiz || !vertical){
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;
@@ -1949,8 +1952,10 @@ 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, "cicular scroll off\n");
@@ -1991,7 +1996,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);
}
}
@@ -2098,6 +2104,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) {
@@ -2108,9 +2115,17 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
sd->up++;
priv->autoscroll_y += 1.0;
}
+ if (abs(priv->autoscroll_yspd) < ddy) {
+ priv->autoscroll_yspd = 0;
+ priv->scroll_packet_count = 0;
+ } 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) {
@@ -2121,6 +2136,12 @@ HandleScrolling(SynapticsPrivate *priv, struct SynapticsHwState *hw,
sd->left++;
priv->autoscroll_x += 1.0;
}
+ if (abs(priv->autoscroll_xspd) < ddx) {
+ priv->autoscroll_xspd = 0;
+ priv->scroll_packet_count = 0;
+ } else {
+ priv->autoscroll_xspd += (priv->autoscroll_xspd < 0 ? ddx : -1*ddx);
+ }
}
return delay;
diff --git a/src/synapticsstr.h b/src/synapticsstr.h
index a8a7e3d..9dc0a19 100644
--- a/src/synapticsstr.h
+++ b/src/synapticsstr.h
@@ -150,6 +150,7 @@ typedef struct _SynapticsParameters
int palm_min_width; /* Palm detection width */
int palm_min_z; /* Palm detection depth */
double coasting_speed; /* Coasting threshold scrolling speed */
+ double coasting_friction; /* Number of scrolls per second per second to change coasting speed */
int press_motion_min_z; /* finger pressure at which minimum pressure motion factor is applied */
int press_motion_max_z; /* finger pressure at which maximum pressure motion factor is applied */
double press_motion_min_factor; /* factor applied on speed when finger pressure is at minimum */
@@ -218,6 +219,7 @@ typedef struct _SynapticsPrivateRec
int palm; /* Set to true when palm detected, reset to false when
palm/finger contact disappears */
int prev_z; /* previous z value, for palm detection */
+ int prevFingers; /* previous numFingers, for transition detection */
int avg_width; /* weighted average of previous fingerWidth values */
double horiz_coeff; /* normalization factor for x coordintes */
double vert_coeff; /* normalization factor for y coordintes */
diff --git a/tools/synclient.c b/tools/synclient.c
index bd57faa..e7be499 100644
--- a/tools/synclient.c
+++ b/tools/synclient.c
@@ -132,6 +132,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, 255, SYNAPTICS_PROP_COASTING_SPEED, 0 /* float*/, 1},
{"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},
@@ -496,11 +497,8 @@ dp_show_settings(Display *dpy, XDevice *dev)
for (j = 0; params[j].name; j++) {
struct Parameter *par = &params[j];
a = XInternAtom(dpy, par->prop_name, True);
- if (!a) {
- fprintf(stderr, " %-23s = missing\n",
- par->name);
+ if (!a)
continue;
- }
len = 1 + ((par->prop_offset * (par->prop_format ? par->prop_format : 32)/8))/4;