[WindowMaker] 0.95.4-5

Andreas Bierfert awjb at fedoraproject.org
Sun Feb 10 11:48:00 UTC 2013


commit 9bcf7d5ab3880afc42fb1c860a5da6884cd29474
Author: Andreas Bierfert <andreas.bierfert at lowlatency.de>
Date:   Sun Feb 10 12:47:50 2013 +0100

    0.95.4-5
    
    - add proplist menu code from git

 ...WINGS-New-function-WMReadPropListFromPipe.patch |   97 +++++++++
 ...MENU-option-to-parse-command-generated-pr.patch |  171 ++++++++++++++++
 0003-Teach-WPrefs-about-OPEN_PLMENU.patch          |  210 ++++++++++++++++++++
 WindowMaker.spec                                   |   19 ++-
 4 files changed, 496 insertions(+), 1 deletions(-)
---
diff --git a/0001-WINGS-New-function-WMReadPropListFromPipe.patch b/0001-WINGS-New-function-WMReadPropListFromPipe.patch
new file mode 100644
index 0000000..1039631
--- /dev/null
+++ b/0001-WINGS-New-function-WMReadPropListFromPipe.patch
@@ -0,0 +1,97 @@
+From 9d33224c1294f6d0dd80d3f24b290d406af7711f Mon Sep 17 00:00:00 2001
+From: Andreas Bierfert <andreas.bierfert at lowlatency.de>
+Date: Sun, 10 Feb 2013 10:39:27 +0100
+Subject: [PATCH 1/3] 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
+---
+ WINGs/WINGs/WUtil.h |  2 ++
+ WINGs/proplist.c    | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 56 insertions(+)
+
+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)
+-- 
+1.8.1.2
+
diff --git a/0002-Add-OPEN_PLMENU-option-to-parse-command-generated-pr.patch b/0002-Add-OPEN_PLMENU-option-to-parse-command-generated-pr.patch
new file mode 100644
index 0000000..1231506
--- /dev/null
+++ b/0002-Add-OPEN_PLMENU-option-to-parse-command-generated-pr.patch
@@ -0,0 +1,171 @@
+From 4d68d6808190bc591806833fd122522c62039117 Mon Sep 17 00:00:00 2001
+From: Andreas Bierfert <andreas.bierfert at lowlatency.de>
+Date: Sun, 10 Feb 2013 10:51:02 +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"
+)
+
+v2: code cleanup
+---
+ src/rootmenu.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 101 insertions(+)
+
+diff --git a/src/rootmenu.c b/src/rootmenu.c
+index 2fcd0ae..ed5a865 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,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)
+@@ -786,6 +842,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 +1052,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.2
+
diff --git a/0003-Teach-WPrefs-about-OPEN_PLMENU.patch b/0003-Teach-WPrefs-about-OPEN_PLMENU.patch
new file mode 100644
index 0000000..1d81f71
--- /dev/null
+++ b/0003-Teach-WPrefs-about-OPEN_PLMENU.patch
@@ -0,0 +1,210 @@
+From ee644287c5943a3d7fb9f5404815ecb81fc66459 Mon Sep 17 00:00:00 2001
+From: Andreas Bierfert <andreas.bierfert at lowlatency.de>
+Date: Sun, 10 Feb 2013 10:54:59 +0100
+Subject: [PATCH 3/3] Teach WPrefs about OPEN_PLMENU
+
+Add option to WPrefs to read, add and edit OPEN_PLMENU menu entries
+---
+ WPrefs.app/Menu.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 85 insertions(+), 1 deletion(-)
+
+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 menu\n" "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 for\n" "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
+-- 
+1.8.1.2
+
diff --git a/WindowMaker.spec b/WindowMaker.spec
index eb3c2ac..57a455d 100644
--- a/WindowMaker.spec
+++ b/WindowMaker.spec
@@ -1,7 +1,7 @@
 Summary:        A fast, feature rich Window Manager
 Name:           WindowMaker
 Version:        0.95.4
-Release:        4%{?dist}
+Release:        5%{?dist}
 License:        GPLv2+
 Group:          User Interface/Desktops
 URL:            http://www.windowmaker.org 
@@ -27,6 +27,15 @@ Patch0:         0001-Fix-underlinking.patch
 Patch1:         0001-Fix-incorrect-FSF-address.patch
 Patch2:         0002-Include-LGPL-with-correct-FSF-address.patch
 
+# add proplist menu code from git
+# see
+# http://repo.or.cz/w/wmaker-crm.git/commit/cc69d2aae38b5563d39d3348cec805ed8b3d753d
+# http://repo.or.cz/w/wmaker-crm.git/commit/c21ae6b580889d247408123a5c624abf6d784232
+# http://repo.or.cz/w/wmaker-crm.git/commit/066de301df2f07c614b77e7a2bbadd9ff1342e46
+Patch3:         0001-WINGS-New-function-WMReadPropListFromPipe.patch
+Patch4:         0002-Add-OPEN_PLMENU-option-to-parse-command-generated-pr.patch
+Patch5:         0003-Teach-WPrefs-about-OPEN_PLMENU.patch
+
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-buildroot
 # X BR
 BuildRequires:  libICE-devel
@@ -118,6 +127,10 @@ icons and a few themes.
 %patch1 -p1 -b .fixfsfaddress
 %patch2 -p1 -b .usecurrentlgpl
 
+%patch3 -p1 -b .wmreadproplistfrompipe
+%patch4 -p1 -b .openplmenu
+%patch5 -p1 -b .wprefsopenplmenu
+
 # add uk translation
 cp %{SOURCE3} po/uk.po
 cp %{SOURCE4} WPrefs.app/po/uk.po
@@ -311,6 +324,10 @@ rm -rf $RPM_BUILD_ROOT
 %{_mandir}/man1/get-wutil-flags*
 
 %changelog
+* Sun Feb 10 2013 Andreas Bierfert <andreas.bierfert[AT]lowlatency.de>
+- 0.95.4-5
+- add proplist menu code from git
+
 * Fri Jan 18 2013 Adam Tkac <atkac redhat com> - 0.95.4-4
 - rebuild due to "jpeg8-ABI" feature drop
 


More information about the scm-commits mailing list