pipemenu enhancements

pipemenus work both parented non parented

<openbox_menu>
<menu id="app-menu" label="Applications" execute="labwc-menu-generator -p" />
...
<menu id="root-menu" label="">
...
<menu id="app-menu" />

Or

<menu id="root-menu" label="" />
<separator label="Root Menu" />
<menu id="weather-menu" label="Weather" execute="openweather.sh" />
This commit is contained in:
Droc 2024-09-07 08:55:44 -05:00
parent 8850368ab9
commit 5caaccd7e7
2 changed files with 112 additions and 13 deletions

View file

@ -583,25 +583,30 @@ handle_menu_element(xmlNode *n, struct server *server)
wlr_log(WLR_DEBUG, "pipemenu '%s:%s:%s'", id, label, execute); wlr_log(WLR_DEBUG, "pipemenu '%s:%s:%s'", id, label, execute);
if (!current_menu) { if (!current_menu) {
/* /*
* We currently do not support pipemenus without a * pipemenus without a parent
* parent <item> such as the one the example below:
* *
* <?xml version="1.0" encoding="UTF-8"?> * <?xml version="1.0" encoding="UTF-8"?>
* <openbox_menu> * <openbox_menu>
* <menu id="root-menu" label="foo" execute="bar"/> * <menu id="root-menu" label="foo" execute="bar"/>
* </openbox_menu> * </openbox_menu>
*
* TODO: Consider supporting this
*/ */
wlr_log(WLR_ERROR, current_menu = menu_create(server, id, label);
"pipemenu '%s:%s:%s' has no parent <menu>", current_menu->is_pipemenu = true;
id, label, execute); current_item = item_create(current_menu, label,
goto error; /* arrow */ true);
current_item_action = NULL;
current_item->execute = xstrdup(execute);
current_item->id = xstrdup(id);
} else {
/*
* pipemenus with a parent
*/
current_item = item_create(current_menu, label,
/* arrow */ true);
current_item_action = NULL;
current_item->execute = xstrdup(execute);
current_item->id = xstrdup(id);
} }
current_item = item_create(current_menu, label, /* arrow */ true);
current_item_action = NULL;
current_item->execute = xstrdup(execute);
current_item->id = xstrdup(id);
} else if ((label && id) || is_toplevel_static_menu_definition(n, id)) { } else if ((label && id) || is_toplevel_static_menu_definition(n, id)) {
/* /*
* (label && id) refers to <menu id="" label=""> which is an * (label && id) refers to <menu id="" label=""> which is an
@ -634,6 +639,7 @@ handle_menu_element(xmlNode *n, struct server *server)
} }
++menu_level; ++menu_level;
current_menu = menu_create(server, id, label); current_menu = menu_create(server, id, label);
current_menu->is_pipemenu = false;
if (submenu) { if (submenu) {
*submenu = current_menu; *submenu = current_menu;
} }
@ -657,8 +663,23 @@ handle_menu_element(xmlNode *n, struct server *server)
} }
struct menu *menu = menu_get_by_id(server, id); struct menu *menu = menu_get_by_id(server, id);
if (menu) { if (menu && menu->is_pipemenu) {
/*
* A pipemenu without a parent
*/
current_item = item_create(current_menu, menu->label, true); current_item = item_create(current_menu, menu->label, true);
struct menuitem *item;
wl_list_for_each(item, &menu->menuitems, link) {
current_item->execute = xstrdup(item->execute);
current_item->id = strdup_printf("%s%d",
item->id, rand());
}
} else if (menu) {
/*
* An inline menu defined elsewhere
*/
current_item = item_create(current_menu, menu->label,
true);
if (current_item) { if (current_item) {
current_item->submenu = menu; current_item->submenu = menu;
} }

78
src/menu/menu.c.rej Normal file
View file

@ -0,0 +1,78 @@
--- src/menu/menu.c
+++ src/menu/menu.c
@@ -583,25 +583,30 @@ handle_menu_element(xmlNode *n, struct server *server)
wlr_log(WLR_DEBUG, "pipemenu '%s:%s:%s'", id, label, execute);
if (!current_menu) {
/*
- * We currently do not support pipemenus without a
- * parent <item> such as the one the example below:
+ * pipemenus without a parent
*
* <?xml version="1.0" encoding="UTF-8"?>
* <openbox_menu>
* <menu id="root-menu" label="foo" execute="bar"/>
* </openbox_menu>
- *
- * TODO: Consider supporting this
*/
- wlr_log(WLR_ERROR,
- "pipemenu '%s:%s:%s' has no parent <menu>",
- id, label, execute);
- goto error;
+ current_menu = menu_create(server, id, label);
+ current_menu->is_pipemenu = true;
+ current_item = item_create(current_menu, label,
+ /* arrow */ true);
+ current_item_action = NULL;
+ current_item->execute = xstrdup(execute);
+ current_item->id = xstrdup(id);
+ } else {
+ /*
+ * pipemenus with a parent
+ */
+ current_item = item_create(current_menu, label,
+ /* arrow */ true);
+ current_item_action = NULL;
+ current_item->execute = xstrdup(execute);
+ current_item->id = xstrdup(id);
}
- current_item = item_create(current_menu, label, /* arrow */ true);
- current_item_action = NULL;
- current_item->execute = xstrdup(execute);
- current_item->id = xstrdup(id);
} else if ((label && id) || is_toplevel_static_menu_definition(n, id)) {
/*
* (label && id) refers to <menu id="" label=""> which is an
@@ -634,6 +639,7 @@ handle_menu_element(xmlNode *n, struct server *server)
}
++menu_level;
current_menu = menu_create(server, id, label);
+ current_menu->is_pipemenu = false;
if (submenu) {
*submenu = current_menu;
}
@@ -657,8 +663,23 @@ handle_menu_element(xmlNode *n, struct server *server)
}
struct menu *menu = menu_get_by_id(server, id);
- if (menu) {
+ if (menu && menu->is_pipemenu) {
+ /*
+ * A pipemenu without a parent
+ */
current_item = item_create(current_menu, menu->label, true);
+ struct menuitem *item;
+ wl_list_for_each(item, &menu->menuitems, link) {
+ current_item->execute = xstrdup(item->execute);
+ current_item->id = strdup_printf("%s%d",
+ item->id, rand());
+ }
+ } else if (menu) {
+ /*
+ * An inline menu defined elsewhere
+ */
+ current_item = item_create(current_menu, menu->label,
+ true);
if (current_item) {
current_item->submenu = menu;
}