diff --git a/src/bin/e_dbusmenu.c b/src/bin/e_dbusmenu.c index b3e254987..5a94b9be8 100644 --- a/src/bin/e_dbusmenu.c +++ b/src/bin/e_dbusmenu.c @@ -37,11 +37,10 @@ static void proxy_init(E_DBusMenu_Ctx *ctx); static int id_find(const char *text, const char *array_of_names[], unsigned max) { - unsigned i; + unsigned int i; for (i = 0; i < max; i++) { - if (strcmp(text, array_of_names[i])) - continue; + if (strcmp(text, array_of_names[i])) continue; return i; } return 0; @@ -90,8 +89,7 @@ dbus_menu_prop_dict_cb(void *data, const void *key, Eldbus_Message_Iter *var) eldbus_message_iter_arguments_get(var, "ay", &array); eldbus_message_iter_fixed_array_get(array, 'y', &img_data, &size); - if (!size) - return; + if (!size) return; m->icon_data = malloc(sizeof(unsigned char) * size); EINA_SAFETY_ON_FALSE_RETURN(m->icon_data); memcpy(m->icon_data, img_data, size); @@ -114,19 +112,15 @@ dbus_menu_prop_dict_cb(void *data, const void *key, Eldbus_Message_Iter *var) { int state; eldbus_message_iter_arguments_get(var, "i", &state); - if (state == 1) - m->toggle_state = EINA_TRUE; - else - m->toggle_state = EINA_FALSE; + if (state == 1) m->toggle_state = EINA_TRUE; + else m->toggle_state = EINA_FALSE; } else if (!strcmp(key, "children-display")) { const char *display; eldbus_message_iter_arguments_get(var, "s", &display); - if (!strcmp(display, "submenu")) - m->is_submenu = EINA_TRUE; - else - m->is_submenu = EINA_FALSE; + if (!strcmp(display, "submenu")) m->is_submenu = EINA_TRUE; + else m->is_submenu = EINA_FALSE; } else if (!strcmp(key, "disposition")) { @@ -147,6 +141,7 @@ parse_layout(Eldbus_Message_Iter *layout, E_DBusMenu_Item *parent, E_DBusMenu_Ct Eldbus_Message_Iter *menu_item_prop, *sub_menu_items_prop, *var; E_DBusMenu_Item *m = calloc(1, sizeof(E_DBusMenu_Item)); EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); + m->references = 1; m->ctx = ctx; m->enabled = EINA_TRUE; m->visible = EINA_TRUE; @@ -172,8 +167,7 @@ parse_layout(Eldbus_Message_Iter *layout, E_DBusMenu_Item *parent, E_DBusMenu_Ct parse_layout(st, m, ctx); } - if (!parent) - return m; + if (!parent) return m; parent->sub_items = eina_inlist_append(parent->sub_items, EINA_INLIST_GET(m)); m->parent = parent; @@ -186,17 +180,21 @@ dbus_menu_free(E_DBusMenu_Item *m) Eina_Inlist *inlist; E_DBusMenu_Item *child; - if (m->icon_name) - eina_stringshare_del(m->icon_name); - if (m->label) - eina_stringshare_del(m->label); EINA_INLIST_FOREACH_SAFE(m->sub_items, inlist, child) - dbus_menu_free(child); - if (m->parent) - m->parent->sub_items = eina_inlist_remove(m->parent->sub_items, - EINA_INLIST_GET(m)); - if (m->icon_data_size) - free(m->icon_data); + { + e_dbusmenu_item_unref(child); + } + EINA_INLIST_FREE(m->sub_items, child) + { + m->sub_items = eina_inlist_remove + (m->sub_items, EINA_INLIST_GET(child)); + child->parent = NULL; + } + if (m->icon_name) eina_stringshare_del(m->icon_name); + if (m->label) eina_stringshare_del(m->label); + if (m->parent) m->parent->sub_items = eina_inlist_remove + (m->parent->sub_items, EINA_INLIST_GET(m)); + if (m->icon_data_size) free(m->icon_data); free(m); } @@ -229,7 +227,7 @@ attempt_hacks(E_DBusMenu_Ctx *ctx) if ((unsigned int)(p - bus) > sizeof(buf) - 1) return EINA_FALSE; strncpy(buf, bus, p - bus); snprintf(buf2, sizeof(buf2), "%s%d", buf, n); - E_FREE_FUNC(ctx->root_menu, dbus_menu_free); + E_FREE_FUNC(ctx->root_menu, e_dbusmenu_item_unref); eldbus_proxy_unref(ctx->proxy); eldbus_object_unref(obj); @@ -267,15 +265,13 @@ layout_get_cb(void *data, const Eldbus_Message *msg, Eldbus_Pending *pending EIN { if (attempt_hacks(ctx)) { - dbus_menu_free(m); + e_dbusmenu_item_unref(m); return; } } - if (ctx->update_cb) - ctx->update_cb(ctx->data, m); - if (ctx->root_menu) - dbus_menu_free(ctx->root_menu); + if (ctx->update_cb) ctx->update_cb(ctx->data, m); + if (ctx->root_menu) e_dbusmenu_item_unref(ctx->root_menu); ctx->root_menu = m; } @@ -289,13 +285,11 @@ dbus_menu_find(E_DBusMenu_Ctx *ctx, int id) EINA_INLIST_FOREACH(ctx->root_menu, m) { E_DBusMenu_Item *child, *found; - if (m->id == id) - return m; + if (m->id == id) return m; EINA_INLIST_FOREACH(m->sub_items, child) { found = dbus_menu_find(ctx, id); - if (found) - return found; + if (found) return found; } } return NULL; @@ -316,10 +310,8 @@ menu_pop_request(void *data, const Eldbus_Message *msg) } m = dbus_menu_find(ctx, id); - if (!m) - return; - if (ctx->pop_request_cb) - ctx->pop_request_cb(ctx->data, m); + if (!m) return; + if (ctx->pop_request_cb) ctx->pop_request_cb(ctx->data, m); } static void @@ -334,8 +326,7 @@ prop_changed_cb(void *data EINA_UNUSED, const Eldbus_Message *msg) return; } - if (strcmp(propname, "IconThemePath")) - return; + if (strcmp(propname, "IconThemePath")) return; if (!eldbus_message_iter_arguments_get(variant, "as", &array)) { @@ -426,6 +417,19 @@ e_dbusmenu_event_send(E_DBusMenu_Item *m, E_DBusMenu_Item_Event event) eldbus_proxy_send(m->ctx->proxy, msg, NULL, NULL, -1); } +E_API void +e_dbusmenu_item_ref(E_DBusMenu_Item *m) +{ + m->references++; +} + +E_API void +e_dbusmenu_item_unref(E_DBusMenu_Item *m) +{ + m->references--; + if (m->references == 0) dbus_menu_free(m); +} + E_API void e_dbusmenu_unload(E_DBusMenu_Ctx *ctx) { @@ -433,8 +437,7 @@ e_dbusmenu_unload(E_DBusMenu_Ctx *ctx) Eldbus_Object *obj; EINA_SAFETY_ON_NULL_RETURN(ctx); - if (ctx->root_menu) - dbus_menu_free(ctx->root_menu); + if (ctx->root_menu) e_dbusmenu_item_unref(ctx->root_menu); obj = eldbus_proxy_object_get(ctx->proxy); conn = eldbus_object_connection_get(obj); eldbus_proxy_unref(ctx->proxy); diff --git a/src/bin/e_dbusmenu.h b/src/bin/e_dbusmenu.h index cbc9df45f..835c45ecf 100644 --- a/src/bin/e_dbusmenu.h +++ b/src/bin/e_dbusmenu.h @@ -40,8 +40,10 @@ typedef struct _E_DBusMenu_Ctx E_DBusMenu_Ctx; struct _E_DBusMenu_Item { EINA_INLIST; - unsigned revision; + unsigned int revision; int id; + unsigned int icon_data_size; + int references; const char *label; E_DBusMenu_Item_Type type; E_DBusMenu_Item_Toggle_Type toggle_type; @@ -52,7 +54,6 @@ struct _E_DBusMenu_Item Eina_Bool is_submenu; const char *icon_name; unsigned char *icon_data; - unsigned icon_data_size; Eina_Inlist *sub_items; E_DBusMenu_Item *parent; E_DBusMenu_Ctx *ctx; @@ -67,5 +68,7 @@ E_API void e_dbusmenu_update_cb_set(E_DBusMenu_Ctx *menu_data, E_DBusMenu_Update E_API void e_dbusmenu_pop_request_cb_set(E_DBusMenu_Ctx *menu_data, E_DBusMenu_Pop_Request_Cb cb); E_API void e_dbusmenu_event_send(E_DBusMenu_Item *m, E_DBusMenu_Item_Event event); +E_API void e_dbusmenu_item_ref(E_DBusMenu_Item *m); +E_API void e_dbusmenu_item_unref(E_DBusMenu_Item *m); #endif diff --git a/src/modules/appmenu/e_mod_appmenu_render.c b/src/modules/appmenu/e_mod_appmenu_render.c index 082181cde..32c424058 100644 --- a/src/modules/appmenu/e_mod_appmenu_render.c +++ b/src/modules/appmenu/e_mod_appmenu_render.c @@ -45,8 +45,22 @@ menu_deactive(E_Menu *m) { Eina_List *iter; E_Menu_Item *mi; + E_DBusMenu_Item *item; + + item = e_object_data_get(E_OBJECT(m)); + if (item) + { + e_object_data_set(E_OBJECT(m), NULL); + e_dbusmenu_item_unref(item); + } EINA_LIST_FOREACH(m->items, iter, mi) { + item = e_object_data_get(E_OBJECT(mi)); + if (item) + { + e_object_data_set(E_OBJECT(m), NULL); + e_dbusmenu_item_unref(item); + } if (mi->submenu) { menu_deactive(mi->submenu); @@ -81,15 +95,17 @@ item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi) m = e_menu_new(); EINA_SAFETY_ON_NULL_RETURN_VAL(m, NULL); - if (mi) - e_menu_item_submenu_set(mi, m); + e_dbusmenu_item_ref(item); + e_object_data_set(E_OBJECT(m), item); + if (mi) e_menu_item_submenu_set(mi, m); EINA_INLIST_FOREACH(item->sub_items, child) { E_Menu_Item *submi; - if (!child->visible) - continue; + if (!child->visible) continue; submi = e_menu_item_new(m); + e_dbusmenu_item_ref(child); + e_object_data_set(E_OBJECT(submi), child); if (child->type == E_DBUSMENU_ITEM_TYPE_SEPARATOR) { e_menu_item_separator_set(submi, 1); @@ -97,8 +113,7 @@ item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi) } e_menu_item_label_set(submi, child->label); e_menu_item_callback_set(submi, sub_item_clicked_cb, child); - if (!child->enabled) - e_menu_item_disabled_set(submi, 1); + if (!child->enabled) e_menu_item_disabled_set(submi, 1); if (child->toggle_type) { if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_CHECKMARK) diff --git a/src/modules/systray/e_mod_notifier_host.c b/src/modules/systray/e_mod_notifier_host.c index 46a239502..90f6929e2 100644 --- a/src/modules/systray/e_mod_notifier_host.c +++ b/src/modules/systray/e_mod_notifier_host.c @@ -130,13 +130,25 @@ _menu_post_deactivate(void *data, E_Menu *m) Eina_List *iter; E_Menu_Item *mi; E_Gadcon *gadcon = data; + E_DBusMenu_Item *item; - if (gadcon) - e_gadcon_locked_set(gadcon, 0); + item = e_object_data_get(E_OBJECT(m)); + if (item) + { + e_object_data_set(E_OBJECT(m), NULL); + e_dbusmenu_item_unref(item); + } + + if (gadcon) e_gadcon_locked_set(gadcon, 0); EINA_LIST_FOREACH(m->items, iter, mi) { - if (mi->submenu) - e_menu_deactivate(mi->submenu); + item = e_object_data_get(E_OBJECT(mi)); + if (item) + { + e_object_data_set(E_OBJECT(m), NULL); + e_dbusmenu_item_unref(item); + } + if (mi->submenu) e_menu_deactivate(mi->submenu); } e_object_del(E_OBJECT(m)); } @@ -149,14 +161,17 @@ _item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi) E_Menu_Item *submi; m = e_menu_new(); + e_dbusmenu_item_ref(item); + e_object_data_set(E_OBJECT(m), item); e_menu_post_deactivate_callback_set(m, _menu_post_deactivate, NULL); - if (mi) - e_menu_item_submenu_set(mi, m); + if (mi) e_menu_item_submenu_set(mi, m); EINA_INLIST_FOREACH(item->sub_items, child) { if (!child->visible) continue; submi = e_menu_item_new(m); + e_dbusmenu_item_ref(child); + e_object_data_set(E_OBJECT(submi), child); if (child->type == E_DBUSMENU_ITEM_TYPE_SEPARATOR) e_menu_item_separator_set(submi, 1); else