evas_event: remove child object from list when child is deleted.
authorHosang Kim <hosang12.kim@samsung.com>
Wed, 12 Feb 2020 09:31:07 +0000 (18:31 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Thu, 13 Feb 2020 21:47:54 +0000 (06:47 +0900)
Event list of source object is not managed when child object is
deleted. So sometimes event list have dangling pointers.

Add Efl_Event_Del callback for managing child object.

Change-Id: Ia4c16994d34c58b2a2e50274e8c658774abcf7f2

src/lib/evas/canvas/evas_events.c
src/lib/evas/canvas/evas_object_main.c
src/lib/evas/include/evas_private.h

index b35627c..3a3fb52 100644 (file)
@@ -486,6 +486,48 @@ _evas_event_legacy_device_get(Eo *evas, Eina_Bool mouse)
    return dev;
 }
 
+//TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+void
+_source_child_del_cb(void *data, const Efl_Event *event)
+{
+   Eo *eo_src = data;
+   Eo *obj = event->object;
+   Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
+
+   if (!src || src->delete_me) return;
+
+   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, obj);
+   EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
+}
+
+static void
+_source_child_callback_add(Evas_Object *eo_src)
+{
+   Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
+   Evas_Object *eo_child;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
+     {
+        efl_event_callback_add(eo_child, EFL_EVENT_DEL, _source_child_del_cb, eo_src);
+     }
+}
+
+static void
+_source_child_callback_del(Evas_Object *eo_src)
+{
+   Evas_Object_Protected_Data *src = efl_data_scope_get(eo_src, EFL_CANVAS_OBJECT_CLASS);
+   Evas_Object *eo_child;
+   Eina_List *l;
+
+   EINA_LIST_FOREACH(src->proxy->src_event_in, l, eo_child)
+     {
+        efl_event_callback_del(eo_child, EFL_EVENT_DEL, _source_child_del_cb, eo_src);
+     }
+}
+//
+
 static void
 _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
                                      Efl_Input_Pointer *parent_ev,
@@ -539,7 +581,12 @@ _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
         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);
+               {
+                  //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+                  _source_child_callback_del(eo_src);
+                  proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
+                  //
+               }
 
              if (src->is_smart)
                {
@@ -559,6 +606,10 @@ _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
                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);
+
+        //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+        _source_child_callback_add(eo_src);
+        //
      }
 
    if (pdata->seat->mouse_grabbed == 0)
@@ -736,6 +787,9 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
 
                   _evas_event_havemap_adjust_f(child, &ev->cur, &ev->prev, obj_pdata->mouse_grabbed);
 
+                  //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+                  efl_event_callback_del(eo_child, EFL_EVENT_DEL, _source_child_del_cb, eo_src);
+                  //
                   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);
@@ -849,12 +903,20 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
 
         if (pdata->seat->mouse_grabbed == 0)
           {
+             //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+             _source_child_callback_del(eo_src);
+             //
+
              EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
                {
                   eina_list_free(proxy_write->src_event_in);
                   proxy_write->src_event_in = ins;
                }
              EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
+
+             //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+             _source_child_callback_add(eo_src);
+             //
           }
         else
           {
@@ -1301,12 +1363,20 @@ _evas_event_source_multi_move_events(Evas_Object_Protected_Data *obj, Evas_Publi
         eina_list_free(copy);
         if (pdata->seat->mouse_grabbed == 0)
           {
+             //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+             _source_child_callback_del(eo_src);
+             //
+
              EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
                {
                   eina_list_free(proxy_write->src_event_in);
                   proxy_write->src_event_in = ins;
                }
              EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
+
+             //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+             _source_child_callback_add(eo_src);
+             //
           }
         else
           eina_list_free(ins);
@@ -1399,6 +1469,10 @@ _evas_event_source_mouse_in_events(Evas_Object *eo_obj, Evas *eo_e,
           }
      }
 
+   //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+   _source_child_callback_del(eo_src);
+   //
+
    EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
      {
        eina_list_free(proxy_write->src_event_in);
@@ -1406,6 +1480,10 @@ _evas_event_source_mouse_in_events(Evas_Object *eo_obj, Evas *eo_e,
      }
    EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
 
+   //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+   _source_child_callback_add(eo_src);
+   //
+
    efl_unref(evt);
 }
 
@@ -1468,6 +1546,10 @@ _evas_event_source_mouse_out_events(Evas_Object *eo_obj, Evas *eo_e,
      }
    eina_list_free(copy);
 
+   //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+   _source_child_callback_del(eo_src);
+   //
+
    EINA_COW_WRITE_BEGIN(evas_object_proxy_cow, src->proxy, Evas_Object_Proxy_Data, proxy_write)
      proxy_write->src_event_in = eina_list_free(proxy_write->src_event_in);
    EINA_COW_WRITE_END(evas_object_proxy_cow, src->proxy, proxy_write);
index bb38f84..518027a 100644 (file)
@@ -117,6 +117,9 @@ _evas_object_proxy_grab_del(Evas_Object_Protected_Data *obj,
           {
              pdata->evas_pdata->seat->mouse_grabbed -= obj_pdata->mouse_grabbed;
              obj_pdata->mouse_grabbed = 0;
+             //TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+             efl_event_callback_del(eo_child, EFL_EVENT_DEL, _source_child_del_cb, eo_src);
+             //
              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);
index a0bad34..55b318c 100755 (executable)
@@ -1739,6 +1739,9 @@ Eina_Bool _efl_canvas_object_clipper_unset_block(Eo *eo_obj, Evas_Object_Protect
 Eina_Bool _efl_canvas_object_efl_gfx_entity_size_set_block(Eo *eo_obj, Evas_Object_Protected_Data *obj, Evas_Coord w, Evas_Coord h, Eina_Bool internal);
 
 void _evas_focus_device_invalidate_cb(void *data, const Efl_Event *ev);
+//TIZEN_ONLY(20200213): remove child object from list when child is deleted.
+void _source_child_del_cb(void *data, const Efl_Event *ev);
+//
 
 /* Node functions. */
 void evas_canvas3d_node_traverse(Evas_Canvas3D_Node *from, Evas_Canvas3D_Node *to, Evas_Canvas3D_Node_Traverse_Type type, Eina_Bool skip, Evas_Canvas3D_Node_Func func, void *data);