]> git.mdlowis.com Git - proto/labwc.git/commitdiff
menu: support CDATA for <command> element
authorJohan Malm <jgm323@gmail.com>
Sun, 2 Jul 2023 20:17:26 +0000 (21:17 +0100)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 4 Jul 2023 05:01:47 +0000 (06:01 +0100)
...in order to support obmenu-generator output such as this:

  <menu id="root-menu" label="Applications">
    <item label="File Manager"><action name="Execute"><command><![CDATA[xdg-open .]]></command></action></item>
    <item label="Terminal"><action name="Execute"><command><![CDATA[xterm]]></command></action></item>
    <item label="Web Browser"><action name="Execute"><command><![CDATA[xdg-open http://]]></command></action></item>
    <item label="Run command"><action name="Execute"><command><![CDATA[gmrun]]></command></action></item>
  </menu>

References:
- https://github.com/trizen/obmenu-generator
- https://aur.archlinux.org/packages/obmenu-generator
- https://trizenx.blogspot.com/2012/02/obmenu-generator.html

Fixes: issue #972
docs/labwc-menu.5.scd
src/menu/menu.c

index bae3602159ce0bd42b5c8a8b7be716902b9da657..a121930586cfa06297cc834333a1ab77976b2734 100644 (file)
@@ -48,7 +48,8 @@ A menu file must be entirely enclosed within <openbox_menu> and
        The visible name of the menu item.
 
 *menu.item.action*
-       See labwc-action(5)
+       See labwc-action(5). Note: XML CDATA is supported for this node in
+       order to maintain compatibility with obmenu-generator.
 
 *menu.separator*
        Horizontal line.
index 180575fdf6dafd7ffcbaf183d55015ca4233b42d..ff7bfda85bd6b08228130759da69f54c1918954b 100644 (file)
@@ -14,6 +14,7 @@
 #include "common/buf.h"
 #include "common/font.h"
 #include "common/list.h"
+#include "common/match.h"
 #include "common/mem.h"
 #include "common/nodename.h"
 #include "common/scaled_font_buffer.h"
@@ -300,19 +301,53 @@ item_destroy(struct menuitem *item)
        free(item);
 }
 
+/*
+ * We support XML CDATA for <command> in menu.xml in order to provide backward
+ * compatibility with obmenu-generator. For example:
+ *
+ * <menu id="" label="">
+ *   <item label="">
+ *     <action name="Execute">
+ *       <command><![CDATA[xdg-open .]]></command>
+ *     </action>
+ *   </item>
+ * </menu>
+ *
+ * <execute> is an old, deprecated openbox variety of <command>. We support it
+ * for backward compatibility with old openbox-menu generators. It has the same
+ * function and <command>
+ *
+ * The match_glob() wildcard allows for nested menus giving nodenames with
+ * ...menu.menu... or ...menu.menu.menu... and so on.
+ */
+static bool
+nodename_supports_cdata(char *nodename)
+{
+       return match_glob("command.action.item.*menu.openbox_menu", nodename)
+               || match_glob("execute.action.item.*menu.openbox_menu", nodename);
+}
+
 static void
 entry(xmlNode *node, char *nodename, char *content)
 {
-       if (!nodename || !content) {
+       if (!nodename) {
+               return;
+       }
+       xmlChar *cdata = NULL;
+       if (!content && nodename_supports_cdata(nodename)) {
+               cdata = xmlNodeGetContent(node);
+       }
+       if (!content && !cdata) {
                return;
        }
        string_truncate_at_pattern(nodename, ".openbox_menu");
        if (getenv("LABWC_DEBUG_MENU_NODENAMES")) {
-               printf("%s: %s\n", nodename, content);
+               printf("%s: %s\n", nodename, content ? content : (char *)cdata);
        }
        if (in_item) {
-               fill_item(nodename, content);
+               fill_item(nodename, content ? content : (char *)cdata);
        }
+       xmlFree(cdata);
 }
 
 static void