[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