diff --git a/docs/labwc.1.scd b/docs/labwc.1.scd
index 4e643918..4840c0fa 100644
--- a/docs/labwc.1.scd
+++ b/docs/labwc.1.scd
@@ -134,8 +134,7 @@ example: *LABWC_DEBUG_FOO=1 labwc*.
Increase logging of paths for config files (for example rc.xml,
autostart, environment and menu.xml) as well as titlebar buttons.
-*LABWC_DEBUG_CONFIG_NODENAMES*++
-*LABWC_DEBUG_MENU_NODENAMES*
+*LABWC_DEBUG_CONFIG_NODENAMES*
Enable logging of all nodenames (for example *policy.placement: Cascade*
for *Cascade*) for config and
menu files respectively.
diff --git a/src/menu/menu.c b/src/menu/menu.c
index 8d80231f..0232e2d5 100644
--- a/src/menu/menu.c
+++ b/src/menu/menu.c
@@ -20,12 +20,12 @@
#include "common/lab-scene-rect.h"
#include "common/list.h"
#include "common/mem.h"
-#include "common/nodename.h"
#include "common/scaled-font-buffer.h"
#include "common/scaled-icon-buffer.h"
#include "common/scene-helpers.h"
#include "common/spawn.h"
#include "common/string-helpers.h"
+#include "common/xml.h"
#include "labwc.h"
#include "output.h"
#include "workspaces.h"
@@ -38,15 +38,6 @@
#define ICON_SIZE (rc.theme->menu_item_height - 2 * rc.theme->menu_items_padding_y)
-/* state-machine variables for processing */
-struct menu_parse_context {
- struct server *server;
- struct menu *menu;
- struct menuitem *item;
- struct action *action;
- bool in_item;
-};
-
static bool waiting_for_pipe_menu;
static struct menuitem *selected_item;
@@ -140,7 +131,7 @@ validate(struct server *server)
}
static struct menuitem *
-item_create(struct menu *menu, const char *text, bool show_arrow)
+item_create(struct menu *menu, const char *text, const char *icon_name, bool show_arrow)
{
assert(menu);
assert(text);
@@ -152,6 +143,13 @@ item_create(struct menu *menu, const char *text, bool show_arrow)
menuitem->text = xstrdup(text);
menuitem->arrow = show_arrow ? "›" : NULL;
+#if HAVE_LIBSFDO
+ if (rc.menu_show_icons && !string_null_or_empty(icon_name)) {
+ menuitem->icon_name = xstrdup(icon_name);
+ menu->has_icons = true;
+ }
+#endif
+
menuitem->native_width = font_width(&rc.font_menuitem, text);
if (menuitem->arrow) {
menuitem->native_width += font_width(&rc.font_menuitem, menuitem->arrow);
@@ -473,34 +471,22 @@ menu_create_scene(struct menu *menu)
*
*/
static void
-fill_item(struct menu_parse_context *ctx, const char *nodename,
- const char *content)
+fill_item(struct menu *menu, xmlNode *node)
{
- /* - defines the start of a new item */
- if (!strcmp(nodename, "label")) {
- ctx->item = item_create(ctx->menu, content, false);
- ctx->action = NULL;
- } else if (!ctx->item) {
- wlr_log(WLR_ERROR, "expect
- element first. "
- "nodename: '%s' content: '%s'", nodename, content);
- } else if (!strcmp(nodename, "icon")) {
-#if HAVE_LIBSFDO
- if (rc.menu_show_icons && !string_null_or_empty(content)) {
- xstrdup_replace(ctx->item->icon_name, content);
- ctx->menu->has_icons = true;
- }
-#endif
- } else if (!strcmp(nodename, "name.action")) {
- ctx->action = action_create(content);
- if (ctx->action) {
- wl_list_append(&ctx->item->actions, &ctx->action->link);
- }
- } else if (!ctx->action) {
- wlr_log(WLR_ERROR, "expect element first. "
- "nodename: '%s' content: '%s'", nodename, content);
- } else {
- action_arg_from_xml_node(ctx->action, nodename, content);
+ char *label = (char *)xmlGetProp(node, (xmlChar *)"label");
+ char *icon_name = (char *)xmlGetProp(node, (xmlChar *)"icon");
+ if (!label) {
+ wlr_log(WLR_ERROR, "missing label in
- ");
+ goto out;
}
+
+ struct menuitem *item = item_create(menu, (char *)label, icon_name, false);
+ lab_xml_expand_dotted_attributes(node);
+ append_parsed_actions(node, &item->actions);
+
+out:
+ free(label);
+ free(icon_name);
}
static void
@@ -516,103 +502,10 @@ item_destroy(struct menuitem *item)
free(item);
}
-/*
- * We support XML CDATA for in menu.xml in order to provide backward
- * compatibility with obmenu-generator. For example:
- *
- *
- *
- * is an old, deprecated openbox variety of . We support it
- * for backward compatibility with old openbox-menu generators. It has the same
- * function and
- *
- * The following nodenames support CDATA.
- * - command.action.item.*menu.openbox_menu
- * - execute.action.item.*menu.openbox_menu
- * - command.action.item.openbox_pipe_menu
- * - execute.action.item.openbox_pipe_menu
- * - command.action.item.*menu.openbox_pipe_menu
- * - execute.action.item.*menu.openbox_pipe_menu
- *
- * The *menu allows nested menus with nodenames such as ...menu.menu... or
- * ...menu.menu.menu... and so on. We could use match_glob() for all of the
- * above but it seems simpler to just check the first three fields.
- */
-static bool
-nodename_supports_cdata(char *nodename)
-{
- return !strncmp("command.action.", nodename, 15)
- || !strncmp("execute.action.", nodename, 15);
-}
-
-static void
-entry(struct menu_parse_context *ctx, xmlNode *node, char *nodename,
- char *content)
-{
- if (!nodename) {
- return;
- }
- xmlChar *cdata = NULL;
- if (!content && nodename_supports_cdata(nodename)) {
- cdata = xmlNodeGetContent(node);
- }
- if (!content && !cdata) {
- return;
- }
- string_truncate_at_pattern(nodename, ".openbox_menu");
- string_truncate_at_pattern(nodename, ".openbox_pipe_menu");
- if (getenv("LABWC_DEBUG_MENU_NODENAMES")) {
- printf("%s: %s\n", nodename, content ? content : (char *)cdata);
- }
- if (ctx->in_item) {
- /*
- * Nodenames for most menu-items end with '.item.menu'
- * but top-level pipemenu items do not have the associated
- *