]> git.mdlowis.com Git - proto/labwc.git/commitdiff
menu: do not require label attribute for highest level menu definition
authorJohan Malm <jgm323@gmail.com>
Thu, 11 Aug 2022 17:43:51 +0000 (18:43 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Thu, 11 Aug 2022 19:59:57 +0000 (20:59 +0100)
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

docs/labwc-menu.5.scd
docs/menu.xml
src/menu/menu.c

index 716e00b89851319ab6ead8a3f7e3f6648e0ac384..f6e961291876fd6b397254eae8ae6a31bdd89444 100644 (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="">
index b61dd85adebd71dbfec5657d5bfb0ef92b154b7a..1bb42788f8e7471c6a15836615224315dfee9b22 100644 (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>
index a2677c8b10918d140bdc8c2ece7318f72c387b4b..fa4d26092a6ab9c08d9930a3e6ef05ce16bc5cf4 100644 (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);