Introduced tracking the leading finger of the drag gesture 03/282803/2
authorMaria Bialota <m.bialota@samsung.com>
Fri, 7 Oct 2022 20:30:54 +0000 (22:30 +0200)
committerMaria Bialota <m.bialota@samsung.com>
Tue, 11 Oct 2022 15:30:09 +0000 (17:30 +0200)
This patch solves the problem of incorrect ending of tap & hold
gesture in Screen Reader mode and introduces leading finger change
during the gesture.

When Screen Reader is running and user performs tap+tap&hold gesture,
drag action can be performed. In current solution in case a user
touches the screen with a second finger during the course of the drag
gesture and releases the first finger before releasing the second
finger, the tap&hold gesture is not concluded properly - the drag
action is suspended without a proper closing with mouse up event.

This patch solves this issue and additionally provides possibility
of changing fingers many times within one drag action.

Change-Id: Ice65689d50883c9ef44a83695d04db974b4d7055
(cherry picked from commit c8989870a04b8c3cbd84f374c6fdbe2f5505c703)

src/e_screen_reader_gestures.c

index fbda1359d8dce9134db36fe5cdfbc0d24f446bc8..2d5e55ef196b3de74579c242c89d69edb19cc2d3 100644 (file)
@@ -90,9 +90,13 @@ struct _Cover
         int n_taps;
         Eina_Bool double_tap;
         Ecore_Event_Mouse_Button *ev_down, *ev_multi_down;
-        Eina_Bool drag_start;
+        Eina_Bool drag_start; // indicates if tap&hold gesture is ongoing
         int drag_x_delta;
         int drag_y_delta;
+        int n_fingers; // number of fingers currently touching the screen
+        int initiating_finger_id; // ID of a finger that initiated the tap&hold gesture
+        int primary_finger_id; // ID of a finger that is currently leading the tap&hold gesture
+        int secondary_finger_id; // ID of a finger that may become the next leading finger in the tap&hold gesture
    } tap_n_hold_gesture_data;
 
    struct {
@@ -1020,6 +1024,11 @@ _hover_event_emit(Cover *cov, gesture_state_e state)
         _emit_mouse_move_event(cov->tap_n_hold_gesture_data.ev_down);
         cov->tap_n_hold_gesture_data.ev_down->multi.radius += MAGIC_NUMBER;
         cov->tap_n_hold_gesture_data.drag_start = EINA_TRUE;
+        cover->tap_n_hold_gesture_data.n_fingers = cov->hover_gesture.n_fingers;
+        cover->tap_n_hold_gesture_data.initiating_finger_id = cov->hover_gesture.finger[0];
+        cover->tap_n_hold_gesture_data.primary_finger_id = cov->hover_gesture.finger[0];
+        //currently we don't consider secondary finger being predefined at the beginning of tap&hold gesture
+        cover->tap_n_hold_gesture_data.secondary_finger_id = cover->tap_n_hold_gesture_data.primary_finger_id;
         ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, cov->tap_n_hold_gesture_data.ev_down, NULL, NULL);
         if (cov->tap_gesture_data.tap_type == TWO_FINGERS_GESTURE)
           {
@@ -1471,9 +1480,10 @@ static Eina_Bool
 _mouse_move(int type, Ecore_Event_Mouse_Move *event)
 {
    Ecore_Event_Mouse_Move *ev = event;
-   // During draging ignore events from other fingers than the finger that initiated the drag
-   if (cover->tap_n_hold_gesture_data.drag_start && ev->multi.device > 0)
+   // During draging ignore events from other fingers than the primary finger of the tap&hold gesture
+   if (cover->tap_n_hold_gesture_data.drag_start && ev->multi.device != cover->tap_n_hold_gesture_data.primary_finger_id)
      {
+        cover->tap_n_hold_gesture_data.secondary_finger_id = ev->multi.device;
         return EINA_FALSE;
      }
 
@@ -1499,6 +1509,7 @@ _mouse_move(int type, Ecore_Event_Mouse_Move *event)
                   ev->y += cover->tap_n_hold_gesture_data.drag_y_delta;
                   ev->root.x += cover->tap_n_hold_gesture_data.drag_x_delta;
                   ev->root.y += cover->tap_n_hold_gesture_data.drag_y_delta;
+                  ev->multi.device = cover->tap_n_hold_gesture_data.initiating_finger_id;
                }
              else
                {
@@ -1543,9 +1554,14 @@ _mouse_button_up(int type, Ecore_Event_Mouse_Button *event)
         event->multi.radius -= MAGIC_NUMBER;
         return EINA_TRUE;
      }
-   // During draging ignore events from other fingers than the finger that initiated the drag
-   if (cover->tap_n_hold_gesture_data.drag_start && ev->multi.device > 0)
+   // During draging change the leading finger if number of fingers involved was more than 1
+   if (cover->tap_n_hold_gesture_data.drag_start && cover->tap_n_hold_gesture_data.n_fingers > 1 )
      {
+        cover->tap_n_hold_gesture_data.n_fingers--;
+        if(event->multi.device == cover->tap_n_hold_gesture_data.primary_finger_id)
+        {
+          cover->tap_n_hold_gesture_data.primary_finger_id = cover->tap_n_hold_gesture_data.secondary_finger_id;
+        }
         return EINA_FALSE;
      }
 
@@ -1559,6 +1575,7 @@ _mouse_button_up(int type, Ecore_Event_Mouse_Button *event)
           }
         memcpy(ev_up, ev, sizeof(Ecore_Event_Mouse_Button));
         ev_up->multi.radius += MAGIC_NUMBER;
+        ev_up->multi.device = cover->tap_n_hold_gesture_data.initiating_finger_id;
 
         if (cover->up_timer)
           ecore_timer_del(cover->up_timer);
@@ -1577,6 +1594,7 @@ _mouse_button_up(int type, Ecore_Event_Mouse_Button *event)
              ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev_multi_up, NULL, NULL);
           }
         cover->tap_n_hold_gesture_data.drag_start = EINA_FALSE;
+        cover->tap_n_hold_gesture_data.n_fingers = 0;
         g_context->highlighted_object_x = -1;
         g_context->highlighted_object_y = -1;
      }
@@ -1607,9 +1625,11 @@ _mouse_button_down(int type, Ecore_Event_Mouse_Button *event)
         ev->multi.radius -= MAGIC_NUMBER;
         return EINA_TRUE;
      }
-   // During draging ignore events from other fingers than the finger that initiated the drag
-   if (cover->tap_n_hold_gesture_data.drag_start && ev->multi.device > 0)
+   // During draging ignore events from other fingers than the primary finger of the tap&hold gesture
+   if (cover->tap_n_hold_gesture_data.drag_start && ev->multi.device != cover->tap_n_hold_gesture_data.primary_finger_id)
      {
+        // register that the number of fingers touching screen increased
+        cover->tap_n_hold_gesture_data.n_fingers++;
         return EINA_FALSE;
      }
    cover->n_taps++;