evas: put events related pointer into a cow to reduce evas_object fat.

This commit is contained in:
Cedric Bail 2017-06-12 11:41:25 -07:00
parent d1a5df7055
commit f69686ba40
6 changed files with 145 additions and 78 deletions

View File

@ -31,7 +31,7 @@ _efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_next(Efl_Object
if (!eina_clist_next(it->head, it->current)) return EINA_FALSE; if (!eina_clist_next(it->head, it->current)) return EINA_FALSE;
obj = EINA_CLIST_ENTRY(eina_clist_head(it->current), Evas_Object_Protected_Data, event.member); obj = EINA_CLIST_ENTRY(eina_clist_head(it->current), Evas_Object_Protected_Data, events->event.member);
if (data) *data = obj->object; if (data) *data = obj->object;
it->current = eina_clist_next(it->head, it->current); it->current = eina_clist_next(it->head, it->current);
@ -99,6 +99,14 @@ _stacking_verify(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *
} }
} }
static void
_child_add_after(Evas_Object_Protected_Data *a, Evas_Object_Events_Data *events)
{
EINA_COW_WRITE_BEGIN(evas_object_events_cow, a->events, Evas_Object_Events_Data, evs)
eina_clist_add_after(&evs->event.member, &events->event.member);
EINA_COW_WRITE_END(evas_object_events_cow, a->events, evs);
}
static void static void
_child_insert(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *obj) _child_insert(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *obj)
{ {
@ -107,38 +115,44 @@ _child_insert(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *obj
if (eina_clist_empty(&pd->contained)) if (eina_clist_empty(&pd->contained))
{ {
/* pd->rect case */ /* pd->rect case */
eina_clist_add_head(&pd->contained, &obj->event.member); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
eina_clist_add_head(&pd->contained, &events->event.member);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
return; return;
} }
if (pd->vis) _stacking_verify(pd, obj); if (pd->vis) _stacking_verify(pd, obj);
EINA_CLIST_FOR_EACH_ENTRY_REV(a, &pd->contained, Evas_Object_Protected_Data, event.member) EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
{ {
if (a->object == pd->rect) EINA_CLIST_FOR_EACH_ENTRY_REV(a, &pd->contained, Evas_Object_Protected_Data, events->event.member)
{ {
eina_clist_add_after(&a->event.member, &obj->event.member); if (a->object == pd->rect)
return;
}
if (a->layer->layer > obj->layer->layer) continue;
if (a->layer->layer < obj->layer->layer)
{
eina_clist_add_after(&a->event.member, &obj->event.member);
return;
}
EINA_INLIST_FOREACH(EINA_INLIST_GET(a->layer->objects), i)
{
if (a == i)
{ {
eina_clist_add_after(&a->event.member, &obj->event.member); _child_add_after(a, events);
return; return;
} }
if (obj == i) if (a->layer->layer > obj->layer->layer) continue;
if (a->layer->layer < obj->layer->layer)
{ {
eina_clist_add_before(&a->event.member, &obj->event.member); _child_add_after(a, events);
return; return;
} }
EINA_INLIST_FOREACH(EINA_INLIST_GET(a->layer->objects), i)
{
if (a == i)
{
_child_add_after(a, events);
return;
}
if (obj == i)
{
_child_add_after(a, events);
return;
}
}
} }
} }
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
} }
static void static void
@ -147,7 +161,10 @@ _efl_canvas_object_event_grabber_child_restack(void *data, const Efl_Event *even
Efl_Object_Event_Grabber_Data *pd = data; Efl_Object_Event_Grabber_Data *pd = data;
Evas_Object_Protected_Data *obj = efl_data_scope_get(event->object, EFL_CANVAS_OBJECT_CLASS); Evas_Object_Protected_Data *obj = efl_data_scope_get(event->object, EFL_CANVAS_OBJECT_CLASS);
eina_clist_remove(&obj->event.member); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
eina_clist_remove(&events->event.member);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
_child_insert(pd, obj); _child_insert(pd, obj);
} }
@ -197,10 +214,12 @@ _efl_canvas_object_event_grabber_efl_canvas_group_group_member_add(Eo *eo_obj, E
return; return;
} }
} }
if (obj->event.parent == eo_obj) return; if (obj->events->event.parent == eo_obj) return;
if (obj->smart.parent || obj->event.parent) evas_object_smart_member_del(member); if (obj->smart.parent || obj->events->event.parent) evas_object_smart_member_del(member);
obj->event.parent = eo_obj; EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->event.parent = eo_obj;
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
_child_insert(pd, obj); _child_insert(pd, obj);
efl_event_callback_add(member, EFL_EVENT_DEL, _efl_canvas_object_event_grabber_child_del, pd); efl_event_callback_add(member, EFL_EVENT_DEL, _efl_canvas_object_event_grabber_child_del, pd);
if (member != pd->rect) if (member != pd->rect)
@ -214,8 +233,12 @@ _efl_canvas_object_event_grabber_efl_canvas_group_group_member_del(Eo *eo_obj EI
efl_event_callback_del(member, EFL_EVENT_DEL, _efl_canvas_object_event_grabber_child_del, pd); efl_event_callback_del(member, EFL_EVENT_DEL, _efl_canvas_object_event_grabber_child_del, pd);
efl_event_callback_del(member, EFL_GFX_EVENT_RESTACK, _efl_canvas_object_event_grabber_child_restack, pd); efl_event_callback_del(member, EFL_GFX_EVENT_RESTACK, _efl_canvas_object_event_grabber_child_restack, pd);
eina_clist_remove(&obj->event.member); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
obj->event.parent = NULL; {
eina_clist_remove(&events->event.member);
events->event.parent = NULL;
}
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
} }
EOLIAN static void EOLIAN static void
@ -263,7 +286,7 @@ _efl_canvas_object_event_grabber_efl_gfx_visible_set(Eo *eo_obj EINA_UNUSED, Efl
{ {
Evas_Object_Protected_Data *obj; Evas_Object_Protected_Data *obj;
EINA_CLIST_FOR_EACH_ENTRY(obj, &pd->contained, Evas_Object_Protected_Data, event.member) EINA_CLIST_FOR_EACH_ENTRY(obj, &pd->contained, Evas_Object_Protected_Data, events->event.member)
if (obj->object != pd->rect) _stacking_verify(pd, obj); if (obj->object != pd->rect) _stacking_verify(pd, obj);
} }
pd->vis = !!set; pd->vis = !!set;
@ -287,11 +310,13 @@ _efl_canvas_object_event_grabber_restack(void *data, const Efl_Event *event)
evas_object_layer_set(pd->rect, evas_object_layer_get(event->object)); evas_object_layer_set(pd->rect, evas_object_layer_get(event->object));
evas_object_stack_below(pd->rect, event->object); evas_object_stack_below(pd->rect, event->object);
EINA_CLIST_FOR_EACH_ENTRY_SAFE(obj, nobj, &pd->contained, Evas_Object_Protected_Data, event.member) EINA_CLIST_FOR_EACH_ENTRY_SAFE(obj, nobj, &pd->contained, Evas_Object_Protected_Data, events->event.member)
{ {
if (obj->object == pd->rect) continue; if (obj->object == pd->rect) continue;
list = eina_list_append(list, obj); list = eina_list_append(list, obj);
eina_clist_remove(&obj->event.member); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
eina_clist_remove(&events->event.member);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
} }
EINA_LIST_FREE(list, obj) EINA_LIST_FREE(list, obj)
_child_insert(pd, obj); _child_insert(pd, obj);
@ -301,7 +326,7 @@ EOLIAN static Eo *
_efl_canvas_object_event_grabber_efl_object_constructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd) _efl_canvas_object_event_grabber_efl_object_constructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd)
{ {
Evas_Object_Protected_Data *obj; Evas_Object_Protected_Data *obj;
eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
efl_canvas_object_type_set(eo_obj, MY_CLASS_NAME_LEGACY); efl_canvas_object_type_set(eo_obj, MY_CLASS_NAME_LEGACY);
obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS); obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
@ -321,7 +346,7 @@ EOLIAN static void
_efl_canvas_object_event_grabber_efl_object_destructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd) _efl_canvas_object_event_grabber_efl_object_destructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd)
{ {
Evas_Object_Protected_Data *obj, *nobj; Evas_Object_Protected_Data *obj, *nobj;
EINA_CLIST_FOR_EACH_ENTRY_SAFE(obj, nobj, &pd->contained, Evas_Object_Protected_Data, event.member) EINA_CLIST_FOR_EACH_ENTRY_SAFE(obj, nobj, &pd->contained, Evas_Object_Protected_Data, events->event.member)
efl_canvas_group_member_del(eo_obj, obj->object); efl_canvas_group_member_del(eo_obj, obj->object);
efl_canvas_group_del(eo_obj); efl_canvas_group_del(eo_obj);
efl_destructor(efl_super(eo_obj, MY_CLASS)); efl_destructor(efl_super(eo_obj, MY_CLASS));

View File

@ -436,13 +436,13 @@ evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data
nothing_here: nothing_here:
if (!obj->no_propagate) if (!obj->no_propagate)
{ {
if ((obj->smart.parent || obj->event.parent) && (type != EVAS_CALLBACK_FREE) && if ((obj->smart.parent || obj->events->event.parent) && (type != EVAS_CALLBACK_FREE) &&
(type <= EVAS_CALLBACK_KEY_UP)) (type <= EVAS_CALLBACK_KEY_UP))
{ {
Evas_Object_Protected_Data *parent_obj; Evas_Object_Protected_Data *parent_obj;
Eo *parent; Eo *parent;
parent = obj->event.parent ?: obj->smart.parent; parent = obj->events->event.parent ?: obj->smart.parent;
parent_obj = efl_data_scope_get(parent, EFL_CANVAS_OBJECT_CLASS); parent_obj = efl_data_scope_get(parent, EFL_CANVAS_OBJECT_CLASS);
evas_object_event_callback_call(parent, parent_obj, type, event_info, event_id, efl_event_desc); evas_object_event_callback_call(parent, parent_obj, type, event_info, event_id, efl_event_desc);
} }

View File

@ -387,7 +387,7 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
obj; obj;
obj = _EINA_INLIST_CONTAINER(obj, EINA_INLIST_GET(obj)->prev)) obj = _EINA_INLIST_CONTAINER(obj, EINA_INLIST_GET(obj)->prev))
{ {
if (obj->event.parent) continue; if (obj->events->event.parent) continue;
in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source
#ifdef DDD_DO #ifdef DDD_DO
,&spaces ,&spaces
@ -398,7 +398,7 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
} }
else else
{ {
EINA_CLIST_FOR_EACH_ENTRY_SAFE_REV(obj, nobj, clist, Evas_Object_Protected_Data, event.member) EINA_CLIST_FOR_EACH_ENTRY_SAFE_REV(obj, nobj, clist, Evas_Object_Protected_Data, events->event.member)
{ {
in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source
#ifdef DDD_DO #ifdef DDD_DO

View File

@ -106,7 +106,10 @@ _evas_object_unfocus(Evas_Object_Protected_Data *obj, Efl_Input_Device *seat)
{ {
int event_id = _evas_event_counter; int event_id = _evas_event_counter;
obj->focused_by_seats = eina_list_remove(obj->focused_by_seats, seat); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->focused_by_seats = eina_list_remove(events->focused_by_seats, seat);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
_evas_focus_set(obj->object, seat, EINA_FALSE); _evas_focus_set(obj->object, seat, EINA_FALSE);
_evas_focus_dispatch_event(obj, seat, EINA_FALSE); _evas_focus_dispatch_event(obj, seat, EINA_FALSE);
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
@ -138,7 +141,7 @@ _efl_canvas_object_seat_focus_del(Eo *eo_obj,
obj->layer->evas->pending_default_focus_obj = NULL; obj->layer->evas->pending_default_focus_obj = NULL;
} }
EINA_LIST_FOREACH(obj->focused_by_seats, l, dev) EINA_LIST_FOREACH(obj->events->focused_by_seats, l, dev)
{ {
if (dev != seat) if (dev != seat)
continue; continue;
@ -184,7 +187,7 @@ _efl_canvas_object_seat_focus_add(Eo *eo_obj,
if (!efl_input_seat_event_filter_get(eo_obj, seat)) if (!efl_input_seat_event_filter_get(eo_obj, seat))
return EINA_FALSE; return EINA_FALSE;
if (_already_focused(obj->focused_by_seats, seat)) if (_already_focused(obj->events->focused_by_seats, seat))
goto end; goto end;
if (_evas_object_intercept_call_evas(obj, EVAS_OBJECT_INTERCEPT_CB_FOCUS_SET, if (_evas_object_intercept_call_evas(obj, EVAS_OBJECT_INTERCEPT_CB_FOCUS_SET,
@ -202,7 +205,10 @@ _efl_canvas_object_seat_focus_add(Eo *eo_obj,
efl_event_callback_add(seat, EFL_EVENT_DEL, _evas_focus_device_del_cb, obj); efl_event_callback_add(seat, EFL_EVENT_DEL, _evas_focus_device_del_cb, obj);
obj->focused_by_seats = eina_list_append(obj->focused_by_seats, seat); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->focused_by_seats = eina_list_append(events->focused_by_seats, seat);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
_evas_focus_set(eo_obj, seat, EINA_TRUE); _evas_focus_set(eo_obj, seat, EINA_TRUE);
_evas_focus_dispatch_event(obj, seat, EINA_TRUE); _evas_focus_dispatch_event(obj, seat, EINA_TRUE);
@ -225,7 +231,7 @@ _efl_canvas_object_seat_focus_check(Eo *eo_obj,
if (!seat) seat = _default_seat_get(eo_obj); if (!seat) seat = _default_seat_get(eo_obj);
EINA_LIST_FOREACH(obj->focused_by_seats, l, s) EINA_LIST_FOREACH(obj->events->focused_by_seats, l, s)
{ {
if (s == seat) if (s == seat)
return EINA_TRUE; return EINA_TRUE;
@ -253,7 +259,7 @@ _efl_canvas_object_seat_focus_get(Eo *eo_obj, Evas_Object_Protected_Data *obj)
return EINA_FALSE; return EINA_FALSE;
MAGIC_CHECK_END(); MAGIC_CHECK_END();
return eina_list_count(obj->focused_by_seats) ? EINA_TRUE : EINA_FALSE; return eina_list_count(obj->events->focused_by_seats) ? EINA_TRUE : EINA_FALSE;
} }
EOLIAN Eina_Bool EOLIAN Eina_Bool

View File

@ -35,12 +35,16 @@ static const Evas_Object_Protected_State default_state = {
static const Evas_Object_Mask_Data default_mask = { static const Evas_Object_Mask_Data default_mask = {
NULL, 0, 0, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE NULL, 0, 0, EINA_FALSE, EINA_FALSE, EINA_FALSE, EINA_FALSE
}; };
static const Evas_Object_Events_Data default_events = {
NULL, NULL, NULL, { NULL, { 0 } }
};
Eina_Cow *evas_object_proxy_cow = NULL; Eina_Cow *evas_object_proxy_cow = NULL;
Eina_Cow *evas_object_map_cow = NULL; Eina_Cow *evas_object_map_cow = NULL;
Eina_Cow *evas_object_state_cow = NULL; Eina_Cow *evas_object_state_cow = NULL;
Eina_Cow *evas_object_3d_cow = NULL; Eina_Cow *evas_object_3d_cow = NULL;
Eina_Cow *evas_object_mask_cow = NULL; Eina_Cow *evas_object_mask_cow = NULL;
Eina_Cow *evas_object_events_cow = NULL;
static Eina_Bool static Eina_Bool
_init_cow(void) _init_cow(void)
@ -52,21 +56,24 @@ _init_cow(void)
evas_object_state_cow = eina_cow_add("Evas Object State", sizeof (Evas_Object_Protected_State), 64, &default_state, EINA_FALSE); evas_object_state_cow = eina_cow_add("Evas Object State", sizeof (Evas_Object_Protected_State), 64, &default_state, EINA_FALSE);
evas_object_3d_cow = eina_cow_add("Evas Object 3D", sizeof (Evas_Object_3D_Data), 8, &default_proxy, EINA_TRUE); evas_object_3d_cow = eina_cow_add("Evas Object 3D", sizeof (Evas_Object_3D_Data), 8, &default_proxy, EINA_TRUE);
evas_object_mask_cow = eina_cow_add("Evas Mask Data", sizeof (Evas_Object_Mask_Data), 8, &default_mask, EINA_TRUE); evas_object_mask_cow = eina_cow_add("Evas Mask Data", sizeof (Evas_Object_Mask_Data), 8, &default_mask, EINA_TRUE);
evas_object_events_cow = eina_cow_add("Evas Events Data", sizeof (Evas_Object_Events_Data), 8, &default_events, EINA_TRUE);
if (!(evas_object_map_cow && evas_object_proxy_cow && evas_object_state_cow && if (!(evas_object_map_cow && evas_object_proxy_cow && evas_object_state_cow &&
evas_object_3d_cow && evas_object_mask_cow)) evas_object_3d_cow && evas_object_mask_cow && evas_object_events_cow))
{ {
eina_cow_del(evas_object_proxy_cow); eina_cow_del(evas_object_proxy_cow);
eina_cow_del(evas_object_map_cow); eina_cow_del(evas_object_map_cow);
eina_cow_del(evas_object_state_cow); eina_cow_del(evas_object_state_cow);
eina_cow_del(evas_object_3d_cow); eina_cow_del(evas_object_3d_cow);
eina_cow_del(evas_object_mask_cow); eina_cow_del(evas_object_mask_cow);
eina_cow_del(evas_object_events_cow);
evas_object_proxy_cow = NULL; evas_object_proxy_cow = NULL;
evas_object_map_cow = NULL; evas_object_map_cow = NULL;
evas_object_state_cow = NULL; evas_object_state_cow = NULL;
evas_object_3d_cow = NULL; evas_object_3d_cow = NULL;
evas_object_mask_cow = NULL; evas_object_mask_cow = NULL;
evas_object_events_cow = NULL;
return EINA_FALSE; return EINA_FALSE;
} }
@ -80,7 +87,7 @@ _evas_object_pointer_data_find(Evas_Object_Protected_Data *obj,
{ {
Evas_Object_Pointer_Data *pdata; Evas_Object_Pointer_Data *pdata;
EINA_INLIST_FOREACH(obj->pointer_grabs, pdata) EINA_INLIST_FOREACH(obj->events->pointer_grabs, pdata)
{ {
if (pdata->evas_pdata->pointer == pointer) if (pdata->evas_pdata->pointer == pointer)
return pdata; return pdata;
@ -113,8 +120,10 @@ _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj,
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);
efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL, efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL,
_evas_device_del_cb, obj); _evas_device_del_cb, obj);
obj->pointer_grabs = eina_inlist_remove(obj->pointer_grabs, EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
EINA_INLIST_GET(pdata)); events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata));
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
free(pdata); free(pdata);
} }
@ -128,8 +137,11 @@ _evas_object_pointer_data_add(Evas_Pointer_Data *evas_pdata,
EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL); EINA_SAFETY_ON_NULL_RETURN_VAL(pdata, NULL);
pdata->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB; pdata->pointer_mode = EVAS_OBJECT_POINTER_MODE_AUTOGRAB;
pdata->evas_pdata = evas_pdata; pdata->evas_pdata = evas_pdata;
obj->pointer_grabs = eina_inlist_append(obj->pointer_grabs, EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
EINA_INLIST_GET(pdata)); events->pointer_grabs = eina_inlist_append(events->pointer_grabs,
EINA_INLIST_GET(pdata));
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
efl_event_callback_priority_add(evas_pdata->pointer, EFL_EVENT_DEL, efl_event_callback_priority_add(evas_pdata->pointer, EFL_EVENT_DEL,
EFL_CALLBACK_PRIORITY_BEFORE, EFL_CALLBACK_PRIORITY_BEFORE,
_evas_device_del_cb, obj); _evas_device_del_cb, obj);
@ -177,6 +189,7 @@ _efl_canvas_object_efl_object_constructor(Eo *eo_obj, Evas_Object_Protected_Data
obj->prev = eina_cow_alloc(evas_object_state_cow); obj->prev = eina_cow_alloc(evas_object_state_cow);
obj->data_3d = eina_cow_alloc(evas_object_3d_cow); obj->data_3d = eina_cow_alloc(evas_object_3d_cow);
obj->mask = eina_cow_alloc(evas_object_mask_cow); obj->mask = eina_cow_alloc(evas_object_mask_cow);
obj->events = eina_cow_alloc(evas_object_events_cow);
evas_object_inject(eo_obj, obj, evas); evas_object_inject(eo_obj, obj, evas);
evas_object_callback_init(eo_obj, obj); evas_object_callback_init(eo_obj, obj);
@ -891,7 +904,7 @@ _efl_canvas_object_efl_input_interface_seat_event_filter_get(Eo *eo_obj EINA_UNU
//It means this object accept events from any seat. //It means this object accept events from any seat.
if (!obj->events_filter_enabled) if (!obj->events_filter_enabled)
return EINA_TRUE; return EINA_TRUE;
return eina_list_data_find(obj->events_whitelist, seat) ? return eina_list_data_find(obj->events->events_whitelist, seat) ?
EINA_TRUE : EINA_FALSE; EINA_TRUE : EINA_FALSE;
} }
@ -899,8 +912,11 @@ static void
_whitelist_events_device_remove_cb(void *data, const Efl_Event *event) _whitelist_events_device_remove_cb(void *data, const Efl_Event *event)
{ {
Evas_Object_Protected_Data *obj = data; Evas_Object_Protected_Data *obj = data;
obj->events_whitelist = eina_list_remove(obj->events_whitelist,
event->object); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->events_whitelist = eina_list_remove(events->events_whitelist,
event->object);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
} }
EOLIAN static void EOLIAN static void
@ -916,10 +932,10 @@ _efl_canvas_object_efl_input_interface_seat_event_filter_set(Eo *eo_obj,
obj->events_filter_enabled = EINA_TRUE; obj->events_filter_enabled = EINA_TRUE;
if (add) if (add)
{ {
if (eina_list_data_find(obj->events_whitelist, seat)) return; if (eina_list_data_find(obj->events->events_whitelist, seat)) return;
/* remove all previously focused seats, if any - it may happen /* remove all previously focused seats, if any - it may happen
since there wasn't a whitelist in place (no restrictions) */ since there wasn't a whitelist in place (no restrictions) */
if ((!obj->events_whitelist) && (obj->layer) && (obj->layer->evas)) if ((!obj->events->events_whitelist) && (obj->layer) && (obj->layer->evas))
{ {
const Eina_List *devices, *l; const Eina_List *devices, *l;
Efl_Input_Device *dev; Efl_Input_Device *dev;
@ -932,14 +948,20 @@ _efl_canvas_object_efl_input_interface_seat_event_filter_set(Eo *eo_obj,
efl_canvas_object_seat_focus_del(eo_obj, dev); efl_canvas_object_seat_focus_del(eo_obj, dev);
} }
} }
obj->events_whitelist = eina_list_append(obj->events_whitelist, seat); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->events_whitelist = eina_list_append(events->events_whitelist, seat);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
efl_event_callback_add(seat, EFL_EVENT_DEL, efl_event_callback_add(seat, EFL_EVENT_DEL,
_whitelist_events_device_remove_cb, obj); _whitelist_events_device_remove_cb, obj);
} }
else else
{ {
efl_canvas_object_seat_focus_del(eo_obj, seat); efl_canvas_object_seat_focus_del(eo_obj, seat);
obj->events_whitelist = eina_list_remove(obj->events_whitelist, seat); EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
events->events_whitelist = eina_list_remove(events->events_whitelist, seat);
EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
efl_event_callback_del(seat, EFL_EVENT_DEL, efl_event_callback_del(seat, EFL_EVENT_DEL,
_whitelist_events_device_remove_cb, obj); _whitelist_events_device_remove_cb, obj);
} }
@ -1010,24 +1032,30 @@ _efl_canvas_object_efl_object_destructor(Eo *eo_obj, Evas_Object_Protected_Data
edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS); edata = efl_data_scope_get(evas_object_evas_get(eo_obj), EVAS_CANVAS_CLASS);
evas_object_hide(eo_obj); evas_object_hide(eo_obj);
EINA_LIST_FREE (obj->focused_by_seats, dev)
EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events)
{ {
event_id = _evas_event_counter; EINA_LIST_FREE (events->focused_by_seats, dev)
efl_event_callback_del(dev, EFL_EVENT_DEL, {
_evas_focus_device_del_cb, obj); event_id = _evas_event_counter;
eina_hash_del_by_key(edata->focused_objects, &dev); efl_event_callback_del(dev, EFL_EVENT_DEL,
_evas_focus_dispatch_event(obj, dev, EINA_FALSE); _evas_focus_device_del_cb, obj);
if ((obj->layer) && (obj->layer->evas)) eina_hash_del_by_key(edata->focused_objects, &dev);
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); _evas_focus_dispatch_event(obj, dev, EINA_FALSE);
if ((obj->layer) && (obj->layer->evas))
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
}
EINA_INLIST_FREE(events->pointer_grabs, pdata)
_evas_object_pointer_grab_del(obj, pdata);
EINA_LIST_FREE(events->events_whitelist, dev)
efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj);
} }
EINA_INLIST_FREE(obj->pointer_grabs, pdata) EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events);
_evas_object_pointer_grab_del(obj, pdata);
event_id = _evas_object_event_new(); event_id = _evas_object_event_new();
evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_DEL, NULL, event_id, NULL); evas_object_event_callback_call(eo_obj, obj, EVAS_CALLBACK_DEL, NULL, event_id, NULL);
if ((obj->layer) && (obj->layer->evas)) if ((obj->layer) && (obj->layer->evas))
_evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id);
EINA_LIST_FREE(obj->events_whitelist, dev)
efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj);
if (obj->name) evas_object_name_set(eo_obj, NULL); if (obj->name) evas_object_name_set(eo_obj, NULL);
if (obj->layer) if (obj->layer)
{ {
@ -1737,7 +1765,7 @@ _hide(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj)
{ {
Evas_Object_Pointer_Data *obj_pdata; Evas_Object_Pointer_Data *obj_pdata;
EINA_INLIST_FOREACH(obj->pointer_grabs, obj_pdata) EINA_INLIST_FOREACH(obj->events->pointer_grabs, obj_pdata)
{ {
if (!obj_pdata->mouse_grabbed && if (!obj_pdata->mouse_grabbed &&
evas_object_is_in_output_rect(eo_obj, obj, obj_pdata->evas_pdata->seat->x, evas_object_is_in_output_rect(eo_obj, obj, obj_pdata->evas_pdata->seat->x,

View File

@ -86,6 +86,7 @@ typedef struct _Evas_Post_Callback Evas_Post_Callback;
typedef struct _Evas_Coord_Touch_Point Evas_Coord_Touch_Point; typedef struct _Evas_Coord_Touch_Point Evas_Coord_Touch_Point;
typedef struct _Evas_Object_Proxy_Data Evas_Object_Proxy_Data; typedef struct _Evas_Object_Proxy_Data Evas_Object_Proxy_Data;
typedef struct _Evas_Object_Map_Data Evas_Object_Map_Data; typedef struct _Evas_Object_Map_Data Evas_Object_Map_Data;
typedef struct _Evas_Object_Events_Data Evas_Object_Events_Data;
typedef struct _Evas_Proxy_Render_Data Evas_Proxy_Render_Data; typedef struct _Evas_Proxy_Render_Data Evas_Proxy_Render_Data;
typedef struct _Evas_Object_3D_Data Evas_Object_3D_Data; typedef struct _Evas_Object_3D_Data Evas_Object_3D_Data;
typedef struct _Evas_Object_Mask_Data Evas_Object_Mask_Data; typedef struct _Evas_Object_Mask_Data Evas_Object_Mask_Data;
@ -1093,6 +1094,23 @@ struct _Evas_Object_Mask_Data
Eina_Bool is_scaled : 1; Eina_Bool is_scaled : 1;
}; };
struct _Evas_Object_Events_Data
{
/*
The list below contain the seats (Efl.Input.Devices) which this
object allows events to be reported (Mouse, Keybord and focus events).
*/
Eina_List *events_whitelist;
Eina_List *focused_by_seats;
Eina_Inlist *pointer_grabs;
struct {
Evas_Object *parent;
Eina_Clist member;
} event;
};
struct _Evas_Object_Protected_State struct _Evas_Object_Protected_State
{ {
Evas_Object_Protected_Data *clipper; Evas_Object_Protected_Data *clipper;
@ -1148,11 +1166,6 @@ struct _Evas_Object_Protected_Data
Eina_List *grabs; Eina_List *grabs;
Eina_Inlist *callbacks; Eina_Inlist *callbacks;
/*
The list below contain the seats (Efl.Input.Devices) which this
object allows events to be reported (Mouse, Keybord and focus events).
*/
Eina_List *events_whitelist;
struct { struct {
Eina_List *clipees; Eina_List *clipees;
@ -1171,18 +1184,12 @@ struct _Evas_Object_Protected_Data
Evas_Object_Protected_Data *parent_object_data; Evas_Object_Protected_Data *parent_object_data;
} smart; } smart;
struct {
Evas_Object *parent;
Eina_Clist member;
} event;
// Eina_Cow pointer be careful when writing to it // Eina_Cow pointer be careful when writing to it
const Evas_Object_Proxy_Data *proxy; const Evas_Object_Proxy_Data *proxy;
const Evas_Object_Map_Data *map; const Evas_Object_Map_Data *map;
const Evas_Object_3D_Data *data_3d; const Evas_Object_3D_Data *data_3d;
const Evas_Object_Mask_Data *mask; const Evas_Object_Mask_Data *mask;
Eina_List *focused_by_seats; const Evas_Object_Events_Data *events;
Eina_Inlist *pointer_grabs;
// Pointer to the Evas_Object itself // Pointer to the Evas_Object itself
Evas_Object *object; Evas_Object *object;
@ -2078,6 +2085,7 @@ extern Eina_Cow *evas_object_image_pixels_cow;
extern Eina_Cow *evas_object_image_load_opts_cow; extern Eina_Cow *evas_object_image_load_opts_cow;
extern Eina_Cow *evas_object_image_state_cow; extern Eina_Cow *evas_object_image_state_cow;
extern Eina_Cow *evas_object_mask_cow; extern Eina_Cow *evas_object_mask_cow;
extern Eina_Cow *evas_object_events_cow;
# define EINA_COW_STATE_WRITE_BEGIN(Obj, Write, State) \ # define EINA_COW_STATE_WRITE_BEGIN(Obj, Write, State) \
EINA_COW_WRITE_BEGIN(evas_object_state_cow, Obj->State, \ EINA_COW_WRITE_BEGIN(evas_object_state_cow, Obj->State, \