Skip to content

Fix touch termination and BTN_TOOL_ handling after SYN_DROPPED

cc @bentiss

This sits on top of !18 (merged)

Assuming a SYN_DROPPED and at least one touch stopping (possibly restarting) during that SYN_DROPPED, we mangled the event sequences badly, causing libinput bug libinput/libinput#422 (closed). Specifically: The first event frame would contain all the device state and the terminated touches. The second frame would contain only the touches that started or re-started during SYN_DROPPED. Because the key bits were part of the first touch, we could have a sequence like this for a SYN_DROPPED when changing from 3 fingers to 2 fingers (lifting all in between).

EV_KEY BTN_TOOL_DOUBLETAP 1
EV_ABS ABS_MT_SLOT 0
EV_ABS ABS_MT_TRACKING_ID -1
EV_ABS ABS_MT_SLOT 1
EV_ABS ABS_MT_TRACKING_ID -1
EV_ABS ABS_MT_SLOT 0
EV_ABS ABS_MT_TRACKING_ID 23
EV_ABS ABS_MT_SLOT 1
EV_ABS ABS_MT_TRACKING_ID 24
EV_ABS ABS_MT_SLOT 2
EV_ABS ABS_MT_TRACKING_ID -1

The first frame says two fingers are down (BTN_TOOL_DOUBLETAP) despite releasing two out of three fingers in the same frame. This causes libinput to get confused about how many touches the device can handle (there are devices that advertise more slots than they use, so we downward-adjust for that, see libinput/libinput#408 (closed)). Note also that touches that stopped were terminated in the second frame, not the first.

This patch series cleans up a fair chunk of the code, but eventually changes two things about the sequence above:

  • any touches stopped are now terminated in the first frame
  • the required BTN_TOOL_* events are inserted into the stream according to our touch count.

The above interaction thus becomes:

EV_KEY BTN_TOOL_TRIPLETAP 0
EV_ABS ABS_MT_SLOT 0
EV_ABS ABS_MT_TRACKING_ID -1
EV_ABS ABS_MT_SLOT 1
EV_ABS ABS_MT_TRACKING_ID -1
EV_ABS ABS_MT_SLOT 2
EV_ABS ABS_MT_TRACKING_ID -1
EV_ABS ABS_MT_SLOT 0
EV_ABS ABS_MT_TRACKING_ID 23
EV_ABS ABS_MT_SLOT 1
EV_ABS ABS_MT_TRACKING_ID 24
EV_KEY BTN_TOOL_DOUBLETAP 1

Merge request reports