synaptics - double taps are ignored in some applications
Gabriele Mazzotta
gabriele.mzt at gmail.com
Tue Jan 13 04:28:21 PST 2015
On Tuesday 13 January 2015 15:55:44 Peter Hutterer wrote:
> On Mon, Jan 12, 2015 at 09:32:13PM +0100, Gabriele Mazzotta wrote:
> > Hi,
> >
> > I have some problems with double taps in some applications.
> > These applications, e.g. Firefox, often (if not always) ignores double
> > taps. This never happens with double clicks and it happens only with
> > the same applications.
> >
> > After some tests I found that the problem is that there's no delay
> > between the second ButtonPress and the second ButtonRelease.
> >
> > The patch here below seems to solve the problem (the delay should be
> > handled better), but I don't know if it can be considered a good
> > solution. Before I try to improve it, does anyone know a better way
> > to address this problem?
> >
> > I tried to fix the problem from HandleTapProcessing(), but I could only
> > have reliable double taps breaking tap and drag gestures.
>
> docs/tapndrag.dia has the state diagram, though I'm not 100% it's still
> accurate. Based on that I think there may be a solution: when we transition
> from 3 to 2B, we could send up + down. From 2B we have two transitions, back
> to start (Up) or back to 3 (no event needed).
> Since 2B->start is based on a timeout, that adds the required delay.
>
> Does that sound sensible?
> (of course, this could all be bogus if the diagram doesn't reflect the code
> anymore :)
I didn't notice the diagram, thanks. That made things more clear.
> > diff --git a/src/synaptics.c b/src/synaptics.c
> > index 3b11fda..8a3e5c5 100644
> > --- a/src/synaptics.c
> > +++ b/src/synaptics.c
> > @@ -1109,6 +1109,7 @@ SynapticsReset(SynapticsPrivate * priv)
> > priv->mid_emu_state = MBE_OFF;
> > priv->nextRepeat = 0;
> > priv->lastButtons = 0;
> > + priv->mustRelease = -1;
>
> fwiw, I'd expect something named "mustRelease" to be a boolean yes/no, not a
> button number. something like pressedButton or activeButton or so would be
> more obvious. also, X doesn't have a button 0, so that'd be fine to use as
> default.
Yes, this was the result of incremental changes, mustRelease was a bool
and I was just too lazy to rename it. As for the button, it was 0, but
I sent the diff with -1 because I didn't bother to check whether 0 was
safe or not, so I used something I was sure of.
> > priv->prev_z = 0;
> > priv->prevFingers = 0;
> > priv->num_active_touches = 0;
> > @@ -3245,6 +3246,12 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> > Bool using_cumulative_coords = FALSE;
> > Bool ignore_motion;
> >
> > + if (priv->mustRelease != -1) {
> > + xf86PostButtonEvent(pInfo->dev, FALSE, priv->mustRelease, FALSE, 0, 0);
> > + priv->mustRelease = -1;
> > + return 0;
> > + }
> > +
> > /* We need both and x/y, the driver can't handle just one of the two
> > * yet. But since it's possible to hit a phys button on non-clickpads
> > * without ever getting motion data first, we must continue with 0/0 for
> > @@ -3360,6 +3367,7 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> >
> > if (priv->tap_button_state == TBS_BUTTON_DOWN_UP) {
> > if (tap_mask != (priv->lastButtons & tap_mask)) {
> > + priv->mustRelease = priv->tap_button;
> > xf86PostButtonEvent(pInfo->dev, FALSE, priv->tap_button, TRUE,
> > 0, 0);
> > priv->lastButtons |= tap_mask;
> > @@ -3387,8 +3395,9 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> > while (change) {
> > id = ffs(change); /* number of first set bit 1..32 is returned */
> > change &= ~(1 << (id - 1));
> > - xf86PostButtonEvent(pInfo->dev, FALSE, id, (buttons & (1 << (id - 1))),
> > - 0, 0);
> > + if (priv->mustRelease != id)
> > + xf86PostButtonEvent(pInfo->dev, FALSE, id,
> > + (buttons & (1 << (id - 1))), 0, 0);
> > }
> >
> > if (priv->has_scrollbuttons)
> > @@ -3422,6 +3431,9 @@ HandleState(InputInfoPtr pInfo, struct SynapticsHwState *hw, CARD32 now,
> > if (inside_active_area)
> > store_history(priv, hw->x, hw->y, hw->millis);
> >
> > + if (priv->mustRelease)
> > + delay = 50;
>
> I think delay of 50 is too long, that may be noticeable (gut feeling, no
> hard data). I'd probably for for 10 or 20 at max. Whatever is the minimum to
> make the applications work.
I used actual double clicks as reference for this, but I noticed this
is not important. What's really important is the delay between the first
ButtonRelease and the second ButtonPress, as long as there's a delay
after the second ButtonPress and the second ButtonRelease.
Anyway, I think I've managed to handle this from HandleTapProcessing().
I just have to test the changes a bit more.
More information about the xorg-devel
mailing list