dmenu

dynamic menu
git clone git://git.suckless.org/dmenu
Log | Files | Refs | README | LICENSE

commit a7aee433ccfd2590e0785a7b93a89d8d0593a234
parent a3606ecb0eeaffa752fdf26565ebaaba29b83239
Author: Connor Lane Smith <cls@lubutu.com>
Date:   Mon,  2 Aug 2010 14:22:54 +0100

fixed bugs, no more config.h, updated manpage, new libdraw
Diffstat:
MMakefile | 24++++++++----------------
MREADME | 11++++++-----
Dconfig.def.h | 8--------
Mconfig.mk | 17+++++++----------
Mdmenu.1 | 98+++++++++++++++++++++++++++++++++++++------------------------------------------
Mdmenu.c | 222++++++++++++++++++++++++++++++++++---------------------------------------------
Mdmenu_path | 2+-
7 files changed, 162 insertions(+), 220 deletions(-)

diff --git a/Makefile b/Makefile @@ -3,9 +3,6 @@ include config.mk -SRC = dmenu.c -OBJ = ${SRC:.c=.o} - all: options dmenu options: @@ -14,34 +11,28 @@ options: @echo "LDFLAGS = ${LDFLAGS}" @echo "CC = ${CC}" -.c.o: +dmenu.o: dmenu.c config.mk @echo CC $< @${CC} -c ${CFLAGS} $< -${OBJ}: config.h config.mk - -config.h: - @echo creating $@ from config.def.h - @cp config.def.h $@ - -dmenu: ${OBJ} +dmenu: dmenu.o @echo CC -o $@ @${CC} -o $@ $+ ${LDFLAGS} clean: @echo cleaning - @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu.o dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp -R LICENSE Makefile README config.mk dmenu.1 config.def.h dmenu_path dmenu_run ${SRC} dmenu-${VERSION} + @cp -R LICENSE Makefile README config.mk dmenu.1 dmenu.c dmenu_path dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} install: all - @echo installing executable file to ${DESTDIR}${PREFIX}/bin + @echo installing executables to ${DESTDIR}${PREFIX}/bin @mkdir -p ${DESTDIR}${PREFIX}/bin @cp -f dmenu dmenu_path dmenu_run ${DESTDIR}${PREFIX}/bin @chmod 755 ${DESTDIR}${PREFIX}/bin/dmenu @@ -53,8 +44,9 @@ install: all @chmod 644 ${DESTDIR}${MANPREFIX}/man1/dmenu.1 uninstall: - @echo removing executable file from ${DESTDIR}${PREFIX}/bin - @rm -f ${DESTDIR}${PREFIX}/bin/dmenu ${DESTDIR}${PREFIX}/bin/dmenu_path + @echo removing executables from ${DESTDIR}${PREFIX}/bin + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu + @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_path @rm -f ${DESTDIR}${PREFIX}/bin/dmenu_run @echo removing manual page from ${DESTDIR}${MANPREFIX}/man1 @rm -f ${DESTDIR}${MANPREFIX}/man1/dmenu.1 diff --git a/README b/README @@ -1,21 +1,22 @@ dmenu - dynamic menu ==================== -dmenu is a generic and efficient menu for X. +dmenu is an efficient dynamic menu for X. Requirements ------------ In order to build dmenu you need the Xlib header files. + You also need libdraw, available from http://hg.suckless.org/libdraw Installation ------------ -Edit config.mk to match your local setup (dmenu is installed into the -/usr/local namespace by default). +Edit config.mk to match your local setup (dmenu is installed into +the /usr/local namespace by default). -Afterwards enter the following command to build and install dmenu (if -necessary as root): +Afterwards enter the following command to build and install dmenu +(if necessary as root): make clean install diff --git a/config.def.h b/config.def.h @@ -1,8 +0,0 @@ -/* See LICENSE file for copyright and license details. */ - -/* appearance */ -static const char *font = "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"; -static const char *normbgcolor = "#cccccc"; -static const char *normfgcolor = "#000000"; -static const char *selbgcolor = "#0066ff"; -static const char *selfgcolor = "#ffffff"; diff --git a/config.mk b/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.1.1 +VERSION = 4.2 # Customize below to fit your system @@ -7,25 +7,22 @@ VERSION = 4.1.1 PREFIX = /usr/local MANPREFIX = ${PREFIX}/share/man +# Xlib X11INC = /usr/X11R6/include X11LIB = /usr/X11R6/lib # Xinerama, comment if you don't want it -XINERAMALIBS = -L${X11LIB} -lXinerama +XINERAMALIBS = -lXinerama XINERAMAFLAGS = -DXINERAMA # includes and libs -INCS = -I. -I/usr/include -I${X11INC} -LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 -ldraw ${XINERAMALIBS} +INCS = -I${X11INC} +LIBS = -L${X11LIB} -ldraw -lX11 ${XINERAMALIBS} # flags CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} -LDFLAGS = -s ${LIBS} - -# Solaris -#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = ${LIBS} +CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} +LDFLAGS = -s ${LIBS} # compiler and linker CC = cc diff --git a/dmenu.1 b/dmenu.1 @@ -5,81 +5,76 @@ dmenu \- dynamic menu .B dmenu .RB [ \-b ] .RB [ \-i ] -.RB [ \-l " <lines>]" -.RB [ \-p " <prompt>]" -.RB [ \-fn " <font>]" -.RB [ \-nb " <color>]" -.RB [ \-nf " <color>]" -.RB [ \-sb " <color>]" -.RB [ \-sf " <color>]" +.RB [ \-l +.IR lines ] +.RB [ \-p +.IR prompt ] +.RB [ \-fn +.IR font ] +.RB [ \-nb +.IR color ] +.RB [ \-nf +.IR color ] +.RB [ \-sb +.IR color ] +.RB [ \-sf +.IR color ] .RB [ \-v ] - -.B dmenu_run -.RB [ \-b ] -.RB [ \-i ] -.RB [ \-l " <lines>]" -.RB [ \-p " <prompt>]" -.RB [ \-fn " <font>]" -.RB [ \-nb " <color>]" -.RB [ \-nf " <color>]" -.RB [ \-sb " <color>]" -.RB [ \-sf " <color>]" -.RB [ \-v ] - +.P +.BR dmenu_run " ..." +.P .B dmenu_path .SH DESCRIPTION -.SS Overview .B dmenu -is a generic menu for X, originally designed for +is a dynamic menu for X, originally designed for .BR dwm (1). -It manages huge amounts (10000 and more) of user defined menu items efficiently. +It manages huge numbers of user-defined menu items efficiently. +.P +dmenu reads a list of newline-separated items from standard input and creates a +menu. When the user selects an item or enters any text and presses Return, +their choice is printed to standard output and dmenu terminates. .P .B dmenu_run -is a dmenu script which lists programs in the user's PATH and executes -the selected item. +is a dmenu script used by dwm which lists programs in the user's PATH and +executes the selected item. .P .B dmenu_path -is a script used by -.I dmenu_run -to find and cache a list of programs. -.SS Options +is a script used by dmenu_run to find and cache a list of programs. +.SH OPTIONS .TP .B \-b dmenu appears at the bottom of the screen. .TP .B \-i -dmenu matches menu entries case insensitively. +dmenu matches menu items case insensitively. .TP -.B \-l <lines> +.BI \-l " lines" dmenu lists items vertically, with the given number of lines. .TP -.B \-p <prompt> -sets the prompt to be displayed to the left of the input area. +.BI \-p " prompt" +defines the prompt to be displayed to the left of the input area. .TP -.B \-fn <font> -sets the font. +.BI \-fn " font" +defines the font set used. .TP -.B \-nb <color> -sets the background color (#RGB, #RRGGBB, and color names are supported). +.BI \-nb " color" +defines the normal background color. +.IR #RGB , +.IR #RRGGBB , +and color names are supported. .TP -.B \-nf <color> -sets the foreground color (#RGB, #RRGGBB, and color names are supported). +.BI \-nf " color" +defines the normal foreground color. .TP -.B \-sb <color> -sets the background color of selected items (#RGB, #RRGGBB, and color names are -supported). +.BI \-sb " color" +defines the selected background color. .TP -.B \-sf <color> -sets the foreground color of selected items (#RGB, #RRGGBB, and color names are -supported). +.BI \-sf " color" +defines the selected foreground color. .TP .B \-v prints version information to standard output, then exits. .SH USAGE -dmenu reads a list of newline-separated items from standard input and creates a -menu. When the user selects an item or enters any text and presses Return, -their choice is printed to standard output and dmenu terminates. -.P dmenu is completely controlled by the keyboard. Besides standard Unix line editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the following keys are recognized: @@ -96,10 +91,9 @@ Confirm input. Prints the input text to standard output and exits, returning success. .TP .B Escape (Control\-c) -Quit without selecting an item, returning failure. +Exit without selecting an item, returning failure. .TP .B Control\-y Paste the current X selection into the input field. .SH SEE ALSO -.BR dwm (1), -.BR wmii (1). +.BR dwm (1) diff --git a/dmenu.c b/dmenu.c @@ -1,11 +1,9 @@ /* See LICENSE file for copyright and license details. */ #include <ctype.h> -#include <locale.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <X11/keysym.h> #include <X11/Xatom.h> #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -13,7 +11,6 @@ #include <X11/extensions/Xinerama.h> #endif #include <draw.h> -#include "config.h" #define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -38,25 +35,27 @@ static void grabkeyboard(void); static void insert(const char *s, ssize_t n); static void keypress(XKeyEvent *e); static void match(void); -static void paste(Atom atom); +static void paste(void); static void readstdin(void); static void run(void); static void setup(void); static void usage(void); -static char *prompt; static char text[4096]; -static int screen; static size_t cursor = 0; +static const char *prompt = NULL; +static const char *normbgcolor = "#cccccc"; +static const char *normfgcolor = "#000000"; +static const char *selbgcolor = "#0066ff"; +static const char *selfgcolor = "#ffffff"; static unsigned int inputw = 0; static unsigned int lines = 0; static unsigned int mw, mh; -static unsigned int promptw = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; static Atom utf8; static Bool topbar = True; -static DC dc; +static DC *dc; static Item *allitems, *matches; static Item *curr, *prev, *next, *sel; static Window root, win; @@ -67,7 +66,7 @@ static void (*calcoffsets)(void) = calcoffsetsh; void appenditem(Item *item, Item **list, Item **last) { - if(!(*last)) + if(!*last) *list = item; else (*last)->right = item; @@ -80,12 +79,12 @@ void calcoffsetsh(void) { unsigned int w, x; - w = promptw + inputw + textw(&dc, "<") + textw(&dc, ">"); + w = (prompt ? textw(dc, prompt) : 0) + inputw + textw(dc, "<") + textw(dc, ">"); for(x = w, next = curr; next; next = next->right) - if((x += MIN(textw(&dc, next->text), mw / 3)) > mw) + if((x += MIN(textw(dc, next->text), mw / 3)) > mw) break; for(x = w, prev = curr; prev && prev->left; prev = prev->left) - if((x += MIN(textw(&dc, prev->left->text), mw / 3)) > mw) + if((x += MIN(textw(dc, prev->left->text), mw / 3)) > mw) break; } @@ -96,101 +95,75 @@ calcoffsetsv(void) { next = prev = curr; for(i = 0; i < lines && next; i++) next = next->right; - mh = (dc.font.height + 2) * (i + 1); for(i = 0; i < lines && prev && prev->left; i++) prev = prev->left; } char * cistrstr(const char *s, const char *sub) { - int c, csub; - unsigned int len; + size_t len; - if(!sub) - return (char *)s; - if((c = tolower(*sub++)) != '\0') { - len = strlen(sub); - do { - do { - if((csub = *s++) == '\0') - return NULL; - } - while(tolower(csub) != c); - } - while(strncasecmp(s, sub, len) != 0); - s--; - } - return (char *)s; + for(len = strlen(sub); *s; s++) + if(!strncasecmp(s, sub, len)) + return (char *)s; + return NULL; } void drawmenu(void) { - dc.x = 0; - dc.y = 0; - dc.w = mw; - dc.h = mh; - drawbox(&dc, normcol); - dc.h = dc.font.height + 2; - dc.y = topbar ? 0 : mh - dc.h; + dc->x = 0; + dc->y = 0; + drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); + dc->h = dc->font.height + 2; + dc->y = topbar ? 0 : mh - dc->h; /* print prompt? */ if(prompt) { - dc.w = promptw; - drawbox(&dc, selcol); - drawtext(&dc, prompt, selcol); - dc.x += dc.w; + dc->w = textw(dc, prompt); + drawtext(dc, prompt, selcol); + dc->x = dc->w; } - dc.w = mw - dc.x; + dc->w = mw - dc->x; /* print input area */ - if(matches && lines == 0 && textw(&dc, text) <= inputw) - dc.w = inputw; - drawtext(&dc, text, normcol); - drawline(&dc, textnw(&dc, text, cursor) + dc.h/2 - 2, 2, 1, dc.h-4, normcol); + if(matches && lines == 0 && textw(dc, text) <= inputw) + dc->w = inputw; + drawtext(dc, text, normcol); + drawrect(dc, textnw(dc, text, cursor) + dc->h/2 - 2, 2, 1, dc->h - 4, FG(dc, normcol)); if(lines > 0) drawmenuv(); - else if(curr && (dc.w == inputw || curr->next)) + else if(curr && (dc->w == inputw || curr->next)) drawmenuh(); - commitdraw(&dc, win); + commitdraw(dc, win); } void drawmenuh(void) { Item *item; - dc.x += inputw; - dc.w = textw(&dc, "<"); + dc->x += inputw; + dc->w = textw(dc, "<"); if(curr->left) - drawtext(&dc, "<", normcol); - dc.x += dc.w; + drawtext(dc, "<", normcol); for(item = curr; item != next; item = item->right) { - dc.w = MIN(textw(&dc, item->text), mw / 3); - if(item == sel) - drawbox(&dc, selcol); - drawtext(&dc, item->text, (item == sel) ? selcol : normcol); - dc.x += dc.w; + dc->x += dc->w; + dc->w = MIN(textw(dc, item->text), mw / 3); + drawtext(dc, item->text, (item == sel) ? selcol : normcol); } - dc.w = textw(&dc, ">"); - dc.x = mw - dc.w; + dc->w = textw(dc, ">"); + dc->x = mw - dc->w; if(next) - drawtext(&dc, ">", normcol); + drawtext(dc, ">", normcol); } void drawmenuv(void) { Item *item; - XWindowAttributes wa; - dc.y = topbar ? dc.h : 0; - dc.w = mw - dc.x; + dc->y = topbar ? dc->h : 0; + dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { - if(item == sel) - drawbox(&dc, selcol); - drawtext(&dc, item->text, (item == sel) ? selcol : normcol); - dc.y += dc.h; + drawtext(dc, item->text, (item == sel) ? selcol : normcol); + dc->y += dc->h; } - if(!XGetWindowAttributes(dc.dpy, win, &wa)) - eprintf("cannot get window attributes\n"); - if(wa.height != mh) - XMoveResizeWindow(dc.dpy, win, wa.x, wa.y + (topbar ? 0 : wa.height - mh), mw, mh); } void @@ -198,7 +171,7 @@ grabkeyboard(void) { int i; for(i = 0; i < 1000; i++) { - if(!XGrabKeyboard(dc.dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) + if(!XGrabKeyboard(dc->dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime)) return; usleep(1000); } @@ -254,6 +227,7 @@ keypress(XKeyEvent *e) { break; case XK_k: /* delete right */ text[cursor] = '\0'; + match(); break; case XK_n: ksym = XK_Down; @@ -270,10 +244,10 @@ keypress(XKeyEvent *e) { n = 0; while(cursor - n++ > 0 && text[cursor - n] == ' '); while(cursor - n++ > 0 && text[cursor - n] != ' '); - insert(NULL, -(--n)); + insert(NULL, 1-n); break; case XK_y: /* paste selection */ - XConvertSelection(dc.dpy, XA_PRIMARY, utf8, None, win, CurrentTime); + XConvertSelection(dc->dpy, XA_PRIMARY, utf8, None, win, CurrentTime); /* causes SelectionNotify event */ return; } @@ -348,7 +322,7 @@ keypress(XKeyEvent *e) { break; case XK_Return: case XK_KP_Enter: - fputs(((e->state & ShiftMask) || sel) ? sel->text : text, stdout); + fputs((sel && !(e->state & ShiftMask)) ? sel->text : text, stdout); fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: @@ -418,15 +392,14 @@ match(void) { } void -paste(Atom atom) -{ +paste(void) { char *p, *q; int di; unsigned long dl; Atom da; - XGetWindowProperty(dc.dpy, win, atom, 0, sizeof text - cursor, True, - utf8, &da, &di, &dl, &dl, (unsigned char **)&p); + XGetWindowProperty(dc->dpy, win, utf8, 0, sizeof text - cursor, True, + utf8, &da, &di, &dl, &dl, (unsigned char **)&p); insert(p, (q = strchr(p, '\n')) ? q-p : strlen(p)); XFree(p); drawmenu(); @@ -434,24 +407,22 @@ paste(Atom atom) void readstdin(void) { - char buf[sizeof text]; - size_t len; + char buf[sizeof text], *p; Item *item, *new; allitems = NULL; for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) { - len = strlen(buf); - if(buf[len-1] == '\n') - buf[--len] = '\0'; + if((p = strchr(buf, '\n'))) + *p = '\0'; if(!(new = malloc(sizeof *new))) eprintf("cannot malloc %u bytes\n", sizeof *new); if(!(new->text = strdup(buf))) - eprintf("cannot strdup %u bytes\n", len); - inputw = MAX(inputw, textw(&dc, new->text)); + eprintf("cannot strdup %u bytes\n", strlen(buf)); + inputw = MAX(inputw, textw(dc, new->text)); new->next = new->left = new->right = NULL; if(item) item->next = new; - else + else allitems = new; } } @@ -460,7 +431,7 @@ void run(void) { XEvent ev; - while(!XNextEvent(dc.dpy, &ev)) + while(!XNextEvent(dc->dpy, &ev)) switch(ev.type) { case Expose: if(ev.xexpose.count == 0) @@ -470,39 +441,43 @@ run(void) { keypress(&ev.xkey); break; case SelectionNotify: - if(ev.xselection.property != None) - paste(ev.xselection.property); + if(ev.xselection.property == utf8) + paste(); break; case VisibilityNotify: if(ev.xvisibility.state != VisibilityUnobscured) - XRaiseWindow(dc.dpy, win); + XRaiseWindow(dc->dpy, win); break; } } void setup(void) { - int x, y; + int x, y, screen; + XSetWindowAttributes wa; #ifdef XINERAMA - int i, n; + int n; XineramaScreenInfo *info; #endif - XSetWindowAttributes wa; - normcol[ColBG] = getcolor(&dc, normbgcolor); - normcol[ColFG] = getcolor(&dc, normfgcolor); - selcol[ColBG] = getcolor(&dc, selbgcolor); - selcol[ColFG] = getcolor(&dc, selfgcolor); + screen = DefaultScreen(dc->dpy); + root = RootWindow(dc->dpy, screen); + utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); + + normcol[ColBG] = getcolor(dc, normbgcolor); + normcol[ColFG] = getcolor(dc, normfgcolor); + selcol[ColBG] = getcolor(dc, selbgcolor); + selcol[ColFG] = getcolor(dc, selfgcolor); /* input window geometry */ - mh = (dc.font.height + 2) * (lines + 1); + mh = (dc->font.height + 2) * (lines + 1); #ifdef XINERAMA - if((info = XineramaQueryScreens(dc.dpy, &n))) { - int di; + if((info = XineramaQueryScreens(dc->dpy, &n))) { + int i, di; unsigned int du; Window dw; - XQueryPointer(dc.dpy, root, &dw, &dw, &x, &y, &di, &di, &du); + XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); for(i = 0; i < n; i++) if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) break; @@ -515,31 +490,30 @@ setup(void) { #endif { x = 0; - y = topbar ? 0 : DisplayHeight(dc.dpy, screen) - mh; - mw = DisplayWidth(dc.dpy, screen); + y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; + mw = DisplayWidth(dc->dpy, screen); } /* input window */ wa.override_redirect = True; wa.background_pixmap = ParentRelative; wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; - win = XCreateWindow(dc.dpy, root, x, y, mw, mh, 0, - DefaultDepth(dc.dpy, screen), CopyFromParent, - DefaultVisual(dc.dpy, screen), + win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, + DefaultDepth(dc->dpy, screen), CopyFromParent, + DefaultVisual(dc->dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); - match(); grabkeyboard(); - setupdraw(&dc, win); - inputw = MIN(inputw, mw / 3); - utf8 = XInternAtom(dc.dpy, "UTF8_STRING", False); - XMapRaised(dc.dpy, win); + setcanvas(dc, win, mw, mh); + inputw = MIN(inputw, mw/3); + XMapRaised(dc->dpy, win); + match(); } void usage(void) { - fputs("usage: dmenu [-b] [-i] [-l <lines>] [-p <prompt>] [-fn <font>] [-nb <color>]\n" - " [-nf <color>] [-sb <color>] [-sf <color>] [-v]\n", stderr); + fputs("usage: dmenu [-b] [-i] [-l lines] [-p prompt] [-fn font] [-nb color]\n" + " [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); } @@ -548,8 +522,10 @@ main(int argc, char *argv[]) { int i; progname = "dmenu"; + dc = initdraw(); + for(i = 1; i < argc; i++) - /* 1-arg flags */ + /* single flags */ if(!strcmp(argv[i], "-v")) { fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); exit(EXIT_SUCCESS); @@ -562,17 +538,15 @@ main(int argc, char *argv[]) { } else if(i == argc-1) usage(); - /* 2-arg flags */ + /* double flags */ else if(!strcmp(argv[i], "-l")) { if((lines = atoi(argv[++i])) > 0) calcoffsets = calcoffsetsv; } - else if(!strcmp(argv[i], "-p")) { + else if(!strcmp(argv[i], "-p")) prompt = argv[++i]; - promptw = MIN(textw(&dc, prompt), mw/5); - } else if(!strcmp(argv[i], "-fn")) - font = argv[++i]; + initfont(dc, argv[i++]); else if(!strcmp(argv[i], "-nb")) normbgcolor = argv[++i]; else if(!strcmp(argv[i], "-nf")) @@ -584,14 +558,6 @@ main(int argc, char *argv[]) { else usage(); - if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("dmenu: warning: no locale support\n", stderr); - if(!(dc.dpy = XOpenDisplay(NULL))) - eprintf("cannot open display\n"); - screen = DefaultScreen(dc.dpy); - root = RootWindow(dc.dpy, screen); - initfont(&dc, font); - readstdin(); setup(); run(); diff --git a/dmenu_path b/dmenu_path @@ -19,7 +19,7 @@ then do test -x "$file" && echo "$file" done - done | sort | uniq > "$CACHE".$$ && + done | sort -u > "$CACHE".$$ && mv "$CACHE".$$ "$CACHE" fi