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)
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
251 Eo *target, const Efl_Event_Description *gesture_type, void *event) 251 Eo *target, const Efl_Event_Description *gesture_type, void *event)
252{ 252{
253 Efl_Canvas_Gesture_Recognizer_Result recog_result; 253 Efl_Canvas_Gesture_Recognizer_Result recog_result;
254 Efl_Canvas_Gesture_Recognizer_Result recog_state; 254 Efl_Canvas_Gesture_Recognizer_Result recog_state = EFL_GESTURE_RECOGNIZER_RESULT_FINISH;
255 Efl_Canvas_Gesture_Touch *touch_event; 255 Efl_Canvas_Gesture_Touch *touch_event;
256 Efl_Canvas_Gesture_Recognizer_Data *rd = efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
256 //If the gesture canceled or already finished by recognizer. 257 //If the gesture canceled or already finished by recognizer.
257 Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type); 258 Efl_Canvas_Gesture *gesture = _get_state(pd, target, recognizer, gesture_type);
258 if (!gesture) return; 259 if (!gesture) return;
@@ -272,7 +273,9 @@ _gesture_recognizer_process_internal(Efl_Canvas_Gesture_Manager_Data *pd, Efl_Ca
272 //Such as the case of canceling gesture recognition after a mouse down. 273 //Such as the case of canceling gesture recognition after a mouse down.
273 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN) 274 if (efl_gesture_touch_state_get(touch_event) == EFL_GESTURE_TOUCH_STATE_UNKNOWN)
274 return; 275 return;
275 276 if ((!rd->continues) && ((efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_CANCELED) ||
277 (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_FINISHED)))
278 goto post_event;
276 279
277 /* this is the "default" value for the event, recognizers may modify it if necessary */ 280 /* this is the "default" value for the event, recognizers may modify it if necessary */
278 efl_gesture_touch_count_set(gesture, efl_gesture_touch_points_count_get(touch_event)); 281 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
281 recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event); 284 recog_result = efl_gesture_recognizer_recognize(recognizer, gesture, target, touch_event);
282 recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK; 285 recog_state = recog_result & EFL_GESTURE_RECOGNIZER_RESULT_RESULT_MASK;
283 286
284 Efl_Canvas_Gesture_Recognizer_Data *rd =
285 efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
286
287 if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER) 287 if (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_TRIGGER)
288 { 288 {
289 if (efl_gesture_state_get(gesture) == EFL_GESTURE_STATE_NONE) 289 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
318 efl_gesture_timestamp_set(gesture, efl_gesture_touch_current_timestamp_get(touch_event)); 318 efl_gesture_timestamp_set(gesture, efl_gesture_touch_current_timestamp_get(touch_event));
319 efl_event_callback_call(target, gesture_type, gesture); 319 efl_event_callback_call(target, gesture_type, gesture);
320post_event: 320post_event:
321 /* avoid destroying touch tracking before gesture has ended */
322 if ((!rd->continues) &&
323 ((efl_gesture_touch_state_get(touch_event) != EFL_GESTURE_TOUCH_STATE_END) || efl_gesture_touch_points_count_get(touch_event)))
324 return;
321 //If the current event recognizes the gesture continuously, dont delete gesture. 325 //If the current event recognizes the gesture continuously, dont delete gesture.
322 if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) && 326 if (((recog_state == EFL_GESTURE_RECOGNIZER_RESULT_FINISH) || (recog_state == EFL_GESTURE_RECOGNIZER_RESULT_CANCEL)) &&
323 !rd->continues) 327 !rd->continues)
@@ -448,8 +452,6 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
448 Eina_List *l; 452 Eina_List *l;
449 Object_Gesture *object_gesture; 453 Object_Gesture *object_gesture;
450 Efl_Canvas_Gesture *gesture; 454 Efl_Canvas_Gesture *gesture;
451 Efl_Canvas_Gesture_Recognizer_Data *rd =
452 efl_data_scope_get(recognizer, EFL_CANVAS_GESTURE_RECOGNIZER_CLASS);
453 455
454 //If the widget is being deleted we should be careful not to 456 //If the widget is being deleted we should be careful not to
455 //Create a new state. 457 //Create a new state.
@@ -463,16 +465,6 @@ _get_state(Efl_Canvas_Gesture_Manager_Data *pd,
463 object_gesture->recognizer == recognizer && 465 object_gesture->recognizer == recognizer &&
464 object_gesture->type == type) 466 object_gesture->type == type)
465 { 467 {
466 //The gesture is already processed waiting for cleanup
467 if (((efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_FINISHED) ||
468 (efl_gesture_state_get(object_gesture->gesture) == EFL_GESTURE_STATE_CANCELED)) &&
469 (!rd->continues))
470 {
471 _cleanup_cached_gestures(pd, target, type, recognizer);
472 eina_hash_del(pd->m_object_events, &recognizer, NULL);
473 _cleanup_object(pd->m_gestures_to_delete);
474 return NULL;
475 }
476 return object_gesture->gesture; 468 return object_gesture->gesture;
477 } 469 }
478 } 470 }