mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-04 05:50:26 +01:00
touchpad: Make tap code follow state machine diagram part 1
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 adds explicit tap-touch-state checks in the places where they are present in the diagram too. Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
6699d1b637
commit
7a64815faa
1 changed files with 21 additions and 22 deletions
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -731,8 +731,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;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue