This is a workaround upstream suggests for use with kernel 4.1.

Upstream-Status: Inappropriate [temporary work-around]
Signed-off-by: Jussi Kukkonen <jussi.kukkonen@intel.com>



From: Peter Hutterer <peter.hutterer@who-t.net>
Date: Mon Aug 3 18:23:12 PDT 2015
Subject: [PATCH v3 libinput] touchpad: serial synaptics need to fake new touches on TRIPLETAP

On the 4.1 kernels synaptics pretends to have 3 slots (the serial fw only does
2). This was added to avoid cursor jumps but has since been reverted for 4.2
(kernel commit dbf3c37086, 4.1.3 is still buggy). In some cases a TRIPLETAP
may be triggered without slot 2 ever activating.

While there are still those kernels out there, work around this bug by opening
a new touch point where none exists if the fake finger count exceeds the slot
count.

Reported-by: Jan Alexander Steffens <jan.steffens at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
Tested-by: Jan Alexander Steffens <jan.steffens at gmail.com>
Reviewed-by: Hans de Goede <hdegoede at redhat.com>
---
Changes to v2:
- split out the handling instead of having a tmp state variable, see Hans'
  comments from v2

Mainly sending this to the list again so I have a link to point people to.
If you're on 4.1.x add this patch to your distribution package.

 src/evdev-mt-touchpad.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index a683d9a..5ef03d5 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -369,13 +369,23 @@ tp_restore_synaptics_touches(struct tp_dispatch *tp,
 	for (i = 0; i < tp->num_slots; i++) {
 		struct tp_touch *t = tp_get_touch(tp, i);
 
-		if (t->state != TOUCH_END)
+		switch(t->state) {
+		case TOUCH_HOVERING:
+		case TOUCH_BEGIN:
+		case TOUCH_UPDATE:
 			continue;
-
-		/* new touch, move it through begin to update immediately */
-		tp_new_touch(tp, t, time);
-		tp_begin_touch(tp, t, time);
-		t->state = TOUCH_UPDATE;
+		case TOUCH_NONE:
+			/* new touch, move it through to begin immediately */
+			tp_new_touch(tp, t, time);
+			tp_begin_touch(tp, t, time);
+			break;
+		case TOUCH_END:
+			/* touch just ended ,we need need to restore it to update */
+			tp_new_touch(tp, t, time);
+			tp_begin_touch(tp, t, time);
+			t->state = TOUCH_UPDATE;
+			break;
+		}
 	}
 }
 
-- 
2.4.3

