]> git.mdlowis.com Git - proto/labwc.git/commitdiff
menu: support inline submenus
authorJohan Malm <jgm323@gmail.com>
Mon, 8 Nov 2021 17:20:37 +0000 (17:20 +0000)
committerJohan Malm <jgm323@gmail.com>
Mon, 8 Nov 2021 17:20:37 +0000 (17:20 +0000)
...for example:

<menu id="root-menu" label="">
  <menu id="submenu" label="submenu">
    <item label="foo"></item>
  </menu>
  <item label="bar"></item>
</menu>

include/menu/menu.h
src/menu/menu.c

index 2a28cd826439c01886d166fc16cc8c791422c1e2..8f688c5cdb6ff0f03cf8f42964592bacc46189ef 100644 (file)
@@ -25,6 +25,7 @@ struct menu {
        char *id;
        char *label;
        bool visible;
+       struct menu *parent;
        struct wlr_box box;
        struct wl_list menuitems;
        struct server *server;
index 83b38524a90a6037a0f5df4a4753da3306d05a3c..5b3337fec86a0cd53ca36ea1fe050753e1872c0f 100644 (file)
@@ -27,6 +27,7 @@
 static bool in_item;
 static struct menuitem *current_item;
 
+static int menu_level;
 static struct menu *current_menu;
 
 /* vector for <menu id="" label=""> elements */
@@ -46,6 +47,7 @@ menu_create(struct server *server, const char *id, const char *label)
        wl_list_init(&menu->menuitems);
        menu->id = strdup(id);
        menu->label = strdup(label);
+       menu->parent = current_menu;
        menu->server = server;
        return menu;
 }
@@ -178,8 +180,23 @@ handle_menu_element(xmlNode *n, struct server *server)
        if (execute) {
                wlr_log(WLR_ERROR, "we do not support pipemenus");
        } else if (label && id) {
+               struct menu **submenu = NULL;
+               if (menu_level > 0) {
+                       /*
+                        * In a nested (inline) menu definition we need to
+                        * create an item pointing to the new submenu
+                        */
+                       current_item = item_create(current_menu, label);
+                       submenu = &current_item->submenu;
+               }
+               ++menu_level;
                current_menu = menu_create(server, id, label);
-               /* TODO: deal with nested menu definitions */
+               if (submenu) {
+                       *submenu = current_menu;
+               }
+               traverse(n, server);
+               current_menu = current_menu->parent;
+               --menu_level;
        } else if (id) {
                struct menu *menu = get_menu_by_id(id);
                if (menu) {
@@ -203,7 +220,6 @@ xml_tree_walk(xmlNode *node, struct server *server)
                }
                if (!strcasecmp((char *)n->name, "menu")) {
                        handle_menu_element(n, server);
-                       traverse(n, server);
                        continue;
                }
                if (!strcasecmp((char *)n->name, "item")) {