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

Reply via email to