e_menu: recursively delete children menus.

e_menu had this behaviour that submenus were not deleted
automatically, relying on the parent menu to hook to post_deactivate
and then delete them.

This was good because maybe you don't want to delete these children,
you might want to reuse them sometime.

But it ended that nobody was using this feature, and worse: most use
cases were failing to delete these children, causing memory leak.

This commit changes the default behaviour and thus remove all the
existing code that was replicating such work. If one want the old
behavior, just call e_menu_item_submenu_set(mi, NULL) and it will be
unbounded from the parent.

If you experience any problems with that, try adding some printf()
before _e_menu_free() and _e_menu_item_free() and print some relevant
information like m->category and m->header.title or mi->label in order
to figure out the problematic menu.



SVN revision: 38528
This commit is contained in:
Gustavo Sverzut Barbieri 2009-01-10 07:02:32 +00:00
parent 6ff4dd8387
commit 05402668aa
5 changed files with 3 additions and 74 deletions

View File

@ -1260,7 +1260,6 @@ e_gadcon_client_util_menu_items_append(E_Gadcon_Client *gcc, E_Menu *menu, int f
e_menu_item_label_set(mi, _("Appearance"));
e_util_menu_item_edje_icon_set(mi, "enlightenment/appearance");
e_menu_item_submenu_set(mi, mn);
e_object_del(E_OBJECT(mn));
}
if ((gcc->gadcon->shelf) || (gcc->gadcon->toolbar))

View File

@ -61,7 +61,6 @@ static void _e_int_menus_main_showhide (void *data, E_Menu *m, E_Menu_Item
static void _e_int_menus_main_restart (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_main_exit (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_desk_item_cb (void *data, E_Menu *m, E_Menu_Item *mi);
static void _e_int_menus_items_del_hook (void *obj);
static void _e_int_menus_item_label_set (Efreet_Menu *entry, E_Menu_Item *mi);
/* local subsystem globals */
@ -159,7 +158,6 @@ e_int_menus_main_new(void)
mi = e_menu_item_new(m);
e_menu_item_label_set(mi, _("Enlightenment"));
e_util_menu_item_edje_icon_set(mi, "enlightenment/e");
e_object_free_attach_func_set(E_OBJECT(subm), _e_int_menus_items_del_hook);
e_menu_item_submenu_set(mi, subm);
mi = e_menu_item_new(subm);
@ -241,7 +239,6 @@ e_int_menus_apps_new(const char *dir)
m = e_menu_new();
if (dir) e_object_data_set(E_OBJECT(m), strdup(dir));
e_menu_pre_activate_callback_set(m, _e_int_menus_apps_start, NULL);
e_object_del_attach_func_set(E_OBJECT(m), _e_int_menus_items_del_hook);
e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_apps_free_hook);
return m;
}
@ -259,7 +256,6 @@ e_int_menus_desktops_new(void)
e_menu_item_label_set(mi, _("Virtual"));
e_util_menu_item_edje_icon_set(mi, "enlightenment/desktops");
e_menu_pre_activate_callback_set(subm, _e_int_menus_virtuals_pre_cb, NULL);
e_object_free_attach_func_set(E_OBJECT(subm), _e_int_menus_items_del_hook);
e_menu_item_submenu_set(mi, subm);
subm = e_menu_new();
@ -267,7 +263,6 @@ e_int_menus_desktops_new(void)
e_menu_item_label_set(mi, _("Shelves"));
e_util_menu_item_edje_icon_set(mi, "enlightenment/shelf");
e_menu_pre_activate_callback_set(subm, _e_int_menus_shelves_pre_cb, NULL);
e_object_free_attach_func_set(E_OBJECT(subm), _e_int_menus_items_del_hook);
e_menu_item_submenu_set(mi, subm);
mi = e_menu_item_new(m);
@ -278,7 +273,6 @@ e_int_menus_desktops_new(void)
e_util_menu_item_edje_icon_set(mi, "enlightenment/showhide");
e_menu_item_callback_set(mi, _e_int_menus_main_showhide, NULL);
e_object_free_attach_func_set(E_OBJECT(m), _e_int_menus_items_del_hook);
return m;
}
@ -407,17 +401,7 @@ _e_int_menus_main_del_hook(void *obj)
m = obj;
dat = e_object_data_get(E_OBJECT(obj));
if (dat)
{
if (dat->apps) e_object_del(E_OBJECT(dat->apps));
if (dat->all_apps) e_object_del(E_OBJECT(dat->all_apps));
e_object_del(E_OBJECT(dat->desktops));
e_object_del(E_OBJECT(dat->clients));
e_object_del(E_OBJECT(dat->enlightenment));
e_object_del(E_OBJECT(dat->config));
if (dat->lost_clients) e_object_del(E_OBJECT(dat->lost_clients));
free(dat);
}
free(dat);
_e_int_menus_augmentation_del(m, eina_hash_find(_e_int_menus_augmentation, "main/0"));
_e_int_menus_augmentation_del(m, eina_hash_find(_e_int_menus_augmentation, "main/1"));
_e_int_menus_augmentation_del(m, eina_hash_find(_e_int_menus_augmentation, "main/2"));
@ -532,8 +516,6 @@ _e_int_menus_apps_scan(E_Menu *m, Efreet_Menu *menu)
e_menu_pre_activate_callback_set(subm,
_e_int_menus_apps_start,
entry);
e_object_del_attach_func_set(E_OBJECT(subm),
_e_int_menus_items_del_hook);
e_menu_item_submenu_set(mi, subm);
}
/* TODO: Highlight header
@ -573,22 +555,6 @@ _e_int_menus_apps_start(void *data, E_Menu *m)
e_menu_pre_activate_callback_set(m, NULL, NULL);
}
static void
_e_int_menus_items_del_hook(void *obj)
{
E_Menu *m;
Eina_List *l = NULL;
m = obj;
for (l = m->items; l; l = l->next)
{
E_Menu_Item *mi;
mi = l->data;
if (mi->submenu) e_object_del(E_OBJECT(mi->submenu));
}
}
static void
_e_int_menus_apps_free_hook(void *obj)
{

View File

@ -1062,7 +1062,8 @@ _e_menu_item_free(E_Menu_Item *mi)
if (mi->submenu)
{
mi->submenu->parent_item = NULL;
e_object_unref(E_OBJECT(mi->submenu));
e_object_unref(E_OBJECT(mi->submenu)); /* added on submenu_set() */
e_object_del(E_OBJECT(mi->submenu));
}
if (mi->menu->realized) _e_menu_item_unrealize(mi);
mi->menu->items = eina_list_remove(mi->menu->items, mi);

View File

@ -23,7 +23,6 @@ static int _e_shelf_cb_id_sort(const void *data1, const void *data2);
static int _e_shelf_cb_hide_animator(void *data);
static int _e_shelf_cb_hide_animator_timer(void *data);
static int _e_shelf_cb_instant_hide_timer(void *data);
static void _e_shelf_menu_del_hook(void *data);
static void _e_shelf_menu_pre_cb(void *data, E_Menu *m);
static void _e_shelf_edge_event_register(E_Shelf *es, int reg);
@ -1100,7 +1099,6 @@ _e_shelf_menu_append(E_Shelf *es, E_Menu *mn)
e_menu_item_label_set(mi, buf);
e_util_menu_item_edje_icon_set(mi, "enlightenment/shelf");
e_menu_pre_activate_callback_set(subm, _e_shelf_menu_pre_cb, es);
e_object_free_attach_func_set(E_OBJECT(subm), _e_shelf_menu_del_hook);
e_menu_item_submenu_set(mi, subm);
}
@ -1630,22 +1628,6 @@ _e_shelf_cb_instant_hide_timer(void *data)
return 0;
}
static void
_e_shelf_menu_del_hook(void *data)
{
E_Menu *m;
Eina_List *l;
m = data;
for (l = m->items; l; l = l->next)
{
E_Menu_Item *mi;
mi = l->data;
if (mi->submenu) e_object_del(E_OBJECT(mi->submenu));
}
}
static void
_e_shelf_menu_pre_cb(void *data, E_Menu *m)
{

View File

@ -6,7 +6,6 @@ static void _e_toolbar_cb_mouse_down(void *data, Evas *evas, Evas_Object *obj, v
static void _e_toolbar_menu_cb_post(void *data, E_Menu *mn);
static void _e_toolbar_menu_cb_pre(void *data, E_Menu *mn);
static void _e_toolbar_menu_append(E_Toolbar *tbar, E_Menu *mn);
static void _e_toolbar_menu_del_hook(void *data);
static void _e_toolbar_menu_cb_edit(void *data, E_Menu *mn, E_Menu_Item *mi);
static void _e_toolbar_menu_cb_config(void *data, E_Menu *mn, E_Menu_Item *mi);
static void _e_toolbar_menu_cb_contents(void *data, E_Menu *mn, E_Menu_Item *mi);
@ -354,27 +353,9 @@ _e_toolbar_menu_append(E_Toolbar *tbar, E_Menu *mn)
e_menu_item_label_set(mi, tbar->name);
e_util_menu_item_edje_icon_set(mi, "enlightenment/toolbar");
e_menu_pre_activate_callback_set(subm, _e_toolbar_menu_cb_pre, tbar);
e_object_free_attach_func_set(E_OBJECT(subm), _e_toolbar_menu_del_hook);
e_menu_item_submenu_set(mi, subm);
}
static void
_e_toolbar_menu_del_hook(void *data)
{
E_Menu *mn;
Eina_List *l = NULL;
mn = data;
for (l = mn->items; l; l = l->next)
{
E_Menu_Item *mi;
mi = l->data;
if (!mi) continue;
if (mi->submenu) e_object_del(E_OBJECT(mi->submenu));
}
}
static void
_e_toolbar_menu_cb_edit(void *data, E_Menu *mn, E_Menu_Item *mi)
{