[PATCH libinput 5/7] touchpad: Make tap code follow state machine diagram part 1

Hans de Goede hdegoede at redhat.com
Sun Sep 28 04:22:21 PDT 2014


According to the diagram, we should only check the tap-touch-state before
sending a button press / release when in state touch_2 or touch_3.

tp_tap_notify always checks the tap-touch-state. This is problematic when in
state tapped, or one of the follow up states, since this could cause the
button 1 release to never happen.

In practice this is never a problem since the touch passed into tp_tap_notify
is NULL when called for timeout or button events, and in the 2 affected paths
where we're dealing with a touch or release tap-touch-state always is
TAP_TOUCH_STATE_TOUCH.

However we should not rely on this and properly follow the diagram, this
commit therefor drops the touch argument to tp_tap_notify, and add explicit
tap-touch-state checks in the places where they are present in the diagram too.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 src/evdev-mt-touchpad-tap.c | 43 +++++++++++++++++++++----------------------
 1 file changed, 21 insertions(+), 22 deletions(-)

diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index e352ff4..b5f63fa 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -95,16 +95,12 @@ tap_event_to_str(enum tap_event event) {
 
 static void
 tp_tap_notify(struct tp_dispatch *tp,
-	      struct tp_touch *t,
 	      uint64_t time,
 	      int nfingers,
 	      enum libinput_button_state state)
 {
 	int32_t button;
 
-	if (t && t->tap.state == TAP_TOUCH_STATE_DEAD)
-		return;
-
 	switch (nfingers) {
 	case 1: button = BTN_LEFT; break;
 	case 2: button = BTN_RIGHT; break;
@@ -174,7 +170,7 @@ tp_tap_touch_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_RELEASE:
 		tp->tap.state = TAP_STATE_TAPPED;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
 		tp_tap_set_timer(tp, time);
 		break;
 	case TAP_EVENT_TIMEOUT:
@@ -229,11 +225,11 @@ tp_tap_tapped_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_TIMEOUT:
 		tp->tap.state = TAP_STATE_IDLE;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	}
 }
@@ -251,8 +247,10 @@ tp_tap_touch2_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_RELEASE:
 		tp->tap.state = TAP_STATE_HOLD;
-		tp_tap_notify(tp, t, time, 2, LIBINPUT_BUTTON_STATE_PRESSED);
-		tp_tap_notify(tp, t, time, 2, LIBINPUT_BUTTON_STATE_RELEASED);
+		if (t->tap.state == TAP_TOUCH_STATE_TOUCH) {
+			tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_PRESSED);
+			tp_tap_notify(tp, time, 2, LIBINPUT_BUTTON_STATE_RELEASED);
+		}
 		tp_tap_clear_timer(tp);
 		break;
 	case TAP_EVENT_MOTION:
@@ -309,8 +307,10 @@ tp_tap_touch3_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_RELEASE:
 		tp->tap.state = TAP_STATE_TOUCH_2_HOLD;
-		tp_tap_notify(tp, t, time, 3, LIBINPUT_BUTTON_STATE_PRESSED);
-		tp_tap_notify(tp, t, time, 3, LIBINPUT_BUTTON_STATE_RELEASED);
+		if (t->tap.state == TAP_TOUCH_STATE_TOUCH) {
+			tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_PRESSED);
+			tp_tap_notify(tp, time, 3, LIBINPUT_BUTTON_STATE_RELEASED);
+		}
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
@@ -352,9 +352,9 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_RELEASE:
 		tp->tap.state = TAP_STATE_IDLE;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_PRESSED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		tp_tap_clear_timer(tp);
 		break;
 	case TAP_EVENT_MOTION:
@@ -363,7 +363,7 @@ tp_tap_dragging_or_doubletap_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	}
 }
@@ -388,7 +388,7 @@ tp_tap_dragging_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	}
 }
@@ -409,11 +409,11 @@ tp_tap_dragging_wait_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_TIMEOUT:
 		tp->tap.state = TAP_STATE_IDLE;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	}
 }
@@ -430,7 +430,7 @@ tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_TOUCH:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	case TAP_EVENT_MOTION:
 	case TAP_EVENT_TIMEOUT:
@@ -438,7 +438,7 @@ tp_tap_dragging2_handle_event(struct tp_dispatch *tp,
 		break;
 	case TAP_EVENT_BUTTON:
 		tp->tap.state = TAP_STATE_DEAD;
-		tp_tap_notify(tp, t, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
+		tp_tap_notify(tp, time, 1, LIBINPUT_BUTTON_STATE_RELEASED);
 		break;
 	}
 }
@@ -733,8 +733,7 @@ tp_release_all_taps(struct tp_dispatch *tp, uint64_t now)
 
 	for (i = 1; i <= 3; i++)
 		if (tp->tap.buttons_pressed & (1 << i))
-			tp_tap_notify(tp, NULL, now, i,
-				      LIBINPUT_BUTTON_STATE_RELEASED);
+			tp_tap_notify(tp, now, i, LIBINPUT_BUTTON_STATE_RELEASED);
 
 	tp->tap.state = tp->nfingers_down ? TAP_STATE_DEAD : TAP_STATE_IDLE;
 }
-- 
2.1.0



More information about the wayland-devel mailing list