evdevtouch: ensure touchpoints released with typeB mtdev drivers

This happens in one particular case: when the touchpoint corresponding
to the last slot is reported as released and a new point is reported
as pressed right after, so that both events happens within a same sync.
In this case, there will be two ABS_MT_TRACKING_ID events received,
first with -1 to report the released touchpoint, then with a new id
to report the pressed touchpoint, then the SYN_REPORT afterwards.

This results in m_contacts[m_currentSlot].state being updated to
Qt::TouchPointReleased then Qt::TouchPointPressed, with the former never
being reported during the handling of SYN_REPORT.
To handle this scenario we need to inspect m_lastContacts for a change
in tracking id for a particular slot combined with a non-null state,
indicating that slot has not yet been reported released and processed
in the previous sync. (the state for processed released points is reset
to zero at the end of the SYN_REPORT handler)

Task-number: QTBUG-51563
Change-Id: I01493008cf9f267e758d974dab29556d0a1425ea
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Reviewed-by: Robin Burchell <robin.burchell@viroteck.net>
bb10
Romain Pokrzywka 2015-09-17 10:21:32 -07:00 committed by Shawn Rutledge
parent 361142b5fc
commit 359546b069
1 changed files with 10 additions and 3 deletions

View File

@ -531,9 +531,16 @@ void QEvdevTouchScreenData::processInputEvent(input_event *data)
it.next();
Contact &contact(it.value());
int key = m_typeB ? it.key() : contact.trackingId;
if (!m_contacts.contains(key)) {
contact.state = Qt::TouchPointReleased;
addTouchPoint(contact, &combinedStates);
if (m_typeB) {
if (contact.trackingId != m_contacts[key].trackingId && contact.state) {
contact.state = Qt::TouchPointReleased;
addTouchPoint(contact, &combinedStates);
}
} else {
if (!m_contacts.contains(key)) {
contact.state = Qt::TouchPointReleased;
addTouchPoint(contact, &combinedStates);
}
}
}