hermet pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=c006589607c78dd18ed1634f0696d63db0f47727
commit c006589607c78dd18ed1634f0696d63db0f47727 Author: Hosang Kim <hosang12....@samsung.com> Date: Fri Apr 26 13:24:01 2019 +0900 evas_events: fix grab count does not become 0 with proxy object. 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 | 67 +++++++++++++++++++++++----------- src/lib/evas/canvas/evas_object_main.c | 33 ++++++++++++++++- 2 files changed, 78 insertions(+), 22 deletions(-) diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c index bff66c81d9..ca2a903ae4 100644 --- a/src/lib/evas/canvas/evas_events.c +++ b/src/lib/evas/canvas/evas_events.c @@ -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) { diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index ad0eaf82d6..07193790ba 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -111,6 +111,33 @@ _evas_device_del_cb(void *data, const Efl_Event *ev) _evas_object_pointer_grab_del(obj, pdata); } +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) --