all repos — openbox @ 22ff8c587d815c021cad13f46094a31cc79243cf

openbox fork - make it a bit more like ryudo

Menu parsing updates for plugins.

FIFO menus are the only plugin that takes advantage of this.
Example:
<menu id="root" label="Openbox 3">
  <menu id="fonk" label="fonk" plugin="fifo_menu">
  </menu>
</menu>

This creates a FIFO ~/.openbox/fifo_menu/fonk to which you can send
menus to. The menus sent to it must be like
<fifo>
  <item>
   etc...
</fifo>

I think. If my memory serves me right.

It is all hideous, but I just wanted to experiment and see if it was
possible.
Scott Moynes smoynes@nexus.carleton.ca
commit

22ff8c587d815c021cad13f46094a31cc79243cf

parent

5fce782499aa821c3a25bfdbf475066c2c21a7ed

5 files changed, 90 insertions(+), 38 deletions(-)

jump to
M openbox/menu.copenbox/menu.c

@@ -18,28 +18,51 @@ ButtonPressMask | ButtonReleaseMask)

static void parse_menu(xmlDocPtr doc, xmlNodePtr node, void *data) { + parse_menu_full(doc, node, data, TRUE); +} + + +void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, + gboolean newmenu) +{ Action *act; xmlNodePtr nact; - gchar *id = NULL, *title = NULL, *label = NULL; - ObMenu *menu, *parent; - if (!parse_attr_string("id", node->parent, &id)) - goto parse_menu_fail; - if (!parse_attr_string("label", node->parent, &title)) - goto parse_menu_fail; + gchar *id = NULL, *title = NULL, *label = NULL, *plugin; + ObMenu *menu = NULL, *parent; - g_message("menu label %s", title); + if (newmenu == TRUE) { + if (!parse_attr_string("id", node->parent, &id)) + goto parse_menu_fail; + if (!parse_attr_string("label", node->parent, &title)) + goto parse_menu_fail; - menu = menu_new(title, id, data ? *((ObMenu**)data) : NULL); - if (data) - *((ObMenu**)data) = menu; + g_message("menu label %s", title); + + menu = menu_new(title, id, data ? *((ObMenu**)data) : NULL); + if (data) + *((ObMenu**)data) = menu; + } else { + menu = (ObMenu *)data; + } + while (node) { if (!xmlStrcasecmp(node->name, (const xmlChar*) "menu")) { - parent = menu; - parse_menu(doc, node->xmlChildrenNode, &parent); - menu_add_entry(menu, menu_entry_new_submenu(parent->label, - parent)); + if (parse_attr_string("plugin", node, &plugin)) { + PluginMenuCreateData data = { + .doc = doc, + .node = node, + .parent = menu + }; + parent = plugin_create(plugin, &data); + } else { + parent = menu; + parse_menu(doc, node->xmlChildrenNode, &parent); + menu_add_entry(menu, menu_entry_new_submenu(parent->label, + parent)); + } + } else if (!xmlStrcasecmp(node->name, (const xmlChar*) "item")) { if (parse_attr_string("label", node, &label)) {
M openbox/menu.hopenbox/menu.h

@@ -96,7 +96,14 @@ RrAppearance *a_disabled;

RrAppearance *a_hilite; gint y; gint min_w; -}; +} MenuEntry; + +typedef struct PluginMenuCreateData{ + xmlDocPtr doc; + xmlNodePtr node; + ObMenu *parent; +} PluginMenuCreateData; + void menu_startup(); void menu_shutdown();

@@ -147,5 +154,7 @@

void menu_render(ObMenu *self); void menu_render_full(ObMenu *self); +//so plugins can call it? +void parse_menu_full(xmlDocPtr doc, xmlNodePtr node, void *data, gboolean new); void menu_control_mouseover(ObMenuEntry *entry, gboolean enter); #endif
M openbox/plugin.copenbox/plugin.c

@@ -176,7 +176,7 @@ g_io_channel_unref(io);

} } -void *plugin_create(char *name /* TODO */) +void *plugin_create(char *name, void *data) { Plugin *p = (Plugin *)g_datalist_get_data(&plugins, name);

@@ -190,7 +190,7 @@ g_critical("Unsupported create/destroy: %s", name);

return NULL; } - return p->create(); + return p->create(data); } void plugin_destroy(char *name, void *data)
M openbox/plugin.hopenbox/plugin.h

@@ -14,7 +14,7 @@ gboolean plugin_open_reopen(char *name);

void plugin_close(char *name); /* call plugin's generic constructor */ -void *plugin_create(char *name /* TODO */); +void *plugin_create(char *name, void *data); /* free memory allocated by plugin_create() */ void plugin_destroy(char *name, void *object);
M plugins/menu/fifo_menu.cplugins/menu/fifo_menu.c

@@ -73,7 +73,8 @@

FIFO_MENU_DATA(menu)->buf = tmpbuf; num_read = read(fd, - FIFO_MENU_DATA(menu)->buf + FIFO_MENU_DATA(menu)->buflen, + FIFO_MENU_DATA(menu)->buf + + FIFO_MENU_DATA(menu)->buflen, num_realloc); if (num_read == 0) { /* eof */

@@ -83,24 +84,25 @@

menu->invalid = TRUE; menu_clear(menu); - /* TEMP: list them */ - while (NULL != - (found = strchr(&FIFO_MENU_DATA(menu)->buf[count], '\n'))) { - FIFO_MENU_DATA(menu)->buf - [found - FIFO_MENU_DATA(menu)->buf] = '\0'; - menu_add_entry(menu, - menu_entry_new_separator - (&FIFO_MENU_DATA(menu)->buf[count])); - count = found - FIFO_MENU_DATA(menu)->buf + 1; - } - FIFO_MENU_DATA(menu)->buf[FIFO_MENU_DATA(menu)->buflen] = '\0'; - fifo_menu_clean_up(menu); + xmlDocPtr doc = xmlParseMemory(FIFO_MENU_DATA(menu)->buf, + FIFO_MENU_DATA(menu)->buflen); + + xmlNodePtr node = xmlDocGetRootElement(doc); + + if (!xmlStrcasecmp(node->name, (const xmlChar*) "fifo")) { + if ((node = parse_find_node("item", node->xmlChildrenNode))) + parse_menu_full(doc, node, menu, FALSE); + } + + fifo_menu_clean_up(menu); + event_remove_fd(FIFO_MENU_DATA(menu)->handler->fd); if ((FIFO_MENU_DATA(menu)->fd = - open(FIFO_MENU_DATA(menu)->fifo, O_NONBLOCK | O_RDONLY)) == -1) { + open(FIFO_MENU_DATA(menu)->fifo, + O_NONBLOCK | O_RDONLY)) == -1) { g_warning("Can't reopen FIFO"); fifo_menu_clean_up(menu); return;

@@ -134,15 +136,31 @@

menu_free(m->name); } -void *plugin_create() /* TODO: need config */ +void *plugin_create(PluginMenuCreateData *data) + + { char *fifo; char *dir; event_fd_handler *h; - - Fifo_Menu_Data *d = g_new(Fifo_Menu_Data, 1); - ObMenu *m = menu_new("", PLUGIN_NAME, NULL); + Fifo_Menu_Data *d; + ObMenu *m; + char *label = NULL, *id = NULL; + + d = g_new(Fifo_Menu_Data, 1); + + parse_attr_string("id", data->node, &id); + parse_attr_string("label", data->node, &label); + m = menu_new( (label != NULL ? label : ""), + (id != NULL ? id : PLUGIN_NAME), + data->parent); + menu_add_entry(data->parent, menu_entry_new_submenu( + (label != NULL ? label : ""), + m)); + + g_free(label); + g_free(id); d->fd = -1; d->buf = NULL; d->buflen = 0;

@@ -154,7 +172,8 @@ d->fd = -1;

m->plugin_data = (void *)d; - dir = g_build_filename(g_get_home_dir(), ".openbox", PLUGIN_NAME, NULL); + dir = g_build_filename(g_get_home_dir(), ".openbox", + PLUGIN_NAME, NULL); if (mkdir(dir, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST) { /* technically, if ~/.openbox/fifo_menu exists and isn't a directory

@@ -166,7 +185,8 @@ plugin_destroy(m);

return NULL; } - fifo = g_build_filename(g_get_home_dir(), ".openbox", PLUGIN_NAME, + fifo = g_build_filename(g_get_home_dir(), ".openbox", + PLUGIN_NAME, m->name, NULL); if (mkfifo(fifo, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | /* let umask do its thing */