[PATCH synaptics] support inverted scroll direction

Peter Hutterer peter.hutterer at who-t.net
Thu Apr 12 20:50:04 PDT 2012


On Wed, Apr 11, 2012 at 10:00:56PM -0400, Alyssa Hung wrote:
> This patch adds two options to the synaptics driver: InvertEdgeScroll
> and InvertTwoFingerScroll.
> 
> When enabled, they will cause the scroll direction to be inverted when
> edge scrolling and two-finger scrolling, respectively. For instance,
> moving a finger downward along the right edge will pull the scrolled
> content down (causing the page to scroll up). This behaviour is
> consistent with scrolling on modern touchscreen devices.
> 
> Options are provided separately for edge scrolling and two-finger
> scrolling because they follow different metaphors; edge scrolling has
> traditionally been analogous to dragging the scrollbar tab, and may
> therefore be sensible to leave uninverted even when two-finger scroll
> direction is inverted.
> 
> Signed-off-by: Alyssa Hung <ahung at isisview.org>

Thansk Alyssa, two comments regarding this option:
In general, I'm not in favour of adding more options to synaptics. This
particular one is something that we need to deal with in other drivers as
well. With server 1.12, scrolling is now controlled by the increment in the
XIScrollClass, simply changing that could change not only the speed but
also the direction. While support for modifying the increment is the best
solution, it needs a protocol revision.

In this particular case, synaptics already has a
VertScrollDelta and HorizScrollDelta option that controls the amount of
movement before a scroll event is emitted. I think it should be simple
enough to change the code that negative deltas are permitted for scroll
direction inversion.

Cheers,
  Peter

> ---
>  include/synaptics-properties.h |    3 +++
>  man/synaptics.man              |   10 ++++++++++
>  src/properties.c               |   14 ++++++++++++++
>  src/synaptics.c                |   18 ++++++++++++++++--
>  src/synapticsstr.h             |    2 ++
>  tools/synclient.c              |    2 ++
>  6 files changed, 47 insertions(+), 2 deletions(-)
> 
> diff --git a/include/synaptics-properties.h b/include/synaptics-properties.h
> index 8c20a0c..558fc38 100644
> --- a/include/synaptics-properties.h
> +++ b/include/synaptics-properties.h
> @@ -72,6 +72,9 @@
>  /* 8 bit (BOOL), 2 values, vertical, horizontal */
>  #define SYNAPTICS_PROP_SCROLL_TWOFINGER "Synaptics Two-Finger Scrolling"
> 
> +/* 8 bit (BOOL), 2 values, edge, two-finger */
> +#define SYNAPTICS_PROP_SCROLL_INVERT "Synaptics Inverted Scrolling"
> +
>  /* FLOAT, 4 values, min, max, accel, trackstick */
>  #define SYNAPTICS_PROP_SPEED "Synaptics Move Speed"
> 
> diff --git a/man/synaptics.man b/man/synaptics.man
> index 864a95f..1947bf9 100644
> --- a/man/synaptics.man
> +++ b/man/synaptics.man
> @@ -161,6 +161,11 @@ Enable vertical scrolling when dragging along the
> right edge. Property:
>  Enable horizontal scrolling when dragging along the bottom edge. Property:
>  "Synaptics Edge Scrolling"
>  .TP 7
> +.BI "Option \*qInvertEdgeScroll\*q \*q" boolean \*q
> +Invert scroll direction when scrolling by dragging along the right or bottom
> +edge. When enabled, the content being scrolled will follow the direction of
> +finger movement. Property: "Synaptics Inverted Scrolling"
> +.TP 7
>  .BI "Option \*qCornerCoasting\*q \*q" boolean \*q
>  Enable edge scrolling to continue while the finger stays in an edge corner.
>  Property: "Synaptics Edge Scrolling"
> @@ -173,6 +178,11 @@ the touchpad. Property: "Synaptics Two-Finger Scrolling"
>  Enable horizontal scrolling when dragging with two fingers anywhere on
>  the touchpad. Property: "Synaptics Two-Finger Scrolling"
>  .TP 7
> +.BI "Option \*qInvertTwoFingerScroll\*q \*q" boolean \*q
> +Invert scroll direction when scrolling by dragging two fingers. When enabled,
> +the content being scrolled will follow the direction of finger movement.
> +Property: "Synaptics Inverted Scrolling"
> +.TP 7
>  .BI "Option \*qVertScrollDelta\*q \*q" integer \*q
>  Move distance of the finger for a scroll event. Property: "Synaptics Scrolling
>  Distance"
> diff --git a/src/properties.c b/src/properties.c
> index 783b516..3fc1d2c 100644
> --- a/src/properties.c
> +++ b/src/properties.c
> @@ -66,6 +66,7 @@ Atom prop_twofinger_width       = 0;
>  Atom prop_scrolldist            = 0;
>  Atom prop_scrolledge            = 0;
>  Atom prop_scrolltwofinger       = 0;
> +Atom prop_scrollinvert          = 0;
>  Atom prop_speed                 = 0;
>  Atom prop_edgemotion_pressure   = 0;
>  Atom prop_edgemotion_speed      = 0;
> @@ -230,6 +231,9 @@ InitDeviceProperties(InputInfoPtr pInfo)
>      values[0] = para->scroll_twofinger_vert;
>      values[1] = para->scroll_twofinger_horiz;
>      prop_scrolltwofinger = InitAtom(pInfo->dev,
> SYNAPTICS_PROP_SCROLL_TWOFINGER,8, 2, values);
> +    values[0] = para->scroll_edge_invert;
> +    values[1] = para->scroll_twofinger_invert;
> +    prop_scrollinvert = InitAtom(pInfo->dev,
> SYNAPTICS_PROP_SCROLL_INVERT, 8, 2, values);
> 
>      fvalues[0] = para->min_speed;
>      fvalues[1] = para->max_speed;
> @@ -501,6 +505,16 @@ SetProperty(DeviceIntPtr dev, Atom property,
> XIPropertyValuePtr prop,
>          twofinger = (BOOL*)prop->data;
>          para->scroll_twofinger_vert  = twofinger[0];
>          para->scroll_twofinger_horiz = twofinger[1];
> +    } else if (property == prop_scrollinvert)
> +    {
> +	CARD8 *invert;
> +
> +	if (prop->size != 2 || prop->format != 8 || prop->type != XA_INTEGER)
> +		return BadMatch;
> +
> +	invert = (BOOL*)prop->data;
> +	para->scroll_edge_invert      = invert[0];
> +	para->scroll_twofinger_invert = invert[1];
>      } else if (property == prop_speed)
>      {
>          float *speed;
> diff --git a/src/synaptics.c b/src/synaptics.c
> index f07fd13..d0dacb1 100644
> --- a/src/synaptics.c
> +++ b/src/synaptics.c
> @@ -716,6 +716,8 @@ static void set_default_parameters(InputInfoPtr pInfo)
>      pars->scroll_edge_corner = xf86SetBoolOption(opts,
> "CornerCoasting", FALSE);
>      pars->scroll_twofinger_vert = xf86SetBoolOption(opts,
> "VertTwoFingerScroll", vertTwoFingerScroll);
>      pars->scroll_twofinger_horiz = xf86SetBoolOption(opts,
> "HorizTwoFingerScroll", horizTwoFingerScroll);
> +    pars->scroll_edge_invert = xf86SetBoolOption(opts,
> "InvertEdgeScroll", FALSE);
> +    pars->scroll_twofinger_invert = xf86SetBoolOption(opts,
> "InvertTwoFingerScroll", FALSE);
>      pars->edge_motion_min_z = xf86SetIntOption(opts,
> "EdgeMotionMinZ", edgeMotionMinZ);
>      pars->edge_motion_max_z = xf86SetIntOption(opts,
> "EdgeMotionMaxZ", edgeMotionMaxZ);
>      pars->edge_motion_min_speed = xf86SetIntOption(opts,
> "EdgeMotionMinSpeed", edgeMotionMinSpeed);
> @@ -2560,14 +2562,26 @@ HandleScrolling(SynapticsPrivate *priv, struct
> SynapticsHwState *hw,
>      if (priv->vert_scroll_edge_on || priv->vert_scroll_twofinger_on) {
>  	/* + = down, - = up */
>  	if (para->scroll_dist_vert > 0 && hw->y != priv->scroll.last_y) {
> -	    priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
> +	    if ((priv->vert_scroll_edge_on && para->scroll_edge_invert) ||
> +		(priv->vert_scroll_twofinger_on && para->scroll_twofinger_invert)) {
> +		priv->scroll.delta_y -= (hw->y - priv->scroll.last_y);
> +	    }
> +	    else {
> +		priv->scroll.delta_y += (hw->y - priv->scroll.last_y);
> +	    }
>  	    priv->scroll.last_y = hw->y;
>  	}
>      }
>      if (priv->horiz_scroll_edge_on || priv->horiz_scroll_twofinger_on) {
>  	/* + = right, - = left */
>  	if (para->scroll_dist_horiz > 0 && hw->x != priv->scroll.last_x) {
> -	    priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
> +	    if ((priv->horiz_scroll_edge_on && para->scroll_edge_invert) ||
> +		(priv->horiz_scroll_twofinger_on && para->scroll_twofinger_invert)) {
> +		priv->scroll.delta_x -= (hw->x - priv->scroll.last_x);
> +	    }
> +	    else {
> +		priv->scroll.delta_x += (hw->x - priv->scroll.last_x);
> +	    }
>  	    priv->scroll.last_x = hw->x;
>  	}
>      }
> diff --git a/src/synapticsstr.h b/src/synapticsstr.h
> index 55aab3d..500cb1f 100644
> --- a/src/synapticsstr.h
> +++ b/src/synapticsstr.h
> @@ -140,6 +140,8 @@ typedef struct _SynapticsParameters
>      Bool scroll_edge_corner;		    /* Enable/disable continuous edge
> scrolling when in the corner */
>      Bool scroll_twofinger_vert;		    /* Enable/disable vertical
> two-finger scrolling */
>      Bool scroll_twofinger_horiz;	    /* Enable/disable horizontal
> two-finger scrolling */
> +    Bool scroll_edge_invert;		    /* Enable/disable invert scroll
> direction when edge scrolling */
> +    Bool scroll_twofinger_invert;	    /* Enable/disable invert scroll
> direction when two-finger scrolling */
>      double min_speed, max_speed, accl;	    /* movement parameters */
>      double trackstick_speed;		    /* trackstick mode speed */
>      int edge_motion_min_z;		    /* finger pressure at which minimum
> edge motion speed is set */
> diff --git a/tools/synclient.c b/tools/synclient.c
> index 942312a..eea3f80 100644
> --- a/tools/synclient.c
> +++ b/tools/synclient.c
> @@ -94,9 +94,11 @@ static struct Parameter params[] = {
>      {"HorizScrollDelta",      PT_INT,    0, 1000,
> SYNAPTICS_PROP_SCROLL_DISTANCE,	32,	1},
>      {"VertEdgeScroll",        PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_EDGE,	8,	0},
>      {"HorizEdgeScroll",       PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_EDGE,	8,	1},
> +    {"InvertEdgeScroll",      PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_INVERT,	8,	0},
>      {"CornerCoasting",        PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_EDGE,	8,	2},
>      {"VertTwoFingerScroll",   PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_TWOFINGER,	8,	0},
>      {"HorizTwoFingerScroll",  PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_TWOFINGER,	8,	1},
> +    {"InvertTwoFingerScroll", PT_BOOL,   0, 1,
> SYNAPTICS_PROP_SCROLL_INVERT,	8,	1},
>      {"MinSpeed",              PT_DOUBLE, 0, 255.0,
> SYNAPTICS_PROP_SPEED,	0, /*float */	0},
>      {"MaxSpeed",              PT_DOUBLE, 0, 255.0,
> SYNAPTICS_PROP_SPEED,	0, /*float */	1},
>      {"AccelFactor",           PT_DOUBLE, 0, 1.0,
> SYNAPTICS_PROP_SPEED,	0, /*float */	2},
> -- 
> 1.7.10
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
> 


More information about the xorg-devel mailing list