[synaptics,v2] Don't count fingers twice when guessing distance (#48316)

Submitted by Peter Hutterer on April 12, 2012, 1:16 a.m.

Details

Message ID 20120412011601.GA5664@yabbi.bne.redhat.com
State Accepted
Commit f68ddd9be4202333a1c3ccf536966a96dc0bfde7
Headers show

Not browsing as part of any series.

Commit Message

Peter Hutterer April 12, 2012, 1:16 a.m.
A finger may be closer than the required distance to more than one finger.
e.g. for fingers A, B, C, AB, AC and BC may trigger the check and count
C twice -resulting in a 4 finger click.

Avoid double-counting by marking those fingers already close enough to a
previous finger to avoid overcounting.

X.Org Bug 48316 <http://bugs.freedesktop.org/show_bug.cgi?id=48316>

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
---
Changes to v1:
- new algorithm. for each pair closer than the distance, mark both points.
  then count the number of points marked.

 src/synaptics.c |   15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/synaptics.c b/src/synaptics.c
index 918dc6f..3681b41 100644
--- a/src/synaptics.c
+++ b/src/synaptics.c
@@ -2624,7 +2624,10 @@  clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
 {
     int nfingers = 0;
 #if HAVE_MULTITOUCH
+    char close_point[SYNAPTICS_MAX_TOUCHES] = {0}; /* 1 for each point close
+                                                      to another one */
     int i, j;
+
     for (i = 0; i < hw->num_mt_mask - 1; i++) {
         ValuatorMask *f1;
 
@@ -2655,14 +2658,18 @@  clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
              * you'll need to find a touchpad that doesn't lie about it's
              * size. Good luck. */
             if (abs(x1 - x2) < (priv->maxx - priv->minx) * .3 &&
-                abs(y1 - y2) < (priv->maxy - priv->miny) * .3)
-                nfingers++;
+                abs(y1 - y2) < (priv->maxy - priv->miny) * .3) {
+                close_point[j] = 1;
+                close_point[i] = 1;
+            }
         }
     }
+
+    for (i = 0; i < SYNAPTICS_MAX_TOUCHES; i++)
+        nfingers += close_point[i];
 #endif
 
-    /* 1 doesn't make sense */
-    return nfingers ? nfingers + 1 : 0;
+    return nfingers;
 }
 
 

Comments

On 04/11/2012 06:16 PM, Peter Hutterer wrote:
> A finger may be closer than the required distance to more than one finger.
> e.g. for fingers A, B, C, AB, AC and BC may trigger the check and count
> C twice -resulting in a 4 finger click.
> 
> Avoid double-counting by marking those fingers already close enough to a
> previous finger to avoid overcounting.
> 
> X.Org Bug 48316 <http://bugs.freedesktop.org/show_bug.cgi?id=48316>
> 
> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
> ---
> Changes to v1:
> - new algorithm. for each pair closer than the distance, mark both points.
>   then count the number of points marked.
> 
>  src/synaptics.c |   15 +++++++++++----
>  1 file changed, 11 insertions(+), 4 deletions(-)
> 
> diff --git a/src/synaptics.c b/src/synaptics.c
> index 918dc6f..3681b41 100644
> --- a/src/synaptics.c
> +++ b/src/synaptics.c
> @@ -2624,7 +2624,10 @@ clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
>  {
>      int nfingers = 0;
>  #if HAVE_MULTITOUCH
> +    char close_point[SYNAPTICS_MAX_TOUCHES] = {0}; /* 1 for each point close
> +                                                      to another one */
>      int i, j;
> +
>      for (i = 0; i < hw->num_mt_mask - 1; i++) {
>          ValuatorMask *f1;
>  
> @@ -2655,14 +2658,18 @@ clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
>               * you'll need to find a touchpad that doesn't lie about it's
>               * size. Good luck. */
>              if (abs(x1 - x2) < (priv->maxx - priv->minx) * .3 &&
> -                abs(y1 - y2) < (priv->maxy - priv->miny) * .3)
> -                nfingers++;
> +                abs(y1 - y2) < (priv->maxy - priv->miny) * .3) {
> +                close_point[j] = 1;
> +                close_point[i] = 1;
> +            }
>          }
>      }
> +
> +    for (i = 0; i < SYNAPTICS_MAX_TOUCHES; i++)
> +        nfingers += close_point[i];
>  #endif
>  
> -    /* 1 doesn't make sense */
> -    return nfingers ? nfingers + 1 : 0;
> +    return nfingers;
>  }

I think this will do! It even fixes up that poor looking return
statement :).

Reviewed-by: Chase Douglas <chase.douglas@canonical.com>