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

Chase Douglas chase.douglas at canonical.com
Tue Apr 10 22:17:48 PDT 2012


On 04/10/2012 06:14 PM, Peter Hutterer wrote:
> On Tue, Apr 10, 2012 at 05:24:26PM -0700, Chase Douglas wrote:
>> On 04/10/2012 05:03 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, AC and BC could both trigger the check and count
>>> C twice.
>>
>> The above description actually results in the correct count for three
>> touches. A better description would mention the case where AC, BC, and
>> AB are all close enough to trigger the check, in which case we have too
>> many fingers.
> 
> right, sorry, amended to:
>    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 at who-t.net>
>>> ---
>>>  src/synaptics.c |    9 ++++++++-
>>>  1 files changed, 8 insertions(+), 1 deletions(-)
>>>
>>> diff --git a/src/synaptics.c b/src/synaptics.c
>>> index 918dc6f..0e10aeb 100644
>>> --- a/src/synaptics.c
>>> +++ b/src/synaptics.c
>>> @@ -2624,7 +2624,9 @@ clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
>>>  {
>>>      int nfingers = 0;
>>>  #if HAVE_MULTITOUCH
>>> +    int skip[SYNAPTICS_MAX_TOUCHES] = {0};
>>>      int i, j;
>>> +
>>>      for (i = 0; i < hw->num_mt_mask - 1; i++) {
>>>          ValuatorMask *f1;
>>>  
>>> @@ -2642,6 +2644,9 @@ clickpad_guess_clickfingers(SynapticsPrivate *priv, struct SynapticsHwState *hw)
>>>                  hw->slot_state[j] == SLOTSTATE_CLOSE)
>>>                  continue;
>>>  
>>> +            if (skip[j])
>>> +                continue;
>>> +
>>>              f2 = hw->mt_mask[j];
>>>  
>>>              x1 = valuator_mask_get_double(f1, 0);
>>> @@ -2655,8 +2660,10 @@ 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)
>>> +                abs(y1 - y2) < (priv->maxy - priv->miny) * .3) {
>>>                  nfingers++;
>>> +                skip[j] = 1;
>>> +            }
>>>          }
>>>      }
>>>  #endif
>>
>> I think we would get the same results if we merely added a "break;"
>> after "nfingers++;". This would ensure we only increment the finger
>> count once for each outer loop iteration. In the example, we would see
>> AB, and BC, but not AC because we broke out of the inner loop after AB.
> 
> you can't guarantee that BC are close enough together when you see the first
> match though. so for the case of physical B left of A left of C, you have AB
> and AC being close but BC may not be. If you break after finding the AB
> match, you'd skip the AC and get two-finger click only.

Good point.

Wouldn't this code break in the same way if you have touches ordered as
A-C-B? We would match A-C, which would mark C for skipping. When we look
at B-C, we would skip it. We wouldn't test C-B because of how the loops
are structured.

I think we need a better algorithm. This one works almost perfect, but I
don't see a way to fix it to cover 100% of cases. Unfortunately, I'm
about to fall asleep in my chair, so I don't have any proposals right now.

-- Chase


More information about the xorg-devel mailing list