From aac580d85994b91cc0ff0becb9f2e3266f51252a Mon Sep 17 00:00:00 2001
From: Andreas Bierfert <andreas.bierf...@lowlatency.de>
Date: Thu, 31 Jan 2013 17:21:48 +0100
Subject: [PATCH 2/3] Add OPEN_PLMENU option to parse command generated
 proplist style menus

This patch adds the OPEN_PLMENU options which behaves similar to OPEN_MENU but
can be used to parse command generated proplists. This can be used e.g. in
conjunction with wmmenugen like:
(
    "Generated PL Submenu",
    OPEN_PLMENU,
    "|| find /usr/share/applications -type f -name '*desktop' | xargs wmmenugen 
-parser:xdg"
)
---
 src/rootmenu.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/src/rootmenu.c b/src/rootmenu.c
index 2fcd0ae..9b836cb 100644
--- a/src/rootmenu.c
+++ b/src/rootmenu.c
@@ -62,6 +62,7 @@ extern Cursor wCursor[WCUR_LAST];
 extern WPreferences wPreferences;
 
 static WMenu *readMenuPipe(WScreen * scr, char **file_name);
+static WMenu *readPLMenuPipe(WScreen * scr, char **file_name);
 static WMenu *readMenuFile(WScreen * scr, char *file_name);
 static WMenu *readMenuDirectory(WScreen * scr, char *title, char **file_name, 
char *command);
 static WMenu *configureMenu(WScreen * scr, WMPropList * definition, Bool 
includeGlobals);
@@ -118,6 +119,12 @@ static Shortcut *shortcutList = NULL;
  *                command must be a valid menu description.
  *                The space between '|' and command is optional.
  *                || will do the same, but will not cache the contents.
+ * OPEN_PLMENU | command
+ *             - opens command and uses its stdout which must be in proplist
+ *               fromat to construct and insert the resulting menu in current
+ *               position.
+ *               The space between '|' and command is optional.
+ *               || will do the same, but will not cache the contents.
  * SAVE_SESSION - saves the current state of the desktop, which include
  *               all running applications, all their hints (geometry,
  *               position on screen, workspace they live on, the dock
@@ -573,6 +580,8 @@ static WMenu *constructPLMenu(WScreen *screen, char *path)
        return menu;
 }
 
+
+
 static void constructMenu(WMenu * menu, WMenuEntry * entry)
 {
        WMenu *submenu;
@@ -695,6 +704,54 @@ static void constructMenu(WMenu * menu, WMenuEntry * entry)
                wfree(cmd);
 }
 
+static void *constructPLMenuFromPipe(WMenu * menu, WMenuEntry * entry)
+{
+       WMenu *submenu = NULL;
+       char **path;
+       char *cmd;
+       int i;
+
+       separateCommand((char *)entry->clientdata, &path, &cmd);
+       if (path == NULL || *path == NULL || **path == 0) {
+               wwarning(_("invalid OPEN_PLMENU specification: %s"),
+                   (char *)entry->clientdata);
+               if (cmd)
+                       wfree(cmd);
+               return;
+       }
+
+       if (path[0][0] == '|') {
+               /* pipe menu */
+
+               if (!menu->cascades[entry->cascade]
+               || menu->cascades[entry->cascade]->timestamp == 0) {
+                       /* parse pipe */
+                       submenu = readPLMenuPipe(menu->frame->screen_ptr, path);
+
+                       if (submenu != NULL) {
+                               if (path[0][1] == '|')
+                                       submenu->timestamp = 0;
+                               else
+                                       submenu->timestamp = 1; /* there's no 
automatic reloading */
+                       }
+               }
+       }
+
+       if (submenu) {
+               wMenuEntryRemoveCascade(menu, entry);
+               wMenuEntrySetCascade(menu, entry, submenu);
+       }
+
+ finish:
+       i = 0;
+       while (path[i] != NULL)
+               wfree(path[i++]);
+
+       wfree(path);
+       if (cmd)
+               wfree(cmd);
+
+}
 static void cleanupWorkspaceMenu(WMenu * menu)
 {
        if (menu->frame->screen_ptr->workspace_menu == menu)
@@ -786,6 +843,23 @@ static WMenuEntry *addMenuEntry(WMenu * menu, char *title, 
char *shortcut, char
                        entry->free_cdata = wfree;
                        wMenuEntrySetCascade(menu, entry, dummy);
                }
+       } else if (strcmp(command, "OPEN_PLMENU") == 0) {
+               if (!params) {
+                       wwarning(_("%s:missing parameter for menu command 
\"%s\""), file_name, command);
+               } else {
+                       WMenu *dummy;
+                       char *path;
+
+                       path = wfindfile(DEF_CONFIG_PATHS, params);
+                       if (!path)
+                               path = wstrdup(params);
+
+                       dummy = wMenuCreate(scr, title, False);
+                       dummy->on_destroy = removeShortcutsForMenu;
+                       entry = wMenuAddCallback(menu, title, 
constructPLMenuFromPipe, path);
+                       entry->free_cdata = wfree;
+                       wMenuEntrySetCascade(menu, entry, dummy);
+               }
        } else if (strcmp(command, "EXEC") == 0) {
                if (!params)
                        wwarning(_("%s:missing parameter for menu command 
\"%s\""), file_name, command);
@@ -979,6 +1053,34 @@ static WMenu *readMenuFile(WScreen * scr, char *file_name)
 }
 
 /************    Menu Configuration From Pipe      *************/
+static WMenu *readPLMenuPipe(WScreen * scr, char **file_name)
+{
+       WMPropList *plist = NULL;
+       WMenu *menu = NULL;
+       char *filename;
+       char flat_file[MAXLINE];
+       int i;
+
+       flat_file[0] = '\0';
+
+       for (i = 0; file_name[i] != NULL; i++) {
+               strcat(flat_file, file_name[i]);
+               strcat(flat_file, " ");
+       }
+       filename = flat_file + (flat_file[1] == '|' ? 2 : 1);
+
+       plist = WMReadPropListFromPipe(filename);
+
+       if (!plist)
+               return NULL;
+
+       menu = configureMenu(scr, plist, False);
+       if (!menu)
+               return NULL;
+
+       menu->on_destroy = removeShortcutsForMenu;
+       return menu;
+}
 
 static WMenu *readMenuPipe(WScreen * scr, char **file_name)
 {
-- 
1.8.1


--
To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to