From d6a1edb6668fc491b3b7303ec3eec6d3a86b3f28 Mon Sep 17 00:00:00 2001 From: ChunEon Park Date: Fri, 18 Jan 2013 09:07:03 +0000 Subject: [PATCH] elementary/ctxpopup - [E-devel] [PATCH] [Elementary] Fix memory leak and callback function in ctxpopup 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 SVN revision: 82968 --- ChangeLog | 5 +++++ NEWS | 1 + src/bin/test_ctxpopup.c | 44 +++++++++++++++++++++++++++++++++++++++++++ src/lib/elc_ctxpopup.c | 19 ++++++++++++++++++- src/lib/elm_widget_ctxpopup.h | 8 ++++++++ 5 files changed, 76 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index b4c2a93..4567c0f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -928,4 +928,9 @@ * 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 --- 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: diff --git a/src/bin/test_ctxpopup.c b/src/bin/test_ctxpopup.c index f5061be..7dd22f0 100644 --- a/src/bin/test_ctxpopup.c +++ b/src/bin/test_ctxpopup.c @@ -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); diff --git a/src/lib/elc_ctxpopup.c b/src/lib/elc_ctxpopup.c index f79c38a..96a1040 100644 --- a/src/lib/elc_ctxpopup.c +++ b/src/lib/elc_ctxpopup.c @@ -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; diff --git a/src/lib/elm_widget_ctxpopup.h b/src/lib/elm_widget_ctxpopup.h index 1c166c4..e8f18c1 100644 --- a/src/lib/elm_widget_ctxpopup.h +++ b/src/lib/elm_widget_ctxpopup.h @@ -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; -- 2.7.4