From aac580d85994b91cc0ff0becb9f2e3266f51252a Mon Sep 17 00:00:00 2001
From: Andreas Bierfert <[email protected]>
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 [email protected].