diff options
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | include/synaptics-properties.h | 2 | ||||
-rw-r--r-- | man/synaptics.man | 11 | ||||
-rw-r--r-- | src/properties.c | 13 | ||||
-rw-r--r-- | src/synaptics.c | 45 | ||||
-rw-r--r-- | src/synapticsstr.h | 2 | ||||
-rw-r--r-- | tools/synclient.c | 6 |
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 = ¶ms[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; |