Hi,
We had a strange situation where putting the menu in stdin was difficult.
For our situation supplying the menu on the command line would be easier.
Attached is a patch that provides this.
The new syntax is
dmenu -m "hello\nworld"
or use the -d flag to specify the seperator
dmenu -m "hello%world" -d "%"
The old style still works.
Hope this helps someone.
Mex.
Only in dmenu-4.0/: dmenu
diff -u dmenu.old/dmenu-4.0/dmenu.c dmenu-4.0/dmenu.c
--- dmenu.old/dmenu-4.0/dmenu.c 2009-04-18 12:50:04.000000000 +0100
+++ dmenu-4.0/dmenu.c 2010-05-11 11:43:37.026266509 +0100
@@ -89,6 +89,9 @@
static int (*fstrncmp)(const char *, const char *, size_t n) = strncmp;
static char *(*fstrstr)(const char *, const char *) = strstr;
+static char* menuoncommandline = 0;
+static char* menudeliminator = "\n";
+
void
appenditem(Item *i, Item **list, Item **last) {
if(!(*last))
@@ -160,10 +163,12 @@
free(allitems);
allitems = itm;
}
- if(dc.font.set)
+ if(dc.font.set) {
XFreeFontSet(dpy, dc.font.set);
- else
+ }
+ else {
XFreeFont(dpy, dc.font.xfont);
+ }
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, win);
@@ -663,6 +668,33 @@
return textnw(text, strlen(text)) + dc.font.height;
}
+void
+commandlinemenu(const char *menu_p, const char* deliminator) {
+ Item *it, *new;
+ char* m_item = NULL;
+ char* menu = strdup(menu_p);
+
+ it = NULL;
+
+ if (menu == NULL) eprint("Failed to malloc \"menu\"");
+
+ for (m_item = strtok(menu, deliminator); m_item; m_item = strtok(NULL, deliminator)){
+ if(!(new = (Item *)malloc(sizeof(Item))))
+ eprint("fatal: could not malloc() %u bytes\n", sizeof(Item));
+ new->next = new->left = new->right = NULL;
+ new->text = strdup(m_item);
+ if (new->text == NULL) eprint("Failed to malloc \"new->text\"");
+
+ if(!it)
+ allitems = new;
+ else
+ it->next = new;
+ it = new;
+ }
+
+ free (menu);
+}
+
int
main(int argc, char *argv[]) {
unsigned int i;
@@ -693,26 +725,41 @@
}
else if(!strcmp(argv[i], "-sf")) {
if(++i < argc) selfgcolor = argv[i];
- }
- else if(!strcmp(argv[i], "-v"))
+ } else if (!strcmp(argv[i], "-m")) {
+ if (++i < argc) menuoncommandline = argv[i];
+ else eprint("-m missing parameter\n");
+ } else if (!strcmp(argv[i], "-d")) {
+ if (++i < argc) menudeliminator = argv[i];
+ else eprint("-d missing parameter\n");
+ } else if(!strcmp(argv[i], "-v"))
eprint("dmenu-"VERSION", © 2006-2008 dmenu engineers, see LICENSE for details\n");
else
eprint("usage: dmenu [-i] [-b] [-fn <font>] [-nb <color>] [-nf <color>]\n"
- " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n");
+ " [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"
+ " [-m <menu>] [-d <deliminator>]\n");
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fprintf(stderr, "warning: no locale support\n");
if(!(dpy = XOpenDisplay(NULL)))
eprint("dmenu: cannot open display\n");
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
+
+ if (menuoncommandline) {
+ commandlinemenu(menuoncommandline, menudeliminator);
+ }
if(isatty(STDIN_FILENO)) {
- readstdin();
+ if (menuoncommandline == NULL) {
+ readstdin();
+ }
running = grabkeyboard();
}
- else { /* prevent keypress loss */
+ else { /* prevent keypress loss */
running = grabkeyboard();
- readstdin();
+
+ if (menuoncommandline == NULL) {
+ readstdin();
+ }
}
setup(topbar);
Only in dmenu-4.0/: dmenuCommandLine.diff
Only in dmenu-4.0/: dmenu.o