diff --git a/legacy/elementary/ChangeLog b/legacy/elementary/ChangeLog index b4c2a933a2..4567c0f8b9 100644 --- a/legacy/elementary/ChangeLog +++ b/legacy/elementary/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/legacy/elementary/NEWS b/legacy/elementary/NEWS index e7abbca8bd..116125b4d9 100644 --- a/legacy/elementary/NEWS +++ b/legacy/elementary/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/legacy/elementary/src/bin/test_ctxpopup.c b/legacy/elementary/src/bin/test_ctxpopup.c index f5061be447..7dd22f0f6e 100644 --- a/legacy/elementary/src/bin/test_ctxpopup.c +++ b/legacy/elementary/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/legacy/elementary/src/lib/elc_ctxpopup.c b/legacy/elementary/src/lib/elc_ctxpopup.c index f79c38aa45..96a1040b62 100644 --- a/legacy/elementary/src/lib/elc_ctxpopup.c +++ b/legacy/elementary/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()); } @@ -1257,6 +1263,13 @@ elm_ctxpopup_item_append(Evas_Object *obj, return ret; } +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) { @@ -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/legacy/elementary/src/lib/elm_widget_ctxpopup.h b/legacy/elementary/src/lib/elm_widget_ctxpopup.h index 1c166c497f..e8f18c1dac 100644 --- a/legacy/elementary/src/lib/elm_widget_ctxpopup.h +++ b/legacy/elementary/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;