From: Matt Mayfield Date: Fri, 31 Aug 2018 02:29:46 +0000 (-0500) Subject: gestures: Improve thumb detection, allow one finger scroll X-Git-Tag: 1.13.901~1^2~9 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=15c8613a653526db17af713e18f6a90f6cae3b80;p=platform%2Fupstream%2Flibinput.git gestures: Improve thumb detection, allow one finger scroll Check if there's a thumb if we have two touches. If one finger moves but the thumb remains still, we assume that one is really a thumb. But if the thumb moves while the finger is still, let's assume this is a 2-finger scroll. Extracted from Matt Mayfield's thumb detection patchset --- diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c index a3f18dc..47d1417 100644 --- a/src/evdev-mt-touchpad-gestures.c +++ b/src/evdev-mt-touchpad-gestures.c @@ -471,11 +471,13 @@ static enum tp_gesture_state tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time) { struct tp_touch *first = tp->gesture.touches[0], - *second = tp->gesture.touches[1]; + *second = tp->gesture.touches[1], + *thumb; uint32_t dir1, dir2; struct device_coords delta; struct phys_coords first_moved, second_moved, distance_mm; double first_mm, second_mm; /* movement since gesture start in mm */ + double thumb_mm, finger_mm; double inner = 1.5; /* inner threshold in mm - count this touch */ double outer = 4.0; /* outer threshold in mm - ignore other touch */ @@ -497,6 +499,17 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time) if (first_mm < 1 && second_mm < 1) return GESTURE_STATE_UNKNOWN; + /* Pick the thumb as the lowest point on the touchpad */ + if (first->point.y > second->point.y) { + thumb = first; + thumb_mm = first_mm; + finger_mm = second_mm; + } else { + thumb = second; + thumb_mm = second_mm; + finger_mm = first_mm; + } + /* If both touches are within 7mm vertically and 40mm horizontally * past the timeout, assume scroll/swipe */ if ((!tp->gesture.enabled || @@ -511,29 +524,35 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time) } /* If one touch exceeds the outer threshold while the other has not - * yet passed the inner threshold, this is not a valid gesture. - * If thumb detection is enabled, and one of the touches is >20mm - * below the other, cancel the gesture and mark the thumb. - * - * Give the thumb a larger effective outer threshold for more reliable - * detection of pinch vs. resting thumb. + * yet passed the inner threshold, there is either a resting thumb, + * or the user is doing "one-finger-scroll," where one touch stays in + * place while the other moves. */ - if (tp->thumb.detect_thumbs && distance_mm.y > 20.0 && - time > (tp->gesture.initial_time + DEFAULT_GESTURE_SWIPE_TIMEOUT)) { - if ((first->point.y >= second->point.y) && - ((first_mm >= outer * 2.0) || - (second_mm >= outer))) { - tp_gesture_cancel(tp, time); - first->thumb.state = THUMB_STATE_YES; + if (first_mm >= outer || second_mm >= outer) { + /* If thumb detection is enabled, and thumb is still while + * finger moves, cancel gestures and mark lower as thumb. + * This applies to all gestures (2, 3, 4+ fingers), but allows + * more thumb motion on >2 finger gestures during detection. + */ + if (tp->thumb.detect_thumbs && thumb_mm < inner) { + tp_thumb_set_state(tp, thumb, THUMB_STATE_YES); return GESTURE_STATE_NONE; } - if ((second->point.y >= first->point.y) && - ((second_mm >= outer * 2.0) || - (first_mm >= outer))) { - tp_gesture_cancel(tp, time); - second->thumb.state = THUMB_STATE_YES; - return GESTURE_STATE_NONE; + + /* If gestures detection is disabled, or if finger is still + * while thumb moves, assume this is "one-finger scrolling." + * This applies only to 2-finger gestures. + */ + if ((!tp->gesture.enabled || finger_mm < inner) && + tp->gesture.finger_count == 2) { + tp_gesture_set_scroll_buildup(tp); + return GESTURE_STATE_SCROLL; } + + /* If we get here, either both fingers have passed the inner + * threshold (handled below), or >2 fingers are involved + * (handled in a future event when both have moved enough). + */ } /* If either touch is still inside the inner threshold, we can't