From 42519cb54258a9d82a136eb781c2c726a2efd6f8 Mon Sep 17 00:00:00 2001 From: Hosang Kim Date: Fri, 26 Apr 2019 13:24:01 +0900 Subject: [PATCH] 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 c1839b6..d7e7228 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 ad0eaf8..0719379 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -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) -- 2.7.4