mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-04 01:10:25 +01:00
Merge branch 'wip/fast-3fg-swipe' into 'main'
touchpad: add support for fast swipe when 3fg drag is enabled See merge request libinput/libinput!1410
This commit is contained in:
commit
bfa943b912
5 changed files with 358 additions and 51 deletions
|
|
@ -38,9 +38,11 @@ enum gesture_cancelled {
|
|||
#define DEFAULT_GESTURE_SWITCH_TIMEOUT usec_from_millis(100)
|
||||
#define DEFAULT_GESTURE_SWIPE_TIMEOUT usec_from_millis(150)
|
||||
#define DEFAULT_GESTURE_PINCH_TIMEOUT usec_from_millis(300)
|
||||
#define DRAG_3FG_OR_SWIPE_TIMEOUT usec_from_millis(80)
|
||||
|
||||
#define HOLD_AND_MOTION_THRESHOLD 0.5 /* mm */
|
||||
#define PINCH_DISAMBIGUATION_MOVE_THRESHOLD 1.5 /* mm */
|
||||
#define DRAG_3FG_OR_SWIPE_MOVE_THRESHOLD 5 /* mm */
|
||||
|
||||
enum gesture_event {
|
||||
GESTURE_EVENT_RESET,
|
||||
|
|
@ -55,7 +57,8 @@ enum gesture_event {
|
|||
GESTURE_EVENT_SCROLL_START,
|
||||
GESTURE_EVENT_SWIPE_START,
|
||||
GESTURE_EVENT_PINCH_START,
|
||||
GESTURE_EVENT_3FG_DRAG_START,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT,
|
||||
GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT,
|
||||
};
|
||||
|
||||
|
|
@ -83,6 +86,8 @@ gesture_state_to_str(enum tp_gesture_state state)
|
|||
CASE_RETURN_STRING(GESTURE_STATE_PINCH);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_SWIPE_START);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_SWIPE);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_3FG_DRAG_OR_SWIPE_START);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_3FG_DRAG_OR_SWIPE);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_3FG_DRAG_START);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_3FG_DRAG);
|
||||
CASE_RETURN_STRING(GESTURE_STATE_3FG_DRAG_RELEASED);
|
||||
|
|
@ -106,7 +111,8 @@ gesture_event_to_str(enum gesture_event event)
|
|||
CASE_RETURN_STRING(GESTURE_EVENT_SCROLL_START);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_SWIPE_START);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_PINCH_START);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_3FG_DRAG_START);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT);
|
||||
CASE_RETURN_STRING(GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT);
|
||||
}
|
||||
return NULL;
|
||||
|
|
@ -315,16 +321,6 @@ tp_gesture_init_pinch(struct tp_dispatch *tp)
|
|||
tp->gesture.prev_scale = 1.0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_gesture_init_3fg_drag(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
tp_gesture_stop_3fg_drag(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_set_scroll_buildup(struct tp_dispatch *tp)
|
||||
{
|
||||
|
|
@ -559,7 +555,7 @@ tp_gesture_handle_event_on_state_none(struct tp_dispatch *tp,
|
|||
*/
|
||||
if (!tp->tap.enabled &&
|
||||
tp->drag_3fg.nfingers == tp->gesture.finger_count) {
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_START;
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_OR_SWIPE_START;
|
||||
} else {
|
||||
tp_gesture_set_hold_timer(tp, time);
|
||||
tp->gesture.state = GESTURE_STATE_UNKNOWN;
|
||||
|
|
@ -578,13 +574,21 @@ tp_gesture_handle_event_on_state_none(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_HOLD_AND_MOTION_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_set_3fg_drag_3fg_or_swipe_timer(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
libinput_timer_set(&tp->gesture.drag_3fg_or_swipe_timer,
|
||||
usec_add(time, DRAG_3FG_OR_SWIPE_TIMEOUT));
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_unknown(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
|
|
@ -625,13 +629,13 @@ tp_gesture_handle_event_on_state_unknown(struct tp_dispatch *tp,
|
|||
tp_gesture_init_pinch(tp);
|
||||
tp->gesture.state = GESTURE_STATE_PINCH_START;
|
||||
break;
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
libinput_timer_cancel(&tp->gesture.hold_timer);
|
||||
tp_gesture_init_3fg_drag(tp, time);
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_START;
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_OR_SWIPE_START;
|
||||
break;
|
||||
case GESTURE_EVENT_HOLD_AND_MOTION_START:
|
||||
case GESTURE_EVENT_FINGER_DETECTED:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -682,14 +686,15 @@ tp_gesture_handle_event_on_state_hold(struct tp_dispatch *tp,
|
|||
tp_gesture_init_pinch(tp);
|
||||
tp->gesture.state = GESTURE_STATE_PINCH_START;
|
||||
break;
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
libinput_timer_cancel(&tp->gesture.hold_timer);
|
||||
tp_gesture_cancel(tp, time);
|
||||
tp_gesture_init_3fg_drag(tp, time);
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_START;
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_OR_SWIPE_START;
|
||||
break;
|
||||
case GESTURE_EVENT_HOLD_TIMEOUT:
|
||||
case GESTURE_EVENT_TAP_TIMEOUT:
|
||||
case GESTURE_EVENT_FINGER_DETECTED:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -730,7 +735,8 @@ tp_gesture_handle_event_on_state_hold_and_motion(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -776,7 +782,8 @@ tp_gesture_handle_event_on_state_pointer_motion(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -809,7 +816,8 @@ tp_gesture_handle_event_on_state_scroll_start(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_POINTER_MOTION_START:
|
||||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -844,7 +852,8 @@ tp_gesture_handle_event_on_state_scroll(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_POINTER_MOTION_START:
|
||||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -872,7 +881,8 @@ tp_gesture_handle_event_on_state_pinch_start(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -911,7 +921,8 @@ tp_gesture_handle_event_on_state_pinch(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -940,7 +951,8 @@ tp_gesture_handle_event_on_state_swipe_start(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -978,13 +990,101 @@ tp_gesture_handle_event_on_state_swipe(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag_or_swipe_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
usec_t time)
|
||||
{
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
case GESTURE_EVENT_END:
|
||||
case GESTURE_EVENT_CANCEL:
|
||||
libinput_timer_cancel(&tp->gesture.hold_timer);
|
||||
tp->gesture.state = GESTURE_STATE_NONE;
|
||||
break;
|
||||
case GESTURE_EVENT_FINGER_SWITCH_TIMEOUT:
|
||||
break;
|
||||
case GESTURE_EVENT_HOLD_AND_MOTION_START:
|
||||
case GESTURE_EVENT_FINGER_DETECTED:
|
||||
case GESTURE_EVENT_TAP_TIMEOUT:
|
||||
case GESTURE_EVENT_HOLD_TIMEOUT:
|
||||
case GESTURE_EVENT_POINTER_MOTION_START:
|
||||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag_or_swipe(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
usec_t time)
|
||||
{
|
||||
struct tp_touch *first = tp->gesture.touches[0],
|
||||
*second = tp->gesture.touches[1];
|
||||
struct phys_coords first_moved, second_moved;
|
||||
double first_mm, second_mm;
|
||||
|
||||
switch (event) {
|
||||
case GESTURE_EVENT_RESET:
|
||||
libinput_timer_cancel(&tp->gesture.hold_timer);
|
||||
tp->gesture.state = GESTURE_STATE_NONE;
|
||||
break;
|
||||
case GESTURE_EVENT_END:
|
||||
case GESTURE_EVENT_CANCEL: {
|
||||
bool cancelled = event == GESTURE_EVENT_CANCEL;
|
||||
gesture_notify_swipe_end(&tp->device->base,
|
||||
time,
|
||||
tp->gesture.finger_count,
|
||||
cancelled);
|
||||
tp->gesture.state = GESTURE_STATE_NONE;
|
||||
break;
|
||||
}
|
||||
case GESTURE_EVENT_FINGER_SWITCH_TIMEOUT:
|
||||
break;
|
||||
case GESTURE_EVENT_HOLD_AND_MOTION_START:
|
||||
case GESTURE_EVENT_FINGER_DETECTED:
|
||||
case GESTURE_EVENT_TAP_TIMEOUT:
|
||||
case GESTURE_EVENT_HOLD_TIMEOUT:
|
||||
case GESTURE_EVENT_POINTER_MOTION_START:
|
||||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_or_swipe_timer);
|
||||
|
||||
first_moved = tp_gesture_mm_moved(tp, first);
|
||||
second_moved = tp_gesture_mm_moved(tp, second);
|
||||
first_mm = hypot(first_moved.x, first_moved.y);
|
||||
second_mm = hypot(second_moved.x, second_moved.y);
|
||||
if ((first_mm + second_mm) / 2.0 >= DRAG_3FG_OR_SWIPE_MOVE_THRESHOLD) {
|
||||
tp->gesture.state = GESTURE_STATE_SWIPE;
|
||||
} else {
|
||||
/* Cancel the swipe */
|
||||
tp_gesture_cancel(tp, time);
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_START;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_event_on_state_3fg_drag_start(struct tp_dispatch *tp,
|
||||
enum gesture_event event,
|
||||
|
|
@ -1007,7 +1107,8 @@ tp_gesture_handle_event_on_state_3fg_drag_start(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -1062,7 +1163,8 @@ tp_gesture_handle_event_on_state_3fg_drag(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_SCROLL_START:
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
|
|
@ -1081,7 +1183,6 @@ tp_gesture_handle_event_on_state_3fg_drag_released(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_END:
|
||||
case GESTURE_EVENT_CANCEL:
|
||||
case GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT:
|
||||
tp_gesture_stop_3fg_drag(tp, time);
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_timer);
|
||||
libinput_timer_cancel(&tp->gesture.finger_count_switch_timer);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
|
|
@ -1100,7 +1201,6 @@ tp_gesture_handle_event_on_state_3fg_drag_released(struct tp_dispatch *tp,
|
|||
case GESTURE_EVENT_FINGER_DETECTED:
|
||||
break;
|
||||
case GESTURE_EVENT_POINTER_MOTION_START:
|
||||
tp_gesture_stop_3fg_drag(tp, time);
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_timer);
|
||||
evdev_pointer_notify_button(tp->device,
|
||||
tp->gesture.drag_3fg_release_time,
|
||||
|
|
@ -1124,10 +1224,13 @@ tp_gesture_handle_event_on_state_3fg_drag_released(struct tp_dispatch *tp,
|
|||
break;
|
||||
case GESTURE_EVENT_SWIPE_START:
|
||||
case GESTURE_EVENT_PINCH_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_START:
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_timer);
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG;
|
||||
break;
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START:
|
||||
case GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT:
|
||||
log_gesture_bug(tp, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1172,6 +1275,14 @@ tp_gesture_handle_event(struct tp_dispatch *tp, enum gesture_event event, usec_t
|
|||
case GESTURE_STATE_SWIPE:
|
||||
tp_gesture_handle_event_on_state_swipe(tp, event, time);
|
||||
break;
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE_START:
|
||||
tp_gesture_handle_event_on_state_3fg_drag_or_swipe_start(tp,
|
||||
event,
|
||||
time);
|
||||
break;
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE:
|
||||
tp_gesture_handle_event_on_state_3fg_drag_or_swipe(tp, event, time);
|
||||
break;
|
||||
case GESTURE_STATE_3FG_DRAG_START:
|
||||
tp_gesture_handle_event_on_state_3fg_drag_start(tp, event, time);
|
||||
break;
|
||||
|
|
@ -1222,6 +1333,14 @@ tp_gesture_3fg_drag_timeout(usec_t now, void *data)
|
|||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_RELEASE_TIMEOUT, now);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_3fg_drag_or_swipe_timeout(usec_t now, void *data)
|
||||
{
|
||||
struct tp_dispatch *tp = data;
|
||||
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_OR_SWIPE_TIMEOUT, now);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
|
|
@ -1264,7 +1383,9 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
|||
if (tp->gesture.enabled && tp->gesture.finger_count > 2 &&
|
||||
tp->gesture.finger_count > tp->num_slots) {
|
||||
if (tp->drag_3fg.nfingers == tp->gesture.finger_count)
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_START, time);
|
||||
tp_gesture_handle_event(tp,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START,
|
||||
time);
|
||||
else
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE_START, time);
|
||||
return;
|
||||
|
|
@ -1294,7 +1415,9 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
|||
if (tp->gesture.finger_count == 2)
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_SCROLL_START, time);
|
||||
else if (tp->drag_3fg.nfingers == tp->gesture.finger_count)
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_START, time);
|
||||
tp_gesture_handle_event(tp,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START,
|
||||
time);
|
||||
else
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_SWIPE_START, time);
|
||||
|
||||
|
|
@ -1302,10 +1425,12 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
|||
}
|
||||
|
||||
/* If 3fg dragging touches are within a 60x10mm box, start
|
||||
* dragging immediately */
|
||||
* dragging (or swiping) immediately */
|
||||
if (tp->gesture.finger_count == tp->drag_3fg.nfingers && distance_mm.x < 60.0 &&
|
||||
distance_mm.y < 10.0) {
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_START, time);
|
||||
tp_gesture_handle_event(tp,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START,
|
||||
time);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1383,7 +1508,9 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
|||
}
|
||||
|
||||
if (tp->drag_3fg.nfingers == tp->gesture.finger_count) {
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_3FG_DRAG_START, time);
|
||||
tp_gesture_handle_event(tp,
|
||||
GESTURE_EVENT_3FG_DRAG_OR_SWIPE_START,
|
||||
time);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1738,11 +1865,45 @@ tp_gesture_handle_state_3fg_drag_released(struct tp_dispatch *tp,
|
|||
tp_gesture_detect_motion_gestures(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_3fg_drag_or_swipe(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
struct device_float_coords raw;
|
||||
struct normalized_coords delta, unaccel;
|
||||
|
||||
raw = tp_get_average_touches_delta(tp);
|
||||
delta = tp_filter_motion(tp, &raw, time);
|
||||
|
||||
if (!normalized_is_zero(delta) || !device_float_is_zero(raw)) {
|
||||
unaccel = tp_filter_motion_unaccelerated(tp, &raw, time);
|
||||
gesture_notify_swipe(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
tp->gesture.finger_count,
|
||||
&delta,
|
||||
&unaccel);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state_3fg_drag_or_swipe_start(struct tp_dispatch *tp, usec_t time)
|
||||
{
|
||||
const struct normalized_coords zero = { 0.0, 0.0 };
|
||||
gesture_notify_swipe(&tp->device->base,
|
||||
time,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
tp->gesture.finger_count,
|
||||
&zero,
|
||||
&zero);
|
||||
tp->gesture.state = GESTURE_STATE_3FG_DRAG_OR_SWIPE;
|
||||
tp_gesture_set_3fg_drag_3fg_or_swipe_timer(tp, time);
|
||||
}
|
||||
|
||||
static void
|
||||
tp_gesture_handle_state(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
||||
{
|
||||
enum tp_gesture_state oldstate = tp->gesture.state;
|
||||
enum tp_gesture_state transitions[16] = { 0 };
|
||||
enum tp_gesture_state transitions[18] = { 0 };
|
||||
enum tp_gesture_state *transition_state = transitions;
|
||||
|
||||
#define REMEMBER_TRANSITION(_ts, _state) { \
|
||||
|
|
@ -1810,6 +1971,14 @@ tp_gesture_handle_state(struct tp_dispatch *tp, usec_t time, bool ignore_motion)
|
|||
tp_gesture_handle_state_3fg_drag_released(tp, time, ignore_motion);
|
||||
REMEMBER_TRANSITION(transition_state, tp->gesture.state);
|
||||
}
|
||||
if (tp->gesture.state == GESTURE_STATE_3FG_DRAG_OR_SWIPE) {
|
||||
tp_gesture_handle_state_3fg_drag_or_swipe(tp, time);
|
||||
REMEMBER_TRANSITION(transition_state, tp->gesture.state);
|
||||
}
|
||||
if (tp->gesture.state == GESTURE_STATE_3FG_DRAG_OR_SWIPE_START) {
|
||||
tp_gesture_handle_state_3fg_drag_or_swipe_start(tp, time);
|
||||
REMEMBER_TRANSITION(transition_state, tp->gesture.state);
|
||||
}
|
||||
|
||||
#undef REMEMBER_TRANSITION
|
||||
|
||||
|
|
@ -1907,6 +2076,7 @@ tp_gesture_end(struct tp_dispatch *tp, usec_t time, enum gesture_cancelled cance
|
|||
case GESTURE_STATE_PINCH_START:
|
||||
case GESTURE_STATE_SWIPE_START:
|
||||
case GESTURE_STATE_3FG_DRAG_START:
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE_START:
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_RESET, time);
|
||||
break;
|
||||
case GESTURE_STATE_HOLD:
|
||||
|
|
@ -1917,6 +2087,7 @@ tp_gesture_end(struct tp_dispatch *tp, usec_t time, enum gesture_cancelled cance
|
|||
case GESTURE_STATE_SWIPE:
|
||||
case GESTURE_STATE_3FG_DRAG:
|
||||
case GESTURE_STATE_3FG_DRAG_RELEASED:
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE:
|
||||
switch (cancelled) {
|
||||
case CANCEL_GESTURE:
|
||||
tp_gesture_handle_event(tp, GESTURE_EVENT_CANCEL, time);
|
||||
|
|
@ -1961,6 +2132,11 @@ tp_gesture_cancel_motion_gestures(struct tp_dispatch *tp, usec_t time)
|
|||
break;
|
||||
case GESTURE_STATE_3FG_DRAG_RELEASED:
|
||||
break;
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE:
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE_START:
|
||||
evdev_log_debug(tp->device, "Cancelling motion gestures\n");
|
||||
tp_gesture_cancel(tp, time);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2002,6 +2178,8 @@ tp_gesture_debounce_finger_changes(struct tp_dispatch *tp)
|
|||
case GESTURE_STATE_3FG_DRAG_START:
|
||||
case GESTURE_STATE_3FG_DRAG_RELEASED:
|
||||
case GESTURE_STATE_3FG_DRAG:
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE:
|
||||
case GESTURE_STATE_3FG_DRAG_OR_SWIPE_START:
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2244,6 +2422,15 @@ tp_init_gesture(struct tp_dispatch *tp)
|
|||
timer_name,
|
||||
tp_gesture_3fg_drag_timeout,
|
||||
tp);
|
||||
snprintf(timer_name,
|
||||
sizeof(timer_name),
|
||||
"%s drag_or_swipe",
|
||||
evdev_device_get_sysname(tp->device));
|
||||
libinput_timer_init(&tp->gesture.drag_3fg_or_swipe_timer,
|
||||
tp_libinput_context(tp),
|
||||
timer_name,
|
||||
tp_gesture_3fg_drag_or_swipe_timeout,
|
||||
tp);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -2252,4 +2439,5 @@ tp_remove_gesture(struct tp_dispatch *tp)
|
|||
libinput_timer_cancel(&tp->gesture.finger_count_switch_timer);
|
||||
libinput_timer_cancel(&tp->gesture.hold_timer);
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_timer);
|
||||
libinput_timer_cancel(&tp->gesture.drag_3fg_or_swipe_timer);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1975,6 +1975,7 @@ tp_interface_destroy(struct evdev_dispatch *dispatch)
|
|||
libinput_timer_destroy(&tp->gesture.finger_count_switch_timer);
|
||||
libinput_timer_destroy(&tp->gesture.hold_timer);
|
||||
libinput_timer_destroy(&tp->gesture.drag_3fg_timer);
|
||||
libinput_timer_destroy(&tp->gesture.drag_3fg_or_swipe_timer);
|
||||
free(tp->touches);
|
||||
free(tp);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ enum tp_gesture_state {
|
|||
GESTURE_STATE_PINCH,
|
||||
GESTURE_STATE_SWIPE_START,
|
||||
GESTURE_STATE_SWIPE,
|
||||
GESTURE_STATE_3FG_DRAG_OR_SWIPE_START,
|
||||
GESTURE_STATE_3FG_DRAG_OR_SWIPE,
|
||||
GESTURE_STATE_3FG_DRAG_START,
|
||||
GESTURE_STATE_3FG_DRAG,
|
||||
GESTURE_STATE_3FG_DRAG_RELEASED,
|
||||
|
|
@ -371,6 +373,8 @@ struct tp_dispatch {
|
|||
|
||||
struct libinput_timer drag_3fg_timer;
|
||||
usec_t drag_3fg_release_time;
|
||||
|
||||
struct libinput_timer drag_3fg_or_swipe_timer;
|
||||
} gesture;
|
||||
|
||||
struct {
|
||||
|
|
|
|||
|
|
@ -1371,6 +1371,7 @@ _litest_timeout(struct libinput *li, const char *func, int lineno, int millis);
|
|||
#define litest_timeout_tablet_proxout(li_) litest_timeout(li_, 170)
|
||||
#define litest_timeout_touch_arbitration(li_) litest_timeout(li_, 100)
|
||||
#define litest_timeout_hysteresis(li_) litest_timeout(li_, 90)
|
||||
#define litest_timeout_3fg_drag_or_swipe(li_) litest_timeout(li_, 90)
|
||||
#define litest_timeout_3fg_drag(li_) litest_timeout(li_, 800)
|
||||
#define litest_timeout_eraser_button(li_) litest_timeout(li_, 50)
|
||||
|
||||
|
|
|
|||
|
|
@ -1587,6 +1587,18 @@ START_TEST(gestures_hold_and_motion_after_timeout)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
static void
|
||||
drain_cancelled_swipe_gesture(struct libinput *li)
|
||||
{
|
||||
litest_drain_events_of_type(li,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE);
|
||||
|
||||
_destroy_(libinput_event) *end = libinput_get_event(li);
|
||||
auto gev = litest_is_gesture_event(end, LIBINPUT_EVENT_GESTURE_SWIPE_END, -1);
|
||||
litest_assert(libinput_event_gesture_get_cancelled(gev));
|
||||
}
|
||||
|
||||
START_TEST(gestures_3fg_drag)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
|
|
@ -1626,21 +1638,25 @@ START_TEST(gestures_3fg_drag)
|
|||
litest_assert_empty_queue(li);
|
||||
} else {
|
||||
litest_checkpoint(
|
||||
"Expecting immediate button press as tapping is disabled");
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
"Expecting immediate swipe begin tapping is disabled");
|
||||
litest_assert_gesture_event(li,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
finger_count);
|
||||
}
|
||||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
|
||||
if (tap_enabled) {
|
||||
litest_checkpoint("Expecting late button press as tapping is enabled");
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
}
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
|
|
@ -1688,10 +1704,15 @@ START_TEST(gestures_3fg_drag_lock_resume_3fg_motion)
|
|||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
|
|
@ -1777,10 +1798,15 @@ START_TEST(gestures_3fg_drag_lock_resume_3fg_release_no_motion)
|
|||
litest_dispatch(li);
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
|
|
@ -1870,10 +1896,15 @@ START_TEST(gestures_3fg_drag_lock_resume_1fg_motion)
|
|||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
|
|
@ -1943,10 +1974,15 @@ START_TEST(gestures_3fg_drag_lock_resume_2fg_scroll)
|
|||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
|
|
@ -2012,14 +2048,19 @@ START_TEST(gestures_3fg_drag_lock_resume_1fg_tap)
|
|||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (int i = 0; i < finger_count; i++)
|
||||
for (int i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
if (i ==
|
||||
0) /* Wait after the first movement to escape the swipe */
|
||||
litest_timeout_3fg_drag_or_swipe(li);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
litest_drain_events_of_type(li,
|
||||
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
|
||||
LIBINPUT_EVENT_GESTURE_HOLD_END,
|
||||
-1);
|
||||
drain_cancelled_swipe_gesture(li);
|
||||
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
|
||||
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
|
||||
|
||||
|
|
@ -2054,6 +2095,72 @@ START_TEST(gestures_3fg_drag_lock_resume_1fg_tap)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(gestures_3fg_drag_fast_swipe)
|
||||
{
|
||||
struct litest_device *dev = litest_current_device();
|
||||
struct libinput *li = dev->libinput;
|
||||
|
||||
uint32_t finger_count = litest_test_param_get_u32(test_env->params, "fingers");
|
||||
bool tap_enabled = litest_test_param_get_bool(test_env->params, "tap-enabled");
|
||||
|
||||
if (litest_slot_count(dev) < 3)
|
||||
return LITEST_NOT_APPLICABLE;
|
||||
if (libinput_device_config_3fg_drag_get_finger_count(dev->libinput_device) <
|
||||
(int)finger_count)
|
||||
return LITEST_NOT_APPLICABLE;
|
||||
|
||||
litest_enable_3fg_drag(dev->libinput_device, finger_count);
|
||||
if (tap_enabled)
|
||||
litest_enable_tap(dev->libinput_device);
|
||||
else
|
||||
litest_disable_tap(dev->libinput_device);
|
||||
|
||||
litest_drain_events(li);
|
||||
|
||||
double y = 30.0;
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
litest_touch_down(dev, i, 10 + i, y);
|
||||
|
||||
while (y < 60.0) {
|
||||
y += 2;
|
||||
for (uint32_t i = 0; i < finger_count; i++) {
|
||||
litest_touch_move(dev, i, 10 + i, y);
|
||||
}
|
||||
litest_dispatch(li);
|
||||
}
|
||||
|
||||
litest_drain_events_of_type(li,
|
||||
LIBINPUT_EVENT_GESTURE_HOLD_BEGIN,
|
||||
LIBINPUT_EVENT_GESTURE_HOLD_END);
|
||||
|
||||
auto begin = libinput_get_event(li);
|
||||
litest_is_gesture_event(begin,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_BEGIN,
|
||||
finger_count);
|
||||
libinput_event_destroy(begin);
|
||||
|
||||
struct libinput_event *update;
|
||||
while ((update = libinput_get_event(li))) {
|
||||
litest_is_gesture_event(update,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_UPDATE,
|
||||
finger_count);
|
||||
libinput_event_destroy(update);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < finger_count; i++)
|
||||
litest_touch_up(dev, i);
|
||||
|
||||
litest_dispatch(li);
|
||||
|
||||
auto end = libinput_get_event(li);
|
||||
auto gev = litest_is_gesture_event(end,
|
||||
LIBINPUT_EVENT_GESTURE_SWIPE_END,
|
||||
finger_count);
|
||||
litest_assert(!libinput_event_gesture_get_cancelled(gev));
|
||||
libinput_event_destroy(end);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
TEST_COLLECTION(gestures)
|
||||
{
|
||||
/* clang-format off */
|
||||
|
|
@ -2136,6 +2243,12 @@ TEST_COLLECTION(gestures)
|
|||
litest_add_parametrized(gestures_3fg_drag_lock_resume_1fg_tap, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, params);
|
||||
}
|
||||
|
||||
litest_with_parameters(params,
|
||||
"fingers", 'u', 2, 3, 4,
|
||||
"tap-enabled", 'b') {
|
||||
litest_add_parametrized(gestures_3fg_drag_fast_swipe, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, params);
|
||||
}
|
||||
|
||||
/* Timing-sensitive test, valgrind is too slow */
|
||||
if (!RUNNING_ON_VALGRIND)
|
||||
litest_add(gestures_swipe_3fg_unaccel, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue