summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2020-02-20 13:17:58 -0500
committerMarcel Hollerbach <mail@marcel-hollerbach.de>2020-03-03 10:54:29 +0100
commit3603884e51daf0cbb853b33a9a7fa6421bf2b7ff (patch)
treebb5b2ab11f6df403cef8c61a8055e5d31ff3059d
parentd300e90d390fc9c764e57dc5806616e43e8db954 (diff)
downloadefl-3603884e51daf0cbb853b33a9a7fa6421bf2b7ff.tar.gz
efl/gesture: fix internal gesture object management
when a gesture ends and is not set to continue, the gesture object must be preserved until the entire touch sequence ends in order to ensure that all the touch point states are accurately detected and updated and so additional instances of that gesture are not accidentally triggered this fixes weird corner cases where you could tap with two fingers and then get a long press event while dragging the second finger around as long as you did it quickly enough Differential Revision: https://phab.enlightenment.org/D11384
-rw-r--r--src/lib/evas/gesture/efl_canvas_gesture_manager.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/src/lib/evas/gesture/efl_canvas_gesture_manager.c b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
index e33e3f2cb0..7a50a687f1 100644
--- a/src/lib/evas/gesture/efl_canvas_gesture_manager.c
+++ b/src/lib/evas/gesture/efl_canvas_gesture_manager.c
@@ -251,8 +251,9 @@ _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Ca
Eo *target, const Efl_Event_Description *gesture_type, void *event)
{
Efl_Canvas_Gesture_Recognizer_Result recog_result;
- Efl_Canvas_Gesture_Recognizer_Result recog_state;
+ Efl_Canvas_Gesture_Recognizer_Result recog_state = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
Efl_Canvas_Gesture_Touch *touch_event;
+ Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
//If the gesture canceled or already finished by recognizer.
Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type);
if (!gesture) return;
@@ -272,7 +273,9 @@ _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Ca
//Such as the case of canceling gesture recognition after a mouse down.
if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
return;
-
+ if ((!rd->continues) && ((efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_CANCELED) ||
+ (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_FINISHED)))
+ goto post_event;
/* this is the "default" value for the event, recognizers may modify it if necessary */
efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event));
@@ -281,9 +284,6 @@ _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Ca
recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK;
- Efl_Canvas_Gesture_Recognizer_Data *rd =
- efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
-
if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER)
{
if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_NONE)
@@ -318,6 +318,10 @@ _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Ca
efl_gesture_timestamp_set(gesture, efl_gesture_touch_current_timestamp_get(touch_event));
efl_event_callback_call(target, gesture_type, gesture);
post_event:
+ /* avoid destroying touch tracking before gesture has ended */
+ if ((!rd->continues) &&
+ ((efl_gesture_touch_state_get(touch_event) != EFL_GESTURE_TOUCH_STATE_END) || efl_gesture_touch_points_count_get(touch_event)))
+ return;
//If the current event recognizes the gesture continuously, dont delete gesture.
if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
!rd->continues)
@@ -448,8 +452,6 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
Eina_List *l;
Object_Gesture *object_gesture;
Efl_Canvas_Gesture *gesture;
- Efl_Canvas_Gesture_Recognizer_Data *rd =
- efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
//If the widget is being deleted we should be careful not to
//Create a new state.
@@ -463,16 +465,6 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
object_gesture->recognizer == recognizer &&
object_gesture->type == type)
{
- //The gesture is already processed waiting for cleanup
- if (((efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_FINISHED) ||
- (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_CANCELED)) &&
- (!rd->continues))
- {
- _cleanup_cached_gestures(pd, target, type, recognizer);
- eina_hash_del(pd->m_object_events, &recognizer, NULL);
- _cleanup_object(pd->m_gestures_to_delete);
- return NULL;
- }
return object_gesture->gesture;
}
}