This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project wmaker-crm.git.
The branch, next has been updated via 066de301df2f07c614b77e7a2bbadd9ff1342e46 (commit) via c21ae6b580889d247408123a5c624abf6d784232 (commit) via cc69d2aae38b5563d39d3348cec805ed8b3d753d (commit) from a657fafcceaeafbd8395068268b1a2117cf7db0b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- http://repo.or.cz/w/wmaker-crm.git/commit/066de301df2f07c614b77e7a2bbadd9ff1342e46 commit 066de301df2f07c614b77e7a2bbadd9ff1342e46 Author: Andreas Bierfert <andreas.bierf...@lowlatency.de> Date: Thu Jan 31 22:44:34 2013 +0100 Teach WPrefs about OPEN_PLMENU From 35f19d77874d1b50de5505b6b1cb31531e1c055a Mon Sep 17 00:00:00 2001 From: Andreas Bierfert <andreas.bierf...@lowlatency.de> Date: Thu, 31 Jan 2013 22:35:42 +0100 Subject: [PATCH 3/3] Teach WPrefs about OPEN_PLMENU Add option to WPrefs to read, add and edit OPEN_PLMENU menu entries diff --git a/WPrefs.app/Menu.c b/WPrefs.app/Menu.c index 4a8cc94..3edb84a 100644 --- a/WPrefs.app/Menu.c +++ b/WPrefs.app/Menu.c @@ -34,6 +34,7 @@ typedef enum { CommandInfo, ExternalInfo, PipeInfo, + PLPipeInfo, DirectoryInfo, WSMenuInfo, WWindowListInfo, @@ -82,6 +83,10 @@ typedef struct _Panel { WMTextField *pipeT; WMButton *pipeCacheB; + WMFrame *plpipeF; + WMTextField *plpipeT; + WMButton *plpipeCacheB; + WMFrame *dpathF; WMTextField *dpathT; @@ -391,6 +396,7 @@ static void createPanel(_Panel * p) panel->markerPix[ExternalInfo] = pixm; panel->markerPix[PipeInfo] = pixm; + panel->markerPix[PLPipeInfo] = pixm; panel->markerPix[DirectoryInfo] = pixm; panel->markerPix[WSMenuInfo] = pixm; panel->markerPix[WWindowListInfo] = pixm; @@ -424,6 +430,7 @@ static void createPanel(_Panel * p) putNewSubmenu(pad, _("Submenu")); putNewItem(panel, pad, ExternalInfo, _("External Submenu")); putNewItem(panel, pad, PipeInfo, _("Generated Submenu")); + putNewItem(panel, pad, PLPipeInfo, _("Generated PL Menu")); putNewItem(panel, pad, DirectoryInfo, _("Directory Contents")); putNewItem(panel, pad, WSMenuInfo, _("Workspace Menu")); putNewItem(panel, pad, WWindowListInfo, _("Window List Menu")); @@ -642,6 +649,31 @@ static void createPanel(_Panel * p) WMMapSubwidgets(panel->pipeF); + /* proplist pipe */ + + panel->plpipeF = WMCreateFrame(panel->optionsF); + WMResizeWidget(panel->plpipeF, width, 155); + WMMoveWidget(panel->plpipeF, 10, 30); + WMSetFrameTitle(panel->plpipeF, _("Command")); + + panel->plpipeT = WMCreateTextField(panel->plpipeF); + WMResizeWidget(panel->plpipeT, width - 20, 20); + WMMoveWidget(panel->plpipeT, 10, 20); + + WMAddNotificationObserver(dataChanged, panel, WMTextDidChangeNotification, panel->plpipeT); + + label = WMCreateLabel(panel->plpipeF); + WMResizeWidget(label, width - 20, 40); + WMMoveWidget(label, 10, 50); + WMSetLabelText(label, _("Enter a command that outputs a proplist menun" "definition to stdout when invoked.")); + + panel->plpipeCacheB = WMCreateSwitchButton(panel->plpipeF); + WMResizeWidget(panel->plpipeCacheB, width - 20, 40); + WMMoveWidget(panel->plpipeCacheB, 10, 110); + WMSetButtonText(panel->plpipeCacheB, _("Cache menu contents after opening forn" "the first time")); + + WMMapSubwidgets(panel->plpipeF); + /* directory menu */ panel->dcommandF = WMCreateFrame(panel->optionsF); @@ -790,6 +822,8 @@ static void createPanel(_Panel * p) panel->sections[PipeInfo][0] = panel->pipeF; + panel->sections[PLPipeInfo][0] = panel->plpipeF; + panel->sections[DirectoryInfo][0] = panel->dpathF; panel->sections[DirectoryInfo][1] = panel->dcommandF; @@ -835,6 +869,10 @@ static void freeItemData(ItemData * data) CFREE(data->param.pipe.command); break; + case PLPipeInfo: + CFREE(data->param.pipe.command); + break; + case ExternalInfo: CFREE(data->param.external.path); break; @@ -941,6 +979,22 @@ static ItemData *parseCommand(WMPropList * item) data->param.external.path = p; } } + } else if (strcmp(command, "OPEN_PLMENU") == 0) { + char *p; + + p = parameter; + while (isspace(*p) && *p) + p++; + if (*p == '|') { + if (*(p + 1) == '|') { + p++; + data->param.pipe.cached = 0; + } else { + data->param.pipe.cached = 1; + } + data->type = PLPipeInfo; + data->param.pipe.command = wtrimspace(p + 1); + } } else if (strcmp(command, "WORKSPACE_MENU") == 0) { data->type = WSMenuInfo; } else if (strcmp(command, "WINDOWS_MENU") == 0) { @@ -1014,6 +1068,10 @@ static void updateFrameTitle(_Panel * panel, char *title, InfoType type) tmp = wstrconcat(title, _(": Program Generated Submenu")); break; + case PLPipeInfo: + tmp = wstrconcat(title, _(": Program Generated Proplist Submenu")); + break; + case DirectoryInfo: tmp = wstrconcat(title, _(": Directory Contents Menu")); break; @@ -1117,6 +1175,15 @@ static void updateMenuItem(_Panel * panel, WEditMenuItem * item, WMWidget * chan } break; + case PLPipeInfo: + if (changedWidget == panel->plpipeT) { + REPLACE(data->param.pipe.command, WMGetTextFieldText(panel->plpipeT)); + } + if (changedWidget == panel->plpipeCacheB) { + data->param.pipe.cached = WMGetButtonSelected(panel->plpipeCacheB); + } + break; + case ExternalInfo: if (changedWidget == panel->pathT) { REPLACE(data->param.external.path, WMGetTextFieldText(panel->pathT)); @@ -1175,6 +1242,11 @@ menuItemCloned(WEditMenuDelegate * delegate, WEditMenu * menu, WEditMenuItem * o newData->param.pipe.cached = data->param.pipe.cached; break; + case PLPipeInfo: + newData->param.pipe.command = DUP(data->param.pipe.command); + newData->param.pipe.cached = data->param.pipe.cached; + break; + case ExternalInfo: newData->param.external.path = DUP(data->param.external.path); break; @@ -1284,6 +1356,11 @@ static void menuItemSelected(WEditMenuDelegate * delegate, WEditMenu * menu, WEd WMSetButtonSelected(panel->pipeCacheB, data->param.pipe.cached); break; + case PLPipeInfo: + WMSetTextFieldText(panel->plpipeT, data->param.pipe.command); + WMSetButtonSelected(panel->plpipeCacheB, data->param.pipe.cached); + break; + case ExternalInfo: WMSetTextFieldText(panel->pathT, data->param.external.path); break; @@ -1459,6 +1536,7 @@ static WMPropList *processData(char *title, ItemData * data) char *s1; static WMPropList *pscut = NULL; static WMPropList *pomenu = NULL; + static WMPropList *poplmenu = NULL; int i; if (data == NULL) @@ -1467,6 +1545,7 @@ static WMPropList *processData(char *title, ItemData * data) if (!pscut) { pscut = WMCreatePLString("SHORTCUT"); pomenu = WMCreatePLString("OPEN_MENU"); + poplmenu = WMCreatePLString("OPEN_PLMENU"); } item = WMCreatePLArray(WMCreatePLString(title), NULL); @@ -1522,9 +1601,14 @@ static WMPropList *processData(char *title, ItemData * data) break; case PipeInfo: + case PLPipeInfo: if (!data->param.pipe.command) return NULL; - WMAddToPLArray(item, pomenu); + if (data->type == PLPipeInfo) + WMAddToPLArray(item, poplmenu); + else + WMAddToPLArray(item, pomenu); + if (data->param.pipe.cached) s1 = wstrconcat("| ", data->param.pipe.command); else http://repo.or.cz/w/wmaker-crm.git/commit/c21ae6b580889d247408123a5c624abf6d784232 commit c21ae6b580889d247408123a5c624abf6d784232 Author: Andreas Bierfert <andreas.bierf...@lowlatency.de> Date: Sun Feb 10 10:56:20 2013 +0100 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" ) v2: code cleanup diff --git a/src/rootmenu.c b/src/rootmenu.c index 0b263cd..5b8ff90 100644 --- a/src/rootmenu.c +++ b/src/rootmenu.c @@ -63,6 +63,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); @@ -119,6 +120,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 @@ -574,6 +581,8 @@ static WMenu *constructPLMenu(WScreen *screen, char *path) return menu; } + + static void constructMenu(WMenu * menu, WMenuEntry * entry) { WMenu *submenu; @@ -696,6 +705,53 @@ 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); + } + + 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) @@ -787,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); @@ -980,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) { http://repo.or.cz/w/wmaker-crm.git/commit/cc69d2aae38b5563d39d3348cec805ed8b3d753d commit cc69d2aae38b5563d39d3348cec805ed8b3d753d Author: Andreas Bierfert <andreas.bierf...@lowlatency.de> Date: Thu Jan 31 22:44:28 2013 +0100 WINGS: New function WMReadPropListFromPipe This functions reads a proplist from a pipe instead of a file (like WMReadPropListFromFile does). It uses a call to popen to open the desired command, reads data into a buffer till EOF and passes the data to getPropList for parsing. v2: code cleanup diff --git a/WINGs/WINGs/WUtil.h b/WINGs/WINGs/WUtil.h index 30476e0..84f60b9 100644 --- a/WINGs/WINGs/WUtil.h +++ b/WINGs/WINGs/WUtil.h @@ -807,6 +807,8 @@ char* WMGetPropListDescription(WMPropList *plist, Bool indented); WMPropList* WMReadPropListFromFile(char *file); +WMPropList* WMReadPropListFromPipe(char *command); + Bool WMWritePropListToFile(WMPropList *plist, char *path); /* ---[ WINGs/userdefaults.c ]-------------------------------------------- */ diff --git a/WINGs/proplist.c b/WINGs/proplist.c index 7b0f49d..7a80f50 100644 --- a/WINGs/proplist.c +++ b/WINGs/proplist.c @@ -1545,6 +1545,60 @@ WMPropList *WMReadPropListFromFile(char *file) return plist; } +WMPropList *WMReadPropListFromPipe(char *command) +{ + FILE *file; + WMPropList *plist; + PLData *pldata; + char line[1024]; + + file = popen(command, "r"); + + if (!file) { + werror(_("%s:could not open menu file"), command); + return NULL; + } + + pldata = (PLData *) wmalloc(sizeof(PLData)); + pldata->ptr = NULL; + pldata->filename = command; + pldata->lineNumber = 1; + + /* read from file till EOF or OOM and fill proplist buffer*/ + while (fgets(line, sizeof(line), file) != NULL) { + if (pldata->ptr == NULL) { + pldata->ptr = wmalloc(strlen(line)+1); + pldata->ptr[0] = '0'; + } else { + pldata->ptr = wrealloc(pldata->ptr, + strlen(line) + strlen(pldata->ptr) + 1); + } + + pldata->ptr = strncat(pldata->ptr, line, strlen(line)); + } + + pclose(file); + + plist = getPropList(pldata); + + if (getNonSpaceChar(pldata) != 0 && plist) { + COMPLAIN(pldata, _("extra data after end of property list")); + /* + * We can't just ignore garbage after the end of the description + * (especially if the description was read from a file), because + * the "garbage" can be the real data and the real garbage is in + * fact in the beginning of the file (which is now inside plist) + */ + WMReleasePropList(plist); + plist = NULL; + } + + wfree(pldata->ptr); + wfree(pldata); + + return plist; +} + /* TODO: review this function's code */ Bool WMWritePropListToFile(WMPropList * plist, char *path) ----------------------------------------------------------------------- Summary of changes: WINGs/WINGs/WUtil.h | 2 + WINGs/proplist.c | 54 +++++++++++++++++++++++++++ WPrefs.app/Menu.c | 86 +++++++++++++++++++++++++++++++++++++++++++- src/rootmenu.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 242 insertions(+), 1 deletions(-) repo.or.cz automatic notification. Contact project admin crma...@gmail.com if you want to unsubscribe, or site admin ad...@repo.or.cz if you receive no reply. -- wmaker-crm.git ("The Window Maker window manager") -- To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.