[PATCH v2 libinput] touchpad: serial synaptics need to fake new touches on TRIPLETAP

Hans de Goede hdegoede at redhat.com
Mon Jul 27 01:16:14 PDT 2015


Hi,

On 27-07-15 07:10, Peter Hutterer wrote:
> 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>
> ---
> Changes to v1:
> - add kernel shas to the commit message for reference
> - fix state handling in case of TOUCH_END
>
> Hans:
> This patch is queued for stable but not in 4.1.y yet, I'll wait a bit longer
> but if it isn't in there in say 2 weeks time I think we should ship this
> one anyway as a stopgap measure.

Grmbl, grbml, ok.

>
>   src/evdev-mt-touchpad.c | 20 +++++++++++++++-----
>   1 file changed, 15 insertions(+), 5 deletions(-)
>
> diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
> index 6718b61..602c670 100644
> --- a/src/evdev-mt-touchpad.c
> +++ b/src/evdev-mt-touchpad.c
> @@ -367,14 +367,24 @@ 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);
> +		enum touch_state state = t->state;
>
> -		if (t->state != TOUCH_END)
> +		switch(state) {
> +		case TOUCH_HOVERING:
> +		case TOUCH_BEGIN:
> +		case TOUCH_UPDATE:
>   			continue;
> +		/* new touch, move it through to begin immediately */
> +		case TOUCH_NONE:
> +		case TOUCH_END:
> +			tp_new_touch(tp, t, time);
> +			tp_begin_touch(tp, t, time);
> +			break;
> +		}
>
> -		/* 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;
> +		/* touch just ended ,we need need to restore it to update */
> +		if (state == TOUCH_END)
> +			t->state = TOUCH_UPDATE;
>   	}
>   }

IMHO it would be cleaner to do this here:

		switch(state) {
		case TOUCH_HOVERING:
		case TOUCH_BEGIN:
		case TOUCH_UPDATE:
  			continue;
		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;
		}

Rather then use the temporary state variable and have the if (state == ) ...

Ack (grmbl) either way:

Reviewed-by: Hans de Goede <hdegoede at redhat.com>

Regards,

Hans


More information about the wayland-devel mailing list