aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/evas
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/evas')
-rw-r--r--src/lib/evas/Evas_Eo.h3
-rw-r--r--src/lib/evas/Evas_Legacy.h26
-rw-r--r--src/lib/evas/canvas/efl_canvas_object_event_grabber.c350
-rw-r--r--src/lib/evas/canvas/efl_canvas_object_event_grabber.eo38
-rw-r--r--src/lib/evas/canvas/evas_callbacks.c10
-rw-r--r--src/lib/evas/canvas/evas_events.c110
-rw-r--r--src/lib/evas/include/evas_private.h10
7 files changed, 522 insertions, 25 deletions
diff --git a/src/lib/evas/Evas_Eo.h b/src/lib/evas/Evas_Eo.h
index 38d1e3a351..858104228e 100644
--- a/src/lib/evas/Evas_Eo.h
+++ b/src/lib/evas/Evas_Eo.h
@@ -66,6 +66,9 @@
#endif /* EFL_EO_API_SUPPORT */
#if defined(EFL_BETA_API_SUPPORT) && defined(EFL_EO_API_SUPPORT)
+
+#include "canvas/efl_canvas_object_event_grabber.eo.h"
+
/**
* @defgroup Evas_3D Evas 3D Extensions
*
diff --git a/src/lib/evas/Evas_Legacy.h b/src/lib/evas/Evas_Legacy.h
index a98aae4441..ac6c429ce4 100644
--- a/src/lib/evas/Evas_Legacy.h
+++ b/src/lib/evas/Evas_Legacy.h
@@ -7666,3 +7666,29 @@ EAPI void evas_object_text_filter_program_set(Evas_Object *obj, const char *code
* @since 1.18
*/
EAPI void evas_object_text_filter_source_set(Evas_Object *obj, const char *name, Evas_Object *source) EINA_DEPRECATED;
+
+#ifdef EFL_BETA_API_SUPPORT
+/**
+ * Creates a new smart rectangle object on the given Evas @p e canvas.
+ *
+ * @param e The given canvas.
+ * @return The created object handle.
+ *
+ * This provides a smart version of the typical "event rectangle",
+ * which allows objects to set this as their parent and route events
+ * to a group of objects. Events will not propagate to non-member objects
+ * below this object.
+ *
+ * Adding members is done just like a normal smart object, using
+ * efl_canvas_group_member_add (Eo API) or evas_object_smart_member_add (legacy).
+ *
+ * Child objects are not modified in any way, unlike other types of smart objects.
+ *
+ * It is a user error for any child objects to be stacked above the event
+ * grabber parent while the event grabber is visible.
+ * A critical error will be raised if this is detected at any point.
+ *
+ * @since 1.20
+ */
+EAPI Evas_Object *evas_object_event_grabber_add(Evas *e);
+#endif
diff --git a/src/lib/evas/canvas/efl_canvas_object_event_grabber.c b/src/lib/evas/canvas/efl_canvas_object_event_grabber.c
new file mode 100644
index 0000000000..12d882dcd2
--- /dev/null
+++ b/src/lib/evas/canvas/efl_canvas_object_event_grabber.c
@@ -0,0 +1,350 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+#include "efl_canvas_object_event_grabber.eo.h"
+
+#define MY_CLASS EFL_CANVAS_OBJECT_EVENT_GRABBER_CLASS
+#define MY_CLASS_NAME "Efl_Object_Event_Grabber"
+#define MY_CLASS_NAME_LEGACY "evas_object_event_grabber"
+
+
+struct _Efl_Object_Event_Grabber_Data
+{
+ Eo *rect;
+ Eina_Clist contained;
+ Eina_Bool vis : 1;
+};
+
+typedef struct Efl_Object_Event_Grabber_Iterator
+{
+ Eina_Iterator iterator;
+
+ Eina_Clist *head;
+ Eina_Clist *current;
+ Eo *parent;
+} Efl_Object_Event_Grabber_Iterator;
+
+
+static Eina_Bool
+_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_next(Efl_Object_Event_Grabber_Iterator *it, void **data)
+{
+ Evas_Object_Protected_Data *obj;
+
+ 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);
+ if (data) *data = obj->object;
+
+ it->current = eina_clist_next(it->head, it->current);
+
+ return EINA_TRUE;
+}
+
+static Evas_Object *
+_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_get_container(Efl_Object_Event_Grabber_Iterator *it)
+{
+ return it->parent;
+}
+
+static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_free(Efl_Object_Event_Grabber_Iterator *it)
+{
+ efl_unref(it->parent);
+ free(it);
+}
+
+EOLIAN static Eina_Iterator*
+_efl_canvas_object_event_grabber_efl_canvas_group_group_children_iterate(const Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd)
+{
+ Efl_Object_Event_Grabber_Iterator *it;
+
+ if (eina_clist_empty(&pd->contained)) return NULL;
+
+ it = calloc(1, sizeof(Efl_Object_Event_Grabber_Iterator));
+ if (!it) return NULL;
+
+ EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
+ it->parent = efl_ref(eo_obj);
+ it->head = it->current = &pd->contained;
+
+ it->iterator.next = FUNC_ITERATOR_NEXT(_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_next);
+ it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_get_container);
+ it->iterator.free = FUNC_ITERATOR_FREE(_efl_canvas_object_event_grabber_efl_canvas_group_group_iterator_free);
+
+ return &it->iterator;
+}
+
+static void
+_stacking_verify(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *obj)
+{
+ Eo *grabber;
+ Evas_Object_Protected_Data *gobj, *i;
+
+ grabber = efl_parent_get(pd->rect);
+ gobj = efl_data_scope_get(grabber, EFL_CANVAS_OBJECT_CLASS);
+ if (obj->layer->layer > gobj->layer->layer)
+ {
+ CRI("Cannot stack child object above event grabber object!");
+ return;
+ }
+ if (obj->layer != gobj->layer) return;
+
+ EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(gobj->layer->objects), i)
+ {
+ if (i == gobj) break;
+ if (i == obj)
+ {
+ CRI("Cannot stack child object above event grabber object!");
+ return;
+ }
+ }
+}
+
+static void
+_child_insert(Efl_Object_Event_Grabber_Data *pd, Evas_Object_Protected_Data *obj)
+{
+ Evas_Object_Protected_Data *a, *i;
+
+ if (eina_clist_empty(&pd->contained))
+ {
+ /* pd->rect case */
+ eina_clist_add_head(&pd->contained, &obj->event.member);
+ return;
+ }
+
+ if (pd->vis) _stacking_verify(pd, obj);
+ EINA_CLIST_FOR_EACH_ENTRY_REV(a, &pd->contained, Evas_Object_Protected_Data, event.member)
+ {
+ if (a->object == pd->rect)
+ {
+ eina_clist_add_after(&a->event.member, &obj->event.member);
+ 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);
+ return;
+ }
+ if (obj == i)
+ {
+ eina_clist_add_before(&a->event.member, &obj->event.member);
+ return;
+ }
+ }
+ }
+}
+
+static void
+_efl_canvas_object_event_grabber_child_restack(void *data, const Efl_Event *event)
+{
+ Efl_Object_Event_Grabber_Data *pd = data;
+ Evas_Object_Protected_Data *obj = efl_data_scope_get(event->object, EFL_CANVAS_OBJECT_CLASS);
+
+ eina_clist_remove(&obj->event.member);
+ _child_insert(pd, obj);
+}
+
+static void
+_efl_canvas_object_event_grabber_child_del(void *data, const Efl_Event *event)
+{
+ Efl_Object_Event_Grabber_Data *pd = data;
+
+ efl_canvas_group_member_del(efl_parent_get(pd->rect), event->object);
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_member_add(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd, Eo *member)
+{
+ Evas_Object_Protected_Data *obj = efl_data_scope_get(member, EFL_CANVAS_OBJECT_CLASS);
+ Evas_Object_Protected_Data *smart = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+
+ EINA_SAFETY_ON_NULL_RETURN(obj);
+ EINA_SAFETY_ON_NULL_RETURN(smart);
+
+ if (member != pd->rect)
+ {
+ if (obj->delete_me)
+ {
+ CRI("Adding deleted object %p to smart obj %p", member, eo_obj);
+ return;
+ }
+ if (smart->delete_me)
+ {
+ CRI("Adding object %p to deleted smart obj %p", member, eo_obj);
+ return;
+ }
+ if (!smart->layer)
+ {
+ CRI("No evas surface associated with smart object (%p)", eo_obj);
+ return;
+ }
+ if (!obj->layer)
+ {
+ CRI("No evas surface associated with member object (%p)", member);
+ return;
+ }
+ if ((obj->layer && smart->layer) &&
+ (obj->layer->evas != smart->layer->evas))
+ {
+ CRI("Adding object %p from Evas (%p) from another Evas (%p)", member, obj->layer->evas, smart->layer->evas);
+ return;
+ }
+ }
+ if (obj->event.parent == eo_obj) return;
+
+ if (obj->smart.parent || obj->event.parent) evas_object_smart_member_del(member);
+ obj->event.parent = eo_obj;
+ _child_insert(pd, obj);
+ efl_event_callback_add(member, EFL_EVENT_DEL, _efl_canvas_object_event_grabber_child_del, pd);
+ if (member != pd->rect)
+ efl_event_callback_add(member, EFL_GFX_EVENT_RESTACK, _efl_canvas_object_event_grabber_child_restack, pd);
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_member_del(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd EINA_UNUSED, Eo *member)
+{
+ Evas_Object_Protected_Data *obj = efl_data_scope_get(member, EFL_CANVAS_OBJECT_CLASS);
+
+ 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);
+ eina_clist_remove(&obj->event.member);
+ obj->event.parent = NULL;
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_change(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd EINA_UNUSED)
+{}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_calculate(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd EINA_UNUSED)
+{}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_canvas_group_group_need_recalculate_set(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd EINA_UNUSED, Eina_Bool set EINA_UNUSED)
+{}
+
+EOLIAN static Eina_Bool
+_efl_canvas_object_event_grabber_efl_canvas_group_group_need_recalculate_get(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd EINA_UNUSED)
+{
+ return EINA_FALSE;
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_gfx_position_set(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd, int x, int y)
+{
+ efl_gfx_position_set(efl_super(eo_obj, MY_CLASS), x, y);
+ efl_gfx_position_set(pd->rect, x, y);
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_gfx_size_set(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd, int w, int h)
+{
+ efl_gfx_size_set(efl_super(eo_obj, MY_CLASS), w, h);
+ efl_gfx_size_set(pd->rect, w, h);
+}
+
+EOLIAN static Eina_Bool
+_efl_canvas_object_event_grabber_efl_gfx_visible_get(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd)
+{
+ return pd->vis;
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_gfx_visible_set(Eo *eo_obj EINA_UNUSED, Efl_Object_Event_Grabber_Data *pd, Eina_Bool set)
+{
+ if (set)
+ {
+ Evas_Object_Protected_Data *obj;
+
+ EINA_CLIST_FOR_EACH_ENTRY(obj, &pd->contained, Evas_Object_Protected_Data, event.member)
+ if (obj->object != pd->rect) _stacking_verify(pd, obj);
+ }
+ pd->vis = !!set;
+ efl_gfx_visible_set(pd->rect, set);
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_gfx_stack_layer_set(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd, short l)
+{
+ efl_gfx_stack_layer_set(efl_super(eo_obj, MY_CLASS), l);
+ efl_gfx_stack_layer_set(pd->rect, l);
+}
+
+static void
+_efl_canvas_object_event_grabber_restack(void *data, const Efl_Event *event)
+{
+ Efl_Object_Event_Grabber_Data *pd = data;
+ Eina_List *list = NULL;
+ Evas_Object_Protected_Data *obj, *nobj;
+
+ evas_object_layer_set(pd->rect, evas_object_layer_get(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)
+ {
+ if (obj->object == pd->rect) continue;
+ list = eina_list_append(list, obj);
+ eina_clist_remove(&obj->event.member);
+ }
+ EINA_LIST_FREE(list, obj)
+ _child_insert(pd, obj);
+}
+
+EOLIAN static Eo *
+_efl_canvas_object_event_grabber_efl_object_constructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd)
+{
+ Evas_Object_Protected_Data *obj;
+
+ eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
+ efl_canvas_object_type_set(eo_obj, MY_CLASS_NAME_LEGACY);
+ obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
+ obj->is_event_parent = 1;
+ obj->is_smart = 0;
+ eina_clist_init(&pd->contained);
+ efl_event_callback_add(eo_obj, EFL_GFX_EVENT_RESTACK, _efl_canvas_object_event_grabber_restack, pd);
+ pd->rect = evas_object_rectangle_add(efl_parent_get(eo_obj));
+ evas_object_pointer_mode_set(pd->rect, EVAS_OBJECT_POINTER_MODE_NOGRAB);
+ efl_parent_set(pd->rect, eo_obj);
+ efl_canvas_group_member_add(eo_obj, pd->rect);
+ evas_object_color_set(pd->rect, 0, 0, 0, 0);
+ return eo_obj;
+}
+
+EOLIAN static void
+_efl_canvas_object_event_grabber_efl_object_destructor(Eo *eo_obj, Efl_Object_Event_Grabber_Data *pd)
+{
+ Evas_Object_Protected_Data *obj, *nobj;
+ EINA_CLIST_FOR_EACH_ENTRY_SAFE(obj, nobj, &pd->contained, Evas_Object_Protected_Data, event.member)
+ efl_canvas_group_member_del(eo_obj, obj->object);
+ efl_canvas_group_del(eo_obj);
+ efl_destructor(efl_super(eo_obj, MY_CLASS));
+}
+
+static void
+_efl_canvas_object_event_grabber_class_constructor(Efl_Class *klass)
+{
+ evas_smart_legacy_type_register(MY_CLASS_NAME_LEGACY, klass);
+}
+
+const Eina_Clist *
+evas_object_event_grabber_members_list(const Eo *eo_obj)
+{
+ Efl_Object_Event_Grabber_Data *pd = efl_data_scope_get(eo_obj, MY_CLASS);
+ return &pd->contained;
+}
+
+EAPI Evas_Object *
+evas_object_event_grabber_add(Evas *eo_e)
+{
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(efl_isa(eo_e, EVAS_CANVAS_CLASS), NULL);
+ return efl_add(MY_CLASS, eo_e, efl_canvas_object_legacy_ctor(efl_added));
+}
+
+#include "efl_canvas_object_event_grabber.eo.c"
diff --git a/src/lib/evas/canvas/efl_canvas_object_event_grabber.eo b/src/lib/evas/canvas/efl_canvas_object_event_grabber.eo
new file mode 100644
index 0000000000..9389c876df
--- /dev/null
+++ b/src/lib/evas/canvas/efl_canvas_object_event_grabber.eo
@@ -0,0 +1,38 @@
+class Efl.Canvas.Object.Event.Grabber (Efl.Canvas.Group)
+{
+ [[Low-level rectangle object.
+
+ This provides a smart version of the typical "event rectangle",
+ which allows objects to set this as their parent and route events
+ to a group of objects. Events will not propagate to non-member objects
+ below this object.
+
+ Adding members is done just like a normal smart object, using
+ efl_canvas_group_member_add (Eo API) or evas_object_smart_member_add (legacy).
+
+ Child objects are not modified in any way, unlike other types of smart objects.
+
+ It is a user error for any child objects to be stacked above the event
+ grabber parent while the event grabber is visible.
+ A critical error will be raised if this is detected at any point.
+
+ @since 1.20
+ ]]
+ data: Efl_Object_Event_Grabber_Data;
+ legacy_prefix: evas_object_event_grabber;
+ implements {
+ class.constructor;
+ Efl.Object.constructor;
+ Efl.Object.destructor;
+ Efl.Canvas.Group.group_member_add;
+ Efl.Canvas.Group.group_member_del;
+ Efl.Canvas.Group.group_children_iterate;
+ Efl.Canvas.Group.group_calculate;
+ Efl.Canvas.Group.group_change;
+ Efl.Canvas.Group.group_need_recalculate { get; set; }
+ Efl.Gfx.position { set; }
+ Efl.Gfx.size { set; }
+ Efl.Gfx.visible { get; set; }
+ Efl.Gfx.Stack.layer { set; }
+ }
+}
diff --git a/src/lib/evas/canvas/evas_callbacks.c b/src/lib/evas/canvas/evas_callbacks.c
index e3d2643bad..822baa2133 100644
--- a/src/lib/evas/canvas/evas_callbacks.c
+++ b/src/lib/evas/canvas/evas_callbacks.c
@@ -436,11 +436,15 @@ evas_object_event_callback_call(Evas_Object *eo_obj, Evas_Object_Protected_Data
nothing_here:
if (!obj->no_propagate)
{
- if ((obj->smart.parent) && (type != EVAS_CALLBACK_FREE) &&
+ if ((obj->smart.parent || obj->event.parent) && (type != EVAS_CALLBACK_FREE) &&
(type <= EVAS_CALLBACK_KEY_UP))
{
- Evas_Object_Protected_Data *smart_parent = efl_data_scope_get(obj->smart.parent, EFL_CANVAS_OBJECT_CLASS);
- evas_object_event_callback_call(obj->smart.parent, smart_parent, type, event_info, event_id, efl_event_desc);
+ Evas_Object_Protected_Data *parent_obj;
+ Eo *parent;
+
+ parent = obj->event.parent ?: obj->smart.parent;
+ 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_unwalk(e);
diff --git a/src/lib/evas/canvas/evas_events.c b/src/lib/evas/canvas/evas_events.c
index 0fc4850ad5..d4b728d307 100644
--- a/src/lib/evas/canvas/evas_events.c
+++ b/src/lib/evas/canvas/evas_events.c
@@ -10,7 +10,7 @@ int _evas_event_counter = 0;
static Eina_List *
_evas_event_object_list_in_get(Evas *eo_e, Eina_List *in,
- const Eina_Inlist *list, Evas_Object *stop,
+ const Eina_Inlist *list, const Eina_Clist *clist, Evas_Object *stop,
int x, int y, int *no_rep, Eina_Bool source);
/* FIXME: use eina_list_clone */
@@ -118,7 +118,7 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
#endif
return in;
}
- if (!obj->cur->visible) return in;
+ if ((!obj->cur->visible) && (!obj->is_event_parent)) return in;
// XXX: this below DYNAMICALLY calculates the current clip rect
// by walking clippers to each parent clipper until there are
// no more of them. this is a necessary hack because cache.clip
@@ -229,8 +229,8 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
if (evas_object_is_source_invisible(eo_obj, obj)) return in;
}
if ((obj->delete_me == 0) &&
- ((source) || ((obj->cur->visible) && (!obj->clip.clipees) &&
- (evas_object_clippers_is_visible(eo_obj, obj)))))
+ ((source) || ((obj->cur->visible || obj->is_event_parent) && (!obj->clip.clipees) &&
+ (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj)))))
{
if (obj->is_smart)
{
@@ -259,6 +259,7 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
in = _evas_event_object_list_in_get
(eo_e, in,
evas_object_smart_members_get_direct(eo_obj),
+ NULL,
stop,
obj->cur->geometry.x + obj->map->cur.map->mx,
obj->cur->geometry.y + obj->map->cur.map->my,
@@ -285,7 +286,7 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
obj->cur->geometry.y <= y &&
obj->cur->geometry.y + obj->cur->geometry.h >= y))
in = _evas_event_object_list_in_get
- (eo_e, in, evas_object_smart_members_get_direct(eo_obj),
+ (eo_e, in, evas_object_smart_members_get_direct(eo_obj), NULL,
stop, x, y, &norep, source);
}
if (norep)
@@ -301,6 +302,25 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
}
}
}
+ else if (obj->is_event_parent)
+ {
+ int norep = 0;
+ in = _evas_event_object_list_in_get(eo_e, in,
+ NULL, evas_object_event_grabber_members_list(eo_obj),
+ stop, x, y, &norep, source);
+ if (norep)
+ {
+ if (!obj->repeat_events)
+ {
+ *no_rep = 1;
+#ifdef DDD_DO
+ (*spaces)--;
+ DDD("***** NO REP1 *****\n");
+#endif
+ return in;
+ }
+ }
+ }
else
{
Evas_Object_Protected_Data *clip = obj->cur->clipper;
@@ -347,23 +367,27 @@ _evas_event_object_list_raw_in_get_single(Evas *eo_e, Evas_Object_Protected_Data
static Eina_List *
_evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
- const Eina_Inlist *list, Evas_Object *stop,
+ const Eina_Inlist *list, const Eina_Clist *clist, Evas_Object *stop,
int x, int y, int *no_rep, Eina_Bool source)
{
Evas_Object_Protected_Data *obj = NULL;
+ Evas_Object_Protected_Data *nobj;
#ifdef DDD_DO
static int spaces = 0;
#endif
- if (!list) return in;
+ if ((!list) && (!clist)) return in;
#ifdef DDD_DO
spaces++;
#endif
+ if (list)
+ {
for (obj = _EINA_INLIST_CONTAINER(obj, eina_inlist_last(list));
obj;
obj = _EINA_INLIST_CONTAINER(obj, EINA_INLIST_GET(obj)->prev))
{
+ if (obj->event.parent) continue;
in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source
#ifdef DDD_DO
,&spaces
@@ -371,6 +395,19 @@ _evas_event_object_list_raw_in_get(Evas *eo_e, Eina_List *in,
);
if (*no_rep) return in;
}
+ }
+ else
+ {
+ EINA_CLIST_FOR_EACH_ENTRY_SAFE_REV(obj, nobj, clist, Evas_Object_Protected_Data, event.member)
+ {
+ in = _evas_event_object_list_raw_in_get_single(eo_e, obj, in, stop, x, y, no_rep, source
+#ifdef DDD_DO
+ ,&spaces
+#endif
+ );
+ if (*no_rep) return in;
+ }
+ }
*no_rep = 0;
#ifdef DDD_DO
spaces--;
@@ -454,7 +491,14 @@ _evas_event_source_mouse_down_events(Evas_Object *eo_obj, Evas *eo_e,
{
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),
+ 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
@@ -571,7 +615,8 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
continue;
}
- if ((evas_object_clippers_is_visible(eo_child, child) ||
+ if ((child->is_event_parent ||
+ evas_object_clippers_is_visible(eo_child, child) ||
obj_pdata->mouse_grabbed) &&
(!evas_event_passes_through(eo_child, child)) &&
(!evas_event_freezes_through(eo_child, child)) &&
@@ -630,6 +675,12 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
{
int no_rep = 0;
ins = _evas_event_object_list_raw_in_get(eo_e, ins, 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)
+ {
+ int no_rep = 0;
+ ins = _evas_event_object_list_raw_in_get(eo_e, ins, NULL, evas_object_event_grabber_members_list(eo_src),
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
}
else
@@ -653,7 +704,8 @@ _evas_event_source_mouse_move_events(Evas_Object *eo_obj, Evas *eo_e,
ev->cur = curpt;
if (evas_object_is_in_output_rect(eo_child, child,
ev->cur.x, ev->cur.y, 1, 1) &&
- (evas_object_clippers_is_visible(eo_child, child) ||
+ (child->is_event_parent ||
+ evas_object_clippers_is_visible(eo_child, child) ||
obj_pdata->mouse_grabbed) &&
eina_list_data_find(ins, eo_child) &&
(!evas_event_passes_through(eo_child, child)) &&
@@ -1047,7 +1099,7 @@ _evas_event_source_multi_move_events(Evas_Object_Protected_Data *obj, Evas_Publi
ev->device);
continue;
}
- if (((evas_object_clippers_is_visible(eo_child, child)) ||
+ if (((child->is_event_parent || evas_object_clippers_is_visible(eo_child, child)) ||
((obj_pdata->mouse_grabbed) &&
(!evas_event_passes_through(eo_child, child)) &&
(!evas_event_freezes_through(eo_child, child)) &&
@@ -1070,7 +1122,14 @@ _evas_event_source_multi_move_events(Evas_Object_Protected_Data *obj, Evas_Publi
{
int no_rep = 0;
ins = _evas_event_object_list_raw_in_get
- (eo_e, ins, evas_object_smart_members_get_direct(eo_src), NULL,
+ (eo_e, ins, evas_object_smart_members_get_direct(eo_src), NULL, NULL,
+ ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
+ }
+ if (src->is_event_parent)
+ {
+ int no_rep = 0;
+ ins = _evas_event_object_list_raw_in_get
+ (eo_e, ins, NULL, evas_object_event_grabber_members_list(eo_src), NULL,
ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
}
else
@@ -1090,7 +1149,7 @@ _evas_event_source_multi_move_events(Evas_Object_Protected_Data *obj, Evas_Publi
}
if (evas_object_is_in_output_rect(eo_child, child, ev->cur.x, ev->cur.y, 1, 1) &&
- (evas_object_clippers_is_visible(eo_child, child) ||
+ (child->is_event_parent || evas_object_clippers_is_visible(eo_child, child) ||
obj_pdata->mouse_grabbed) &&
eina_list_data_find(ins, eo_child) &&
(!evas_event_passes_through(eo_child, child)) &&
@@ -1156,6 +1215,13 @@ _evas_event_source_mouse_in_events(Evas_Object *eo_obj, Evas *eo_e,
{
int no_rep = 0;
ins = _evas_event_object_list_raw_in_get(eo_e, ins, 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)
+ {
+ int no_rep = 0;
+ ins = _evas_event_object_list_raw_in_get(eo_e, ins, NULL, evas_object_event_grabber_members_list(eo_src),
NULL, ev->cur.x, ev->cur.y, &no_rep, EINA_TRUE);
}
@@ -1260,10 +1326,10 @@ _evas_event_source_mouse_out_events(Evas_Object *eo_obj, Evas *eo_e,
static Eina_List *
_evas_event_object_list_in_get(Evas *eo_e, Eina_List *in,
- const Eina_Inlist *list, Evas_Object *stop,
+ const Eina_Inlist *list, const Eina_Clist *clist, Evas_Object *stop,
int x, int y, int *no_rep, Eina_Bool source)
{
- return _evas_event_object_list_raw_in_get(eo_e, in, list, stop, x, y,
+ return _evas_event_object_list_raw_in_get(eo_e, in, list, clist, stop, x, y,
no_rep, source);
}
@@ -1282,7 +1348,7 @@ _evas_event_objects_event_list_no_frozen_check(Evas *eo_e, Evas_Object *stop, in
int no_rep = 0;
D("############################# check layer %i\n", lay->layer);
in = _evas_event_object_list_in_get(eo_e, in,
- EINA_INLIST_GET(lay->objects),
+ EINA_INLIST_GET(lay->objects), NULL,
stop, x, y, &no_rep, EINA_FALSE);
if (no_rep) return in;
}
@@ -2070,7 +2136,7 @@ _canvas_event_feed_mouse_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Da
continue;
}
if ((!e->is_frozen) &&
- (evas_object_clippers_is_visible(eo_obj, obj) ||
+ (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) ||
obj_pdata->mouse_grabbed) &&
(!evas_event_passes_through(eo_obj, obj)) &&
(!evas_event_freezes_through(eo_obj, obj)) &&
@@ -2163,7 +2229,7 @@ _canvas_event_feed_mouse_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Da
// evas_object_clip_recalc(eo_obj);
if ((!e->is_frozen) &&
evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1) &&
- (evas_object_clippers_is_visible(eo_obj, obj) ||
+ (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) ||
obj_pdata->mouse_grabbed) &&
eina_list_data_find(ins, eo_obj) &&
(!evas_event_passes_through(eo_obj, obj)) &&
@@ -2277,7 +2343,7 @@ nogrep:
Evas_Object_Protected_Data *below_obj = efl_data_scope_get(eo_below_obj, EFL_CANVAS_OBJECT_CLASS);
int norep = 0;
ins = _evas_event_object_list_raw_in_get(eo_e, NULL,
- EINA_INLIST_GET(below_obj), NULL,
+ EINA_INLIST_GET(below_obj), NULL, NULL,
pdata->seat->x, pdata->seat->y,
&norep, EINA_FALSE);
}
@@ -2306,7 +2372,7 @@ nogrep:
// evas_object_clip_recalc(eo_obj);
if ((!e->is_frozen) &&
evas_object_is_in_output_rect(eo_obj, obj, x, y, 1, 1) &&
- (evas_object_clippers_is_visible(eo_obj, obj) ||
+ (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) ||
obj_pdata->mouse_grabbed) &&
eina_list_data_find(newin, eo_obj) &&
(!evas_event_passes_through(eo_obj, obj)) &&
@@ -2955,7 +3021,7 @@ _canvas_event_feed_multi_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Da
ev->device);
continue;
}
- if ((evas_object_clippers_is_visible(eo_obj, obj) ||
+ if ((obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) ||
obj_pdata->mouse_grabbed) &&
(!evas_event_passes_through(eo_obj, obj)) &&
(!evas_event_freezes_through(eo_obj, obj)) &&
@@ -2999,7 +3065,7 @@ _canvas_event_feed_multi_move_internal(Evas_Public_Data *e, Efl_Input_Pointer_Da
// FIXME: i don't think we need this
// evas_object_clip_recalc(eo_obj);
if (evas_object_is_in_output_rect(eo_obj, obj, ev->cur.x, ev->cur.y, 1, 1) &&
- (evas_object_clippers_is_visible(eo_obj, obj) ||
+ (obj->is_event_parent || evas_object_clippers_is_visible(eo_obj, obj) ||
obj_pdata->mouse_grabbed) &&
eina_list_data_find(ins, eo_obj) &&
(!evas_event_passes_through(eo_obj, obj)) &&
diff --git a/src/lib/evas/include/evas_private.h b/src/lib/evas/include/evas_private.h
index 6189390698..fea6c3a81d 100644
--- a/src/lib/evas/include/evas_private.h
+++ b/src/lib/evas/include/evas_private.h
@@ -92,6 +92,8 @@ typedef struct _Evas_Object_Mask_Data Evas_Object_Mask_Data;
typedef struct _Evas_Object_Pointer_Data Evas_Object_Pointer_Data;
typedef struct _Evas_Smart_Data Evas_Smart_Data;
+typedef struct _Efl_Object_Event_Grabber_Data Efl_Object_Event_Grabber_Data;
+
typedef struct _Evas_Object_Protected_State Evas_Object_Protected_State;
typedef struct _Evas_Object_Protected_Data Evas_Object_Protected_Data;
@@ -1169,6 +1171,11 @@ struct _Evas_Object_Protected_Data
Evas_Object_Protected_Data *parent_object_data;
} smart;
+ struct {
+ Evas_Object *parent;
+ Eina_Clist member;
+ } event;
+
// Eina_Cow pointer be careful when writing to it
const Evas_Object_Proxy_Data *proxy;
const Evas_Object_Map_Data *map;
@@ -1206,6 +1213,7 @@ struct _Evas_Object_Protected_Data
Eina_Bool changed : 1;
Eina_Bool restack : 1;
Eina_Bool is_smart : 1;
+ Eina_Bool is_event_parent : 1;
Eina_Bool pass_events : 1;
Eina_Bool store : 1;
@@ -1689,6 +1697,8 @@ void evas_object_smart_render_cache_clear(Evas_Object *eo_obj);
void *evas_object_smart_render_cache_get(const Evas_Object *eo_obj);
void evas_object_smart_render_cache_set(Evas_Object *eo_obj, void *data);
+const Eina_Clist *evas_object_event_grabber_members_list(const Eo *eo_obj);
+
const Eina_Inlist *evas_object_smart_members_get_direct(const Evas_Object *obj);
void _efl_canvas_group_group_members_all_del(Evas_Object *eo_obj);
void _evas_object_smart_clipped_smart_move_internal(Evas_Object *eo_obj, Evas_Coord x, Evas_Coord y);