diff --git a/docs/labwc-menu.5.scd b/docs/labwc-menu.5.scd index a50fa254..ae6c425a 100644 --- a/docs/labwc-menu.5.scd +++ b/docs/labwc-menu.5.scd @@ -106,13 +106,23 @@ ID attributes are unique. Duplicates are ignored. When writing pipe menu scripts, make sure to escape XML special characters such as "&" ("&"), "<" ("<"), and ">" (">"). - # LOCALISATION Available localisation for the default "client-menu" is only shown if no "client-menu" is present in menu.xml. Any menu definition in menu.xml is interpreted as a user-override. +# YAML SUPPORT + +Like rc.yaml, labwc supports menu.yaml instead of menu.xml. See labwc-config(5) +for its syntax. Note that following keys in singular form can be expressed as +plural form in menu.yaml: + + - *menus* (converted to *menu*) + - *items* (converted to *item*) + +See /usr/share/docs/labwc/menu.yaml for an example menu configuration in YAML. + # SEE ALSO labwc(1), labwc-actions(5), labwc-config(5), labwc-theme(5) diff --git a/docs/menu.yaml b/docs/menu.yaml new file mode 100644 index 00000000..842799f8 --- /dev/null +++ b/docs/menu.yaml @@ -0,0 +1,33 @@ +menu: + - id: client-menu + item: + label: Minimize + action: { name: Iconify } + item: + label: Maximize + action: { name: ToggleMaximize } + menu: + id: workspaces + label: Workspace + item: + label: Move Left + action: { name: SendToDesktop, to: left } + item: + label: Move Right + action: { name: SendToDesktop, to: right } + separator: + item: + label: Always on Visible Workspace + action: { name: ToggleOmnipresent } + item: + label: Close + action: { name: Close } + + - id: root-menu + items: + - label: Terminal + action: { name: Execute, command: alacritty } + - label: Reconfigure + action: { name: Reconfigure } + - label: Exit + action: { name: Exit } diff --git a/src/common/yaml2xml.c b/src/common/yaml2xml.c index 5ac1e6e5..82fa7f65 100644 --- a/src/common/yaml2xml.c +++ b/src/common/yaml2xml.c @@ -82,6 +82,10 @@ process_value(yaml_parser_t *parser, struct buf *b, key_name = "font"; } else if (!strcasecmp(key_name, "contexts")) { key_name = "context"; + } else if (!strcasecmp(key_name, "items")) { + key_name = "item"; + } else if (!strcasecmp(key_name, "menus")) { + key_name = "menu"; } if (parent_name) { buf_add_fmt(b, "<%s>", parent_name); diff --git a/src/menu/menu.c b/src/menu/menu.c index f8653d64..a8039a09 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -26,6 +26,10 @@ #include "node.h" #include "theme.h" +#if HAVE_LIBYAML +#include "common/yaml2xml.h" +#endif + #define PIPEMENU_MAX_BUF_SIZE 1048576 /* 1 MiB */ #define PIPEMENU_TIMEOUT_IN_MS 4000 /* 4 seconds */ @@ -566,6 +570,35 @@ is_toplevel_static_menu_definition(xmlNode *n, char *id) return id && nr_parents(n) == 2; } +static char * +get_property(xmlNode *n, const char *name) +{ + /* First, search from attributes */ + char *prop = (char *)xmlGetProp(n, (const xmlChar *)name); + if (prop) { + return prop; + } + + /* Then search from child nodes */ + xmlNode *child; + for (child = n->children; child && child->name; + child = child->next) { + if (!strcmp((char *)child->name, name)) { + goto found_child_node; + } + } + return NULL; + +found_child_node: + for (child = child->children; child && child->name; + child = child->next) { + if (child->type == XML_TEXT_NODE) { + return xstrdup((char *)child->content); + } + } + return NULL; +} + /* *