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

Reply via email to