evas_events: fix grab count does not become 0 with proxy object.
authorHosang Kim <hosang12.kim@samsung.com>
Fri, 26 Apr 2019 04:24:01 +0000 (13:24 +0900)
committerWoochanlee <wc0917.lee@samsung.com>
Tue, 30 Apr 2019 00:55:25 +0000 (09:55 +0900)
Summary:
1. src_event_in should not be initialized when grabbed object exists.

2. when object of pointer grab is deleted and if object has proxy,
   proxy object of pointer grab should be deleted together.

Reviewers: Hermet

Reviewed By: Hermet

Subscribers: zmike, cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D8698

src/lib/evas/canvas/evas_events.c
src/lib/evas/canvas/evas_object_main.c

index c1839b6..d7e7228 100644 (file)
@@ -460,6 +460,7 @@ _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
    Eina_Vector2 point;
    int addgrab = 0;
    int no_rep = 0;
+   int srcgrab = 0;
 
    if (obj->delete_me || src->delete_me || e->is_frozen) return;
 
@@ -472,31 +473,52 @@ _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
    ev->source = eo_obj;
    ev->tool = 0;
 
-   EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
+   EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
      {
-        if (proxy_write->src_event_in)
-        proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
+        Evas_Object_Pointer_Data *obj_pdata;
 
-        if (src->is_smart)
+        child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
+        obj_pdata = _evas_object_pointer_data_get(pdata, child);
+        if (!obj_pdata)
           {
-             proxy_write->src_event_in = _evas_event_object_list_raw_in_get
-               (eo_e, proxy_write->src_event_in,
-                evas_object_smart_members_get_direct(eo_src), NULL,
-                NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
-         }
-       else if (src->is_event_parent)
-         {
-            proxy_write->src_event_in = _evas_event_object_list_raw_in_get
-               (eo_e, proxy_write->src_event_in,
-                NULL, evas_object_event_grabber_members_list(eo_src),
-                NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
-         }
-       else
-         proxy_write->src_event_in = eina_list_append(proxy_write->src_event_in, eo_src);
+             ERR("Could not find the object pointer data for device %p",
+                 ev->device);
+             continue;
+          }
+        srcgrab += obj_pdata->mouse_grabbed;
      }
-   EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
 
-   if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
+   if (srcgrab == 0)
+     {
+        EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
+          {
+             if (proxy_write->src_event_in)
+               proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
+
+             if (src->is_smart)
+               {
+                  proxy_write->src_event_in = _evas_event_object_list_raw_in_get
+                     (eo_e, proxy_write->src_event_in,
+                      evas_object_smart_members_get_direct(eo_src), NULL,
+                      NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
+               }
+             else if (src->is_event_parent)
+               {
+                  proxy_write->src_event_in = _evas_event_object_list_raw_in_get
+                     (eo_e, proxy_write->src_event_in,
+                      NULL, evas_object_event_grabber_members_list(eo_src),
+                      NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
+               }
+             else
+               proxy_write->src_event_in = eina_list_append(proxy_write->src_event_in, eo_src);
+          }
+        EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
+     }
+
+   if (pdata->seat->mouse_grabbed == 0)
+     {
+        if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
+     }
 
    EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
      {
@@ -960,7 +982,10 @@ _evas_event_source_multi_down_events(Evas_Object_Protected_Data *obj, Evas_Publi
    ev->source = obj->object;
    ev->action = EFL_POINTER_ACTION_DOWN;
 
-   if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
+   if (pdata->seat->mouse_grabbed == 0)
+     {
+        if (pdata->seat->downs > 1) addgrab = pdata->seat->downs - 1;
+     }
 
    EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
      {
index ad0eaf8..0719379 100644 (file)
@@ -112,6 +112,33 @@ _evas_device_del_cb(void *data, const Efl_Event *ev)
 }
 
 static void
+_evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
+                            Evas_Object_Pointer_Data *pdata)
+{
+   Evas_Object *eo_src = _evas_object_image_source_get(obj->object);
+   Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
+   Eina_List *copy = eina_list_clone(src->proxy->src_event_in);
+   Eina_List *l;
+   Evas_Object *eo_child;
+   EINA_LIST_FOREACH(copy, l, eo_child)
+     {
+        Evas_Object_Protected_Data *child = efl_data_scope_get(eo_child, EFL_CANVAS_OBJECT_CLASS);
+        if (!child) continue;
+        Evas_Object_Pointer_Data *obj_pdata = _evas_object_pointer_data_get(pdata->evas_pdata, child);
+        if (!obj_pdata)
+          continue;
+        if (obj_pdata->mouse_grabbed > 0)
+          {
+             pdata->evas_pdata->seat->mouse_grabbed -= obj_pdata->mouse_grabbed;
+             obj_pdata->mouse_grabbed = 0;
+             EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
+                proxy_write->src_event_in = eina_list_remove(proxy_write->src_event_in, eo_child);
+             EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
+          }
+     }
+}
+
+static void
 _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
                               Evas_Object_Pointer_Data *pdata)
 {
@@ -119,7 +146,11 @@ _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
      pdata->evas_pdata->seat->mouse_grabbed -= pdata->mouse_grabbed;
    if (((pdata->mouse_in) || (pdata->mouse_grabbed > 0)) &&
        (obj->layer) && (obj->layer->evas))
-     pdata->evas_pdata->seat->object.in = eina_list_remove(pdata->evas_pdata->seat->object.in, obj->object);
+     {
+        pdata->evas_pdata->seat->object.in = eina_list_remove(pdata->evas_pdata->seat->object.in, obj->object);
+        if (obj->proxy->is_proxy && obj->proxy->src_events)
+          _evas_object_proxy_grab_del(obj, pdata);
+     }
    efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL,
                           _evas_device_del_cb, obj->object);
    EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)