Dear all,
SeungGyun and I found infinite loop in _elm_win_obj_callback_del.
It calls evas_object_del() to remove evas objects in evas.
However sometimes, there're several objects (which its reference count
is greater than 1) that aren't deleted.
To fix that, I added two evas apis, and changed some logic in elm_win.c
+EAPI Evas_Object *
+evas_object_hier_above_get(const Evas_Object *obj);
+EAPI Evas_Object *
+evas_object_hier_below_get(const Evas_Object *obj);
In evas, evas_object_{above,below}_get() are existed.
But i'm not sure that.
In object deletion, we need to consider smart parent relation?
If it shouldn't be, i think my approach is right way.
Otherwise, the two apis aren't needed to apply. then just replace to
evas_object_{above,below}_get() in elm_win.c
Most of analysis is done by SeungGyun Kim. And I coded to resolve it.
Thanks.
Index: evas/src/lib/Evas.h
===================================================================
--- evas/src/lib/Evas.h (리ë¹ì 69696)
+++ evas/src/lib/Evas.h (ìì
ì¬ë³¸)
@@ -5986,6 +5986,47 @@ EAPI Evas_Object *evas_object_bottom_get
EAPI Evas_Object *evas_object_top_get (const Evas *e)
EINA_WARN_UNUSED_RESULT EINA_ARG_NONNULL(1);
/**
+ * Get the Evas object hierarchically right above @p obj
+ *
+ * @param obj an #Evas_Object
+ * @return the #Evas_Object directly above @p obj, if any, or @c NULL,
+ * if none
+ *
+ * This function will traverse layers in its search, if there are
+ * objects on layers above the one @p obj is placed at.
+ * It doesn't consider about smart attributes. Most of cases, you need to use
+ * evas_object_above_get().
+ *
+ * @see evas_object_below_get()
+ * @see evas_object_above_get()
+ * @see evas_object_hier_below_get()
+ *
+ */
+
+EAPI Evas_Object *
+evas_object_hier_above_get(const Evas_Object *obj);
+
+/**
+ * Get the Evas object hierarchically right below @p obj
+ *
+ * @param obj an #Evas_Object
+ * @return the #Evas_Object directly below @p obj, if any, or @c NULL,
+ * if none
+ *
+ * This function will traverse layers in its search, if there are
+ * objects on layers below the one @p obj is placed at.
+ * It doesn't consider about smart attributes. Most of cases, you need to use
+ * evas_object_below_get().
+ *
+ * @see evas_object_below_get()
+ * @see evas_object_above_get()
+ * @see evas_object_hier_above_get()
+ */
+
+EAPI Evas_Object *
+evas_object_hier_below_get(const Evas_Object *obj);
+
+/**
* @}
*/
Index: evas/src/lib/canvas/evas_stack.c
===================================================================
--- evas/src/lib/canvas/evas_stack.c (리ë¹ì 69696)
+++ evas/src/lib/canvas/evas_stack.c (ìì
ì¬ë³¸)
@@ -336,7 +336,35 @@ evas_object_below_get(const Evas_Object *obj)
return NULL;
}
+EAPI Evas_Object *
+evas_object_hier_above_get(const Evas_Object *obj)
+{
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return NULL;
+ MAGIC_CHECK_END();
+ obj = evas_object_above_get_internal(obj);
+ while (obj)
+ {
+ if (!obj->delete_me) return (Evas_Object *)obj;
+ obj = evas_object_above_get_internal(obj);
+ }
+ return NULL;
+}
+EAPI Evas_Object *
+evas_object_hier_below_get(const Evas_Object *obj)
+{
+ MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
+ return NULL;
+ MAGIC_CHECK_END();
+ obj = evas_object_below_get_internal(obj);
+ while (obj)
+ {
+ if (!obj->delete_me) return (Evas_Object *)obj;
+ obj = evas_object_below_get_internal(obj);
+ }
+ return NULL;
+}
EAPI Evas_Object *
evas_object_bottom_get(const Evas *e)
Index: elementary/src/lib/elm_win.c
===================================================================
--- elementary/src/lib/elm_win.c (리비전 69696)
+++ elementary/src/lib/elm_win.c (작업 사본)
@@ -613,6 +613,7 @@ _elm_win_obj_callback_del(void *data, Evas *e, Eva
{
Elm_Win *win = data;
Evas_Object *child;
+ Evas_Object *delobj;
if (win->parent)
{
@@ -634,15 +635,19 @@ _elm_win_obj_callback_del(void *data, Evas *e, Eva
if (win->shot.timer) ecore_timer_del(win->shot.timer);
evas_object_event_callback_del_full(win->win_obj, EVAS_CALLBACK_DEL,
_elm_win_obj_callback_del, win);
- while (((child = evas_object_bottom_get(win->evas))) &&
- (child != obj))
+ child = evas_object_bottom_get(win->evas);
+ while (child && child != obj)
{
- evas_object_del(child);
+ delobj = child;
+ child = evas_object_hier_above_get(child);
+ evas_object_del(delobj);
}
- while (((child = evas_object_top_get(win->evas))) &&
- (child != obj))
+ child = evas_object_top_get(win->evas);
+ while (child && child != obj)
{
- evas_object_del(child);
+ delobj = child;
+ child = evas_object_hier_below_get(child);
+ evas_object_del(delobj);
}
#ifdef HAVE_ELEMENTARY_X
if (win->client_message_handler)
------------------------------------------------------------------------------
This SF email is sponsosred by:
Try Windows Azure free for 90 days Click Here
http://p.sf.net/sfu/sfd2d-msazure
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel