I've had this running on my laptop pretty much since you sent out the patch and given that I was at a conference and on holidays after, I pretty much exclusively used the touchpad for more than two weeks.
My first impression was - it's slow. Much slower than the current method and while I played around with xset initially to make it faster, I eventually stopped doing that, frequent reboots make it cumbersome. There's some additional knobs I guess that I can use, but I haven't tried tweaking them yet. That aside, I like it a lot. I have a lot more control over the pointer, don't overshoot anymore and generally the pointer now feels it's doing what it should. I didn't realize how much I got used to it until a recent Fedora update changed my test setup and went back to the old accel. On Sat, Jan 16, 2010 at 06:40:59PM +0100, Simon Thum wrote: > this patch fixes the long-standing issue of synaptics being accelerated > twice, once by itself and once by the dix, based on different settings. > This typically makes synaptics feel awkward, since one needs a careful > setup to avoid the issue. > > This patch fixes that by taking most of acceleration out of the driver, > utilizing the accel framework in dix. It should behave quite the same, > except that the double-accel is now missing, so you may need to adapt to > that. > > Unfortunately, I don't have matching a HW+SW to test at the moment. A > previous version of that patch did work though. So I ask for volunteers, > and the maintainers to pick it up when feedback is positive. > > Prerequisites: > X.Org Server 1.7.0+ or git master > xf86-input-synaptics from git (1.2.0 may be fine too) plus patch > > > What to look out for: > > If you are fine with your synaptics, and it stays like that after issuing > > xset m 1 1 > > (or selecting the none (-1) accel profile using xinput, for that matter) > then this patch should not change much for you, because your setup is > already good. A small change in behaviour is acceptable, and should be > for the better. In particular, pressure-sensitive acceleration should > remain working, but AFAIK that feature isn't on by default. > > If the xset m ... changed synaptics behaviour, then the patch should > change it likewise. You can readjust as usual. In the end, it should > behave a bit more predictable. > > Anyone who feels qualified, please test it and give feedback! > > From 0c30a80cb0e32b89a93c2497ebd7ef97652cf211 Mon Sep 17 00:00:00 2001 > From: Simon Thum <[email protected]> > Date: Wed, 9 Sep 2009 14:41:08 +0200 > Subject: [PATCH] Setup pointer acceleration for synaptics > > Setup dix pointer accel from the synaptics driver so synaptics devices > behave like before while benefiting from dix velocity approximation. > > This fixes the longstanding issue with synaptics being > accelerated twice with different algorithms. The pressure-dependent > synaptics acceleration is now performed in a device-specific profile. > > Signed-off-by: Simon Thum <[email protected]> > --- > src/synaptics.c | 123 > +++++++++++++++++++++++++++++++++++++++---------------- > 1 files changed, 88 insertions(+), 35 deletions(-) > > diff --git a/src/synaptics.c b/src/synaptics.c > index 0fdc496..93f716d 100644 > --- a/src/synaptics.c > +++ b/src/synaptics.c > @@ -80,6 +80,7 @@ > #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 > #include <X11/Xatom.h> > #include <xserver-properties.h> > +#include <ptrveloc.h> > #endif > > typedef enum { > @@ -543,6 +544,45 @@ static void set_default_parameters(LocalDevicePtr local) > } > } > > +static float SynapticsAccelerationProfile > + (DeviceIntPtr dev, > + DeviceVelocityPtr vel, > + float velocity, > + float thr, > + float acc) { This is not the coding style used in most of the driver, should be static float foobar(param 1, param 2) { > + LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; > + SynapticsPrivate *priv = (SynapticsPrivate *) (local->private); > + SynapticsParameters* para = &priv->synpara; > + > + double accelfct; > + > + /* speed up linear with finger velocity */ > + accelfct = velocity * para->accl; > + > + /* clip acceleration factor */ > + if (accelfct > para->max_speed) > + accelfct = para->max_speed; > + else if (accelfct < para->min_speed) > + accelfct = para->min_speed; > + > + /* modify speed according to pressure */ > + if (priv->moving_state == MS_TOUCHPAD_RELATIVE) { > + int minZ = para->press_motion_min_z; > + int maxZ = para->press_motion_max_z; > + double minFctr = para->press_motion_min_factor; > + double maxFctr = para->press_motion_max_factor; > + if (priv->hwState.z <= minZ) { > + accelfct *= minFctr; > + } else if (priv->hwState.z >= maxZ) { > + accelfct *= maxFctr; > + } else { > + accelfct *= minFctr + (priv->hwState.z - minZ) * (maxFctr - > minFctr) / (maxZ - minZ); > + } > + } > + > + return accelfct; > +} > + > /* > * called by the module loader for initialization > */ > @@ -852,12 +892,15 @@ DeviceInit(DeviceIntPtr dev) > { > LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate; > SynapticsPrivate *priv = (SynapticsPrivate *) (local->private); > + Atom float_type, prop; > + float tmpf; > unsigned char map[SYN_MAX_BUTTONS + 1]; > int i; > int min, max; > #if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 > Atom btn_labels[SYN_MAX_BUTTONS] = { 0 }; > Atom axes_labels[2] = { 0 }; > + DeviceVelocityPtr pVel; > > InitAxesLabels(axes_labels, 2); > InitButtonLabels(btn_labels, SYN_MAX_BUTTONS); > @@ -890,6 +933,46 @@ DeviceInit(DeviceIntPtr dev) > , axes_labels > #endif > ); > + > + /* > + * setup dix acceleration to match legacy synaptics settings, and > + * etablish a device-specific profile to do stuff like pressure-related > + * acceleration. > + */ > +#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 7 > + if (NULL != (pVel = GetDevicePredictableAccelData(dev))) { > + SetDeviceSpecificAccelerationProfile(pVel, > SynapticsAccelerationProfile); > + > + /* float property type */ > + float_type = XIGetKnownProperty(XATOM_FLOAT); > + > + /* translate MinAcc to constant deceleration. > + * May be overridden in xf86IVD */ please write out which function call that is, even I had to think twice here > + tmpf = 1.0 / priv->synpara.min_speed; > + > + xf86Msg(X_CONFIG, "%s: (accel) MinSpeed is now constant deceleration > %.1f\n", > + dev->name, tmpf); > + prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); > + XIChangeDeviceProperty(dev, prop, float_type, 32, > + PropModeReplace, 1, &tmpf, FALSE); > + > + /* adjust accordingly */ > + priv->synpara.max_speed /= priv->synpara.min_speed; > + /* leave priv->synpara.accl alone since velocity includes const decel */ > + priv->synpara.min_speed = 1.0; > + > + xf86Msg(X_CONFIG, "%s: MaxSpeed is now %.1f\n", > + dev->name, priv->synpara.max_speed); > + xf86Msg(X_CONFIG, "%s: AccelFactor is now %.1f\n", > + dev->name, priv->synpara.accl); > + > + prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); > + i = AccelProfileDeviceSpecific; > + XIChangeDeviceProperty(dev, prop, XA_INTEGER, 32, > + PropModeReplace, 1, &i, FALSE); > + } > +#endif > + > /* X valuator */ > if (priv->minx < priv->maxx) > { > @@ -941,11 +1024,6 @@ DeviceInit(DeviceIntPtr dev) > return Success; > } > > -static int > -move_distance(int dx, int dy) > -{ > - return sqrt(SQR(dx) + SQR(dy)); > -} > > /* > * Convert from absolute X/Y coordinates to a coordinate system where > @@ -1585,9 +1663,8 @@ ComputeDeltas(SynapticsPrivate *priv, struct > SynapticsHwState *hw, > { > SynapticsParameters *para = &priv->synpara; > enum MovingState moving_state; > - int dist; > double dx, dy; > - double speed, integral; > + double integral; > int delay = 1000000000; > > dx = dy = 0; > @@ -1667,36 +1744,12 @@ ComputeDeltas(SynapticsPrivate *priv, struct > SynapticsHwState *hw, > } > } > > - /* speed depending on distance/packet */ > - dist = move_distance(dx, dy); > - speed = dist * para->accl; > - if (speed > para->max_speed) { /* set max speed factor */ > - speed = para->max_speed; > - } else if (speed < para->min_speed) { /* set min speed factor */ > - speed = para->min_speed; > - } > - > - /* modify speed according to pressure */ > - if (priv->moving_state == MS_TOUCHPAD_RELATIVE) { > - int minZ = para->press_motion_min_z; > - int maxZ = para->press_motion_max_z; > - double minFctr = para->press_motion_min_factor; > - double maxFctr = para->press_motion_max_factor; > - > - if (hw->z <= minZ) { > - speed *= minFctr; > - } else if (hw->z >= maxZ) { > - speed *= maxFctr; > - } else { > - speed *= minFctr + (hw->z - minZ) * (maxFctr - minFctr) / > (maxZ - minZ); > - } > - } > - > - /* save the fraction, report the integer part */ > - tmpf = dx * speed + x_edge_speed * dtime + priv->frac_x; > + /* report edge speed as synthetic motion. Of course, it would be > + * cooler to report floats than to buffer, but anyway. */ > + tmpf = dx + x_edge_speed * dtime + priv->frac_x; > priv->frac_x = modf(tmpf, &integral); > dx = integral; > - tmpf = dy * speed + y_edge_speed * dtime + priv->frac_y; > + tmpf = dy + y_edge_speed * dtime + priv->frac_y; > priv->frac_y = modf(tmpf, &integral); > dy = integral; > } > -- > 1.6.4.4 aside from that, looks good to me and I'd be happy to put that one in. We'll see if we get positive feedback. Cheers, Peter _______________________________________________ xorg mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/xorg
