elementary/ctxpopup - [E-devel] [PATCH] [Elementary] Fix memory leak and callback...
authorChunEon Park <hermet@hermet.pe.kr>
Fri, 18 Jan 2013 09:07:03 +0000 (09:07 +0000)
committerChunEon Park <hermet@hermet.pe.kr>
Fri, 18 Jan 2013 09:07:03 +0000 (09:07 +0000)
Hello everyone,

There are two issues with ctxpopup:
- Memory leak: Elm_Ctxpopup_Item is used but not deleted.
- Incorrect callback function: returned object and event_info are list object and item
(should be ctxpopup object and item).

I would like to send a patch to fix above issues.
I also provide the patch for backporting.
Please review them.

Best Regards,
Thiep

Signed-Off-By: Theip Ha<thiep.ha@samsung.com>
SVN revision: 82968

ChangeLog
NEWS
src/bin/test_ctxpopup.c
src/lib/elc_ctxpopup.c
src/lib/elm_widget_ctxpopup.h

index b4c2a93..4567c0f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
         * when parent of ctxpopup is resized, ctxpopup calls dismissed signal
 
+2013-01-18  Thiep Ha (thiep.ha@samsung.com)
+
+        * Fix memory leak of the ctxpopup and callback function to be a ctxpoup obj is delivered to.
+
+
 
diff --git a/NEWS b/NEWS
index e7abbca..116125b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -127,6 +127,7 @@ Fixes:
    * Fix index refill bug when autohide disabled.
    * Fix thumb theme hook.
    * when parent of ctxpopup is resized, ctxpopup calls dismissed signal.
+   * Fix memory leak of the ctxpopup and callback function to be ctxpopup obj is delivered to.
 
 Removals:
 
index f5061be..7dd22f0 100644 (file)
@@ -283,6 +283,48 @@ _list_item_cb6(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSE
    evas_object_smart_callback_add(btn, "clicked", _btn_clicked, ctxpopup);
 }
 
+static void
+_ctxpopup_item_disable_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
+{
+   printf("ctxpopup item selected: %s\n",
+          elm_object_item_text_get(event_info));
+
+   Elm_Object_Item *it = (Elm_Object_Item *)event_info;
+   elm_object_item_disabled_set(it, EINA_TRUE);
+}
+
+static void
+_ctxpopup_item_delete_cb(void *data __UNUSED__, Evas_Object *obj, void *event_info)
+{
+   printf("ctxpopup item selected: %s\n",
+          elm_object_item_text_get(event_info));
+
+   evas_object_del(obj);
+}
+
+static void
+_list_item_cb7(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   Evas_Object *ctxpopup;
+   Evas_Coord x,y;
+
+   ctxpopup = elm_ctxpopup_add(obj);
+   evas_object_smart_callback_add(ctxpopup,
+                                  "dismissed",
+                                  _dismissed,
+                                  NULL);
+
+   elm_ctxpopup_item_append(ctxpopup, "Disable this item", NULL, _ctxpopup_item_disable_cb, ctxpopup);
+   elm_ctxpopup_item_append(ctxpopup, "Delete this ctxpopup", NULL, _ctxpopup_item_delete_cb, ctxpopup);
+   elm_ctxpopup_item_append(ctxpopup, "Another item", NULL, _ctxpopup_item_cb, NULL);
+
+   evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x, &y);
+   evas_object_size_hint_max_set(ctxpopup, 240, 240);
+   evas_object_move(ctxpopup, x, y);
+   evas_object_show(ctxpopup);
+   _print_current_dir(ctxpopup);
+}
+
 static void _list_clicked(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info)
 {
    elm_list_item_selected_set(event_info, EINA_FALSE);
@@ -315,6 +357,8 @@ test_ctxpopup(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_in
                         _list_item_cb5, NULL);
    elm_list_item_append(list, "Ctxpopup with restacking", NULL, NULL,
                         _list_item_cb6, NULL);
+   elm_list_item_append(list, "Ctxpopup with callback function", NULL, NULL,
+                        _list_item_cb7, NULL);
    evas_object_show(list);
    elm_list_go(list);
 
index f79c38a..96a1040 100644 (file)
@@ -1003,12 +1003,14 @@ _item_del_pre_hook(Elm_Object_Item *it)
    if (eina_list_count(elm_list_items_get(list)) < 2)
      {
         elm_object_item_del(ctxpopup_it->list_item);
+        sd->items = eina_list_remove(sd->items, ctxpopup_it);
         evas_object_hide(WIDGET(ctxpopup_it));
 
         return EINA_TRUE;
      }
 
    elm_object_item_del(ctxpopup_it->list_item);
+   sd->items = eina_list_remove(sd->items, ctxpopup_it);
    if (sd->list_visible) elm_layout_sizing_eval(WIDGET(ctxpopup_it));
 
    return EINA_TRUE;
@@ -1086,6 +1088,7 @@ static void
 _elm_ctxpopup_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
 {
    Elm_Ctxpopup_Smart_Data *sd = _pd;
+   Elm_Ctxpopup_Item *it;
 
    evas_object_event_callback_del_full
      (sd->box, EVAS_CALLBACK_RESIZE, _on_content_resized, obj);
@@ -1098,6 +1101,9 @@ _elm_ctxpopup_smart_del(Eo *obj, void *_pd, va_list *list EINA_UNUSED)
    evas_object_del(sd->bg);
    sd->bg = NULL;
 
+   EINA_LIST_FREE (sd->items, it)
+     elm_widget_item_free(it);
+
    eo_do_super(obj, evas_obj_smart_del());
 }
 
@@ -1258,6 +1264,13 @@ elm_ctxpopup_item_append(Evas_Object *obj,
 }
 
 static void
+_item_wrap_cb(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   Elm_Ctxpopup_Item *item = data;
+   item->wcb.org_func_cb((void *)item->wcb.org_data, item->wcb.cobj, item);
+}
+
+static void
 _item_append(Eo *obj, void *_pd, va_list *list)
 {
    const char *label = va_arg(*list, const char *);
@@ -1293,8 +1306,12 @@ _item_append(Eo *obj, void *_pd, va_list *list)
         elm_layout_content_set(obj, "default", sd->list);
      }
 
+   item->wcb.org_func_cb = func;
+   item->wcb.org_data = data;
+   item->wcb.cobj = obj;
    item->list_item =
-     elm_list_item_append(sd->list, label, icon, NULL, func, data);
+     elm_list_item_append(sd->list, label, icon, NULL, _item_wrap_cb, item);
+   sd->items = eina_list_append(sd->items, item);
 
    sd->dir = ELM_CTXPOPUP_DIRECTION_UNKNOWN;
 
index 1c166c4..e8f18c1 100644 (file)
@@ -25,6 +25,13 @@ struct _Elm_Ctxpopup_Item
    ELM_WIDGET_ITEM;
 
    Elm_Object_Item *list_item;
+
+   struct
+     {
+        Evas_Smart_Cb org_func_cb;
+        const void    *org_data;
+        Evas_Object   *cobj;
+     } wcb;
 };
 
 struct _Elm_Ctxpopup_Smart_Data
@@ -32,6 +39,7 @@ struct _Elm_Ctxpopup_Smart_Data
    Evas_Object           *parent;
    Evas_Object           *list;
    Evas_Object           *box;
+   Eina_List             *items;
 
    Evas_Object           *arrow;
    Evas_Object           *bg;