Implementing right click and middle click drag

Peter Hutterer peter.hutterer at
Tue Jul 24 07:48:45 UTC 2018

On Fri, Jul 20, 2018 at 11:10:32AM +0530, Sagar Tewari wrote:
> On Wed, Jul 18, 2018 at 1:52 PM Peter Hutterer <peter.hutterer at>
> wrote:
> >
> > I'm not sure about the WITH_LOCK and POTENTIAL_UNLOCK parts, they should be
> > (in theory) the same as the existing ones where DRAGGING_WAIT goes back to
> > DRAGGING or DRAGGING_OR_TAP. Can you double-check this please whether it
> > would work out?
> >
> ​I've modified the state diagram so that the logic and nomenclature are
> equivalent to the already present left tap drag logic.

thanks! so, let's see:

TOUCH_2_DRAGGING_2: third finger down needs to go to a DEAD state like the
one at the bottom of the graph (so we recover accordingly until all fingers
are up)

TOUCH_2_DRAGGING_OR_TAP: that state is there twice now, was that intended?

TOUCH_2_DRAGGING_OR_TAP (lower one): palm/thumb needs to go back to TOUCH_2_TAPPED
(after marking that touch dead), otherwise an accidental palm brush resets
the dragging state.

TOUCH_2_DRAGGING_OR_TAP (upper left one):  the dragging timeout needs to
connect to TOUCH_2_DRAGGING

TOUCH_2_DRAGGING_WAIT: needs a timeout to go to btn 2 release and then

I'm not sure the two TOUCH_2_DRAGGING_OR_TAP states can be combined into
one, the thumb/palm handling may be different. But right now my brain is too
fried already to figure that out, sorry.

The rest is correct though, afaict.

> > Right now, there's a dead end in it:
> > TOUCH_2_DRAGGING -> finger up -> draglock enabled -> WITH_LOCK -> finger
> >
> > If the finger is now labelled as palm or thumb, you're stuck in
> > DRAGGING_WITH_LOCK until the next finger is down, never releasing.
> > This seems to be intended (your point 2.) but we definitely need a timeout
> > here. Imagine doing this, waiting 10 sec and then still continuing with the
> > dragging on the next touch - not what the user would expect.
> >
> > so DRAGGING_WITH_LOCK needs a timeout to go to the button 2 release.
> > then to make it more consistent to the 1fg case.
> >
> > And TOUCH_2_DRAGGING_DOWN for no other reason than it's more expressive of
> > the state and closer to the MULTITAP_DOWN naming scheme.
> >
> >
> > oh, found another one: in POTENTIAL_UNLOCK you may get a second finger down
> > - what do we do then? Either we go all the way back to TOUCH_2 which gives
> > us the ability to right-click-drag and right-click. Or we go to some new
> > state and resolve the 2fg tap as "end the draglock" tap. I really don't
> > know
> > which one is the more obvious one here.
> >
> > This has the potential to interfere with 2fg scrolling too:
> > - draglog is enabled
> > - 2 fingers down and up
> > - 1 finger down, dragging
> > - 1 finger up
> > - 2 fingers down and dragging (2fg scrol
> > ​
> > l)
> > ​
> >
> >
> ​In synaptics driver it's possible to scroll by putting down a second
> finger while dragging with a tap, it's super useful for selecting large
> texts on webpages and in tools like blender. Would it be possible for
> libinput to behave similarly? It looks like this too would require
> duplicating the code and states for left, right and middle clicks.

fwiw, this working in synaptics may be more by accident than intention. It
may be possible in libinput but scrolling and tapping have different states,
combining them intentionally is going to be tricky.

right now, any time scrolling would kick in, synaptics is already in a 'dead'
state and doesn't send any more events. With your state diagram, you'd end
up in TOUCH_2_DRAGGING_2, so a two-finger scroll that triggers then won't
affect the tapping state - hence it *should* work.

> As a side note, would it be possible to make the state machine more
> abstract, so that the similar behaviors for all the mouse buttons could be
> handled with the same code? Maybe it won't be worth it, since the state
> machine is a relatively short part of the libinput source.

I'm going to say it's not worth it - as soon as you introduce conditions for
the various paths you might as well throw the state machine out because it's
too hard to analyze. Right now, the state machine is a mess but it defines
exactly what happens when you transition from a->b->c. This is incredibly
useful when trying to figure out why a bug triggers.

Making it more abstract means sacrificing coding speed for debugging time -
not a good trade-off IMO (especially since I'll be then one debugging ;)


> Right now, this would... uhm, land us in TOUCH_2_DRAGGING, so it'd be a 2fg
> > scroll with the right button held down. And (hopefully) a warning in the
> > code about an invalid state ;)
> >
> > Oh, and once you handle the second finger down in POTENTIAL_UNLOCK you now
> > have to resolve a third finger down in whatever state comes next. Good
> > luck :)
> Best Regards
> Sagar Tewari

More information about the wayland-devel mailing list