diff --git a/lib/dbusmenu-importer/definitions.h b/lib/dbusmenu-importer/definitions.h index d796f950..cabe6c48 100644 --- a/lib/dbusmenu-importer/definitions.h +++ b/lib/dbusmenu-importer/definitions.h @@ -28,6 +28,7 @@ #define HAS_ICON_NAME "has-icon-name" typedef enum { + DBUS_MENU_ACTION_SECTION, DBUS_MENU_ACTION_NORMAL, DBUS_MENU_ACTION_CHECKMARK, DBUS_MENU_ACTION_RADIO, diff --git a/lib/dbusmenu-importer/item.c b/lib/dbusmenu-importer/item.c index 0b2edc88..34af491f 100644 --- a/lib/dbusmenu-importer/item.c +++ b/lib/dbusmenu-importer/item.c @@ -42,7 +42,7 @@ G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_new_first_section(u_int32_t id, { DBusMenuItem *item = g_slice_new0(DBusMenuItem); item->id = id; - item->is_section = true; + item->action_type = DBUS_MENU_ACTION_SECTION; item->enabled = false; item->toggled = false; item->attributes = @@ -63,10 +63,9 @@ G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_new(u_int32_t id, DBusMenuModel *pa const char *prop; GVariant *value; item_set_magic(item); - item->is_section = false; - item->enabled = true; - item->toggled = false; - item->id = id; + item->enabled = true; + item->toggled = false; + item->id = id; item->attributes = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)g_variant_unref); item->links = @@ -135,7 +134,8 @@ G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_new(u_int32_t id, DBusMenuModel *pa const char *type = g_variant_get_string(value, NULL); if (!g_strcmp0(type, DBUS_MENU_TYPE_SEPARATOR)) { - item->is_section = true; + item->action_type = DBUS_MENU_ACTION_SECTION; + action_creator_found = true; } else if (!g_strcmp0(type, DBUS_MENU_TYPE_NORMAL)) { @@ -150,10 +150,11 @@ G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_new(u_int32_t id, DBusMenuModel *pa } else if (g_strcmp0(prop, "x-kde-title") == 0) { - item->is_section = true; + item->action_type = DBUS_MENU_ACTION_SECTION; g_hash_table_insert(item->attributes, g_strdup(G_MENU_ATTRIBUTE_LABEL), value); + action_creator_found = true; } else if (!action_creator_found) { @@ -185,7 +186,6 @@ G_GNUC_INTERNAL void dbus_menu_item_free(gpointer data) G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_copy(DBusMenuItem *src) { DBusMenuItem *dst = g_slice_new0(DBusMenuItem); - dst->is_section = src->is_section; dst->id = src->id; dst->action_type = src->action_type; dst->enabled = src->enabled; @@ -211,7 +211,7 @@ static bool check_and_update_mutable_attribute(DBusMenuItem *item, const char *k return false; } -static bool dbus_menu_item_update_enabled(DBusMenuItem *item, bool enabled) +G_GNUC_INTERNAL bool dbus_menu_item_update_enabled(DBusMenuItem *item, bool enabled) { bool updated = false; if (item->action_type == DBUS_MENU_ACTION_SUBMENU && !item->toggled) @@ -272,8 +272,6 @@ G_GNUC_INTERNAL void dbus_menu_item_preload(DBusMenuItem *item) if (DBUS_MENU_IS_MODEL(submenu)) dbus_menu_model_update_layout(submenu); } - dbus_menu_item_update_enabled(item, true); - item->toggled = true; } G_GNUC_INTERNAL bool dbus_menu_item_copy_attributes(DBusMenuItem *src, DBusMenuItem *dst) @@ -427,7 +425,7 @@ G_GNUC_INTERNAL bool dbus_menu_item_update_props(DBusMenuItem *item, GVariant *p else if (g_strcmp0(prop, "visible") == 0) { bool vis = g_variant_get_boolean(value); - if (item->is_section) + if (item->action_type == DBUS_MENU_ACTION_SECTION) { item->toggled = !vis; continue; @@ -554,8 +552,6 @@ G_GNUC_INTERNAL bool dbus_menu_item_compare_immutable(DBusMenuItem *a, DBusMenuI { if (a->id != b->id) return false; - if (a->is_section != b->is_section) - return false; if (a->referenced_action_group != b->referenced_action_group) return false; if (a->action_type != b->action_type) @@ -569,12 +565,12 @@ G_GNUC_INTERNAL void dbus_menu_item_copy_submenu(DBusMenuItem *src, DBusMenuItem DBusMenuXml *xml; DBusMenuModel *submenu = NULL; g_object_get(parent, "xml", &xml, NULL); - if (dst->toggled) - dst->enabled = true; if (src == NULL) { if (dst->action_type == DBUS_MENU_ACTION_SUBMENU) { + if (dst->toggled) + dst->enabled = true; submenu = dbus_menu_model_new(dst->id, parent, xml, dst->referenced_action_group); g_hash_table_insert(dst->links, @@ -587,6 +583,8 @@ G_GNUC_INTERNAL void dbus_menu_item_copy_submenu(DBusMenuItem *src, DBusMenuItem if (dst->action_type == DBUS_MENU_ACTION_SUBMENU && src->action_type == DBUS_MENU_ACTION_SUBMENU) { + if (src->toggled || dst->toggled) + dst->enabled = dst->toggled = true; submenu = DBUS_MENU_MODEL(g_hash_table_lookup(src->links, src->enabled ? G_MENU_LINK_SUBMENU @@ -601,6 +599,8 @@ G_GNUC_INTERNAL void dbus_menu_item_copy_submenu(DBusMenuItem *src, DBusMenuItem G_GNUC_INTERNAL void dbus_menu_item_generate_action(DBusMenuItem *item, DBusMenuModel *parent) { + if (item->action_type == DBUS_MENU_ACTION_SECTION) + return; DBusMenuXml *xml; DBusMenuModel *submenu = g_hash_table_lookup(item->links, diff --git a/lib/dbusmenu-importer/item.h b/lib/dbusmenu-importer/item.h index 8aabd13b..2731dd8c 100644 --- a/lib/dbusmenu-importer/item.h +++ b/lib/dbusmenu-importer/item.h @@ -31,7 +31,6 @@ G_BEGIN_DECLS typedef struct { u_int32_t id; - bool is_section; GActionGroup *referenced_action_group; // FIXME: Cannot have activatable submenu item. GAction *referenced_action; @@ -50,6 +49,8 @@ G_GNUC_INTERNAL DBusMenuItem *dbus_menu_item_new_first_section(u_int32_t id, G_GNUC_INTERNAL void dbus_menu_item_free(gpointer data); +G_GNUC_INTERNAL bool dbus_menu_item_update_enabled(DBusMenuItem *item, bool enabled); + G_GNUC_INTERNAL bool dbus_menu_item_update_props(DBusMenuItem *item, GVariant *props); G_GNUC_INTERNAL bool dbus_menu_item_remove_props(DBusMenuItem *item, GVariant *props); @@ -62,6 +63,7 @@ G_GNUC_INTERNAL void dbus_menu_item_copy_submenu(DBusMenuItem *src, DBusMenuItem DBusMenuModel *parent); G_GNUC_INTERNAL void dbus_menu_item_generate_action(DBusMenuItem *item, DBusMenuModel *parent); + G_GNUC_INTERNAL void dbus_menu_item_preload(DBusMenuItem *item); G_GNUC_INTERNAL int dbus_menu_item_id_compare_func(const DBusMenuItem *a, gconstpointer b, diff --git a/lib/dbusmenu-importer/model.c b/lib/dbusmenu-importer/model.c index 25d932cc..0557b262 100644 --- a/lib/dbusmenu-importer/model.c +++ b/lib/dbusmenu-importer/model.c @@ -213,7 +213,7 @@ static void layout_parse(DBusMenuModel *menu, GVariant *layout) DBusMenuItem *old = NULL; DBusMenuItem *new_item = dbus_menu_item_new(cid, menu, cprops); // We receive a section (separator or x-kde-title) - if (new_item->is_section) + if (new_item->action_type == DBUS_MENU_ACTION_SECTION) { bool is_valid_section = !new_item->toggled; // Section is valid, so, parse it @@ -291,11 +291,15 @@ static void layout_parse(DBusMenuModel *menu, GVariant *layout) dbus_menu_item_copy_submenu(NULL, new_item, menu); dbus_menu_item_generate_action(new_item, menu); if (menu->parent_id == 0) + { + dbus_menu_item_update_enabled(new_item, true); + new_item->toggled = true; g_timeout_add_full(100, 300, (GSourceFunc)preload_idle, new_item, NULL); + } current_iter = g_sequence_insert_before(current_iter, new_item); added++; } @@ -313,11 +317,15 @@ static void layout_parse(DBusMenuModel *menu, GVariant *layout) dbus_menu_item_generate_action(new_item, menu); // if it is root, preload submenu if (menu->parent_id == 0) + { + dbus_menu_item_update_enabled(new_item, true); + new_item->toggled = true; g_timeout_add_full(100, 300, (GSourceFunc)preload_idle, new_item, NULL); + } g_sequence_set(current_iter, new_item); } else @@ -522,7 +530,7 @@ static void items_properties_updated_cb(DBusMenuXml *proxy, GVariant *updated_pr if (item != NULL) { // It is the best what we can do to update a section - if (item->is_section) + if (item->action_type == DBUS_MENU_ACTION_SECTION) { // dbus_menu_model_update_layout(menu); } @@ -548,7 +556,7 @@ static void items_properties_updated_cb(DBusMenuXml *proxy, GVariant *updated_pr if (item != NULL) { // It is the best what we can do to update a section - if (item->is_section) + if (item->action_type == DBUS_MENU_ACTION_SECTION) { // dbus_menu_model_update_layout(menu); }