zmike pushed a commit to branch efl-1.22. http://git.enlightenment.org/core/efl.git/commit/?id=57644b8d583a4ad1df00f9208f43b5e1ca739370
commit 57644b8d583a4ad1df00f9208f43b5e1ca739370 Author: Hosang Kim <[email protected]> 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) --
