menu: do not require label attribute for highest level menu definition

Allow highest level menu definitions - typically used for root-menu and
client-menu - to be defined like this:

    <openbox_menu>
      <menu id="">
      </menu>
    </openbox>

Previously this required a label attribute (which was not used for
anything and could be an empty string) as show below:

    <openbox_menu>
      <menu id="" label="">
      </menu>
    </openbox>

Closes issue #472
This commit is contained in:
Johan Malm 2022-08-11 18:43:51 +01:00 committed by Johan Malm
parent ac5c9dae00
commit 70421b1207
3 changed files with 39 additions and 5 deletions

View file

@ -15,7 +15,7 @@ A menu file must be entirely enclosed within <openbox_menu> and
</openbox_menu> tags. Inside these tags, menus are specified as follows:
```
<menu id="" label="">
<menu id="">
<!-- A menu entry with an action, for example to execute an application -->
<item label="">

View file

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<openbox_menu>
<menu id="client-menu" label="ClientMenu">
<menu id="client-menu">
<item label="Minimize">
<action name="Iconify" />
</item>
@ -31,7 +32,8 @@
<action name="Close" />
</item>
</menu>
<menu id="root-menu" label="">
<menu id="root-menu">
<item label="Web browser">
<action name="Execute"><command>firefox</command></action>
</item>

View file

@ -51,7 +51,7 @@ menu_create(struct server *server, const char *id, const char *label)
nr_menus++;
wl_list_init(&menu->menuitems);
menu->id = strdup(id);
menu->label = strdup(label);
menu->label = label ? strdup(label) : strdup(id);
menu->parent = current_menu;
menu->server = server;
menu->size.width = MENUWIDTH;
@ -299,6 +299,17 @@ traverse(xmlNode *n, struct server *server)
xml_tree_walk(n->children, server);
}
static int
nr_parents(xmlNode *n)
{
assert(n);
int i = 0;
for (xmlNode *node = n->parent; node && i < INT_MAX; ++i) {
node = node->parent;
}
return i;
}
/*
* <menu> elements have three different roles:
* * Definition of (sub)menu - has ID, LABEL and CONTENT
@ -314,7 +325,24 @@ handle_menu_element(xmlNode *n, struct server *server)
if (execute) {
wlr_log(WLR_ERROR, "we do not support pipemenus");
} else if (label && id) {
} else if ((label && id) || (id && nr_parents(n) == 2)) {
/*
* (label && id) refers to <menu id="" label=""> which is an
* inline menu definition.
*
* (id && nr_parents(n) == 2) refers to:
* <openbox_menu>
* <menu id="">
* </menu>
* </openbox>
*
* which is the highest level a menu can be defined at.
*
* Openbox spec requires a label="" defined here, but it is
* actually pointless so we handle it with or without the label
* attritute to make it easier for users to define "root-menu"
* and "client-menu".
*/
struct menu **submenu = NULL;
if (menu_level > 0) {
/*
@ -337,6 +365,10 @@ handle_menu_element(xmlNode *n, struct server *server)
current_menu = current_menu->parent;
--menu_level;
} else if (id) {
/*
* <menu id=""> creates an entry which points to a menu
* defined elsewhere
*/
struct menu *menu = menu_get_by_id(id);
if (menu) {
current_item = item_create(current_menu, menu->label);