From d515d2758fab55809ef9dcb9b1b8dfb18a5b1606 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Fri, 7 Jan 2011 18:54:40 +0000 Subject: [PATCH 01/16] cache option in config.mk --- config.mk | 6 ++++-- dmenu_path.c | 4 +--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config.mk b/config.mk index ebaab81..08ea1bf 100644 --- a/config.mk +++ b/config.mk @@ -1,7 +1,9 @@ # dmenu version VERSION = 4.2.1 -# Customize below to fit your system +# dmenu_path cache (absolute or relative to $HOME) +CACHE = .dmenu_cache + # paths PREFIX = /usr/local @@ -19,7 +21,7 @@ INCS = -I${X11INC} LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} # flags -CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} +CPPFLAGS = -D_BSD_SOURCE -DVERSION=\"${VERSION}\" -DCACHE=\"${CACHE}\" ${XINERAMAFLAGS} CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS} LDFLAGS = -s ${LIBS} diff --git a/dmenu_path.c b/dmenu_path.c index 8df2667..407477a 100644 --- a/dmenu_path.c +++ b/dmenu_path.c @@ -7,8 +7,6 @@ #include #include -#define CACHE ".dmenu_cache" - static void die(const char *s); static int qstrcmp(const void *a, const void *b); static void scan(void); @@ -26,7 +24,7 @@ main(void) { if(chdir(home) < 0) die("chdir failed"); if(uptodate()) { - execlp("cat", "cat", CACHE, NULL); + execl("/bin/cat", "cat", CACHE, NULL); die("exec failed"); } scan(); -- 2.20.1 From 47e3e8be7b7df3ed37929dab8941f71cbee19fa9 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Fri, 7 Jan 2011 18:55:00 +0000 Subject: [PATCH 02/16] update license --- LICENSE | 4 ++-- dmenu.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index f44738e..25eb571 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT/X Consortium License -© 2010 Connor Lane Smith -© 2006-2010 Anselm R Garbe +© 2010-2011 Connor Lane Smith +© 2006-2011 Anselm R Garbe © 2009 Gottox © 2009 Markus Schnalke © 2009 Evan Gates diff --git a/dmenu.c b/dmenu.c index a24dfe3..6ed025d 100644 --- a/dmenu.c +++ b/dmenu.c @@ -71,7 +71,7 @@ main(int argc, char *argv[]) { for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { - fputs("dmenu-"VERSION", © 2006-2010 dmenu engineers, see LICENSE for details\n", stdout); + fputs("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details\n", stdout); exit(EXIT_SUCCESS); } else if(!strcmp(argv[i], "-b")) -- 2.20.1 From 210b303941e517a9d7df1cba1e3229165fb4037b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Thu, 5 May 2011 15:46:48 +0100 Subject: [PATCH 03/16] paring --- dmenu.c | 30 +++++++++++------------------- draw.c | 7 ++----- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/dmenu.c b/dmenu.c index 6ed025d..d8ef88f 100644 --- a/dmenu.c +++ b/dmenu.c @@ -36,9 +36,8 @@ static void paste(void); static void readstdin(void); static void run(void); static void setup(void); -static void usage(void); -static char text[BUFSIZ]; +static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw = 0; static int lines = 0; @@ -79,7 +78,7 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; else if(i == argc-1) - usage(); + goto usage; /* double flags */ else if(!strcmp(argv[i], "-l")) lines = atoi(argv[++i]); @@ -98,15 +97,19 @@ main(int argc, char *argv[]) { else if(!strcmp(argv[i], "-sf")) selfgcolor = argv[++i]; else - usage(); + goto usage; dc = initdc(); initfont(dc, font); readstdin(); setup(); run(); + return EXIT_FAILURE; - return EXIT_FAILURE; /* should not reach */ +usage: + fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); + return EXIT_FAILURE; } void @@ -223,7 +226,7 @@ keypress(XKeyEvent *ev) { len = strlen(text); XLookupString(ev, buf, sizeof buf, &ksym, NULL); - if(ev->state & ControlMask) { + if(ev->state & ControlMask) switch(tolower(ksym)) { default: return; @@ -277,7 +280,6 @@ keypress(XKeyEvent *ev) { XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); return; } - } switch(ksym) { default: if(!iscntrl(*buf)) @@ -341,7 +343,6 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); - fflush(stdout); exit(EXIT_SUCCESS); case XK_Right: if(cursor < len) { @@ -403,7 +404,7 @@ match(void) { else matches = lsubstr; } - curr = prev = next = sel = matches; + curr = sel = matches; calcoffsets(); } @@ -438,11 +439,10 @@ readstdin(void) { for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { if((p = strchr(buf, '\n'))) *p = '\0'; - if(!(item = malloc(sizeof *item))) + if(!(item = calloc(1, sizeof *item))) eprintf("cannot malloc %u bytes\n", sizeof *item); if(!(item->text = strdup(buf))) eprintf("cannot strdup %u bytes\n", strlen(buf)+1); - item->next = item->left = item->right = NULL; inputw = MAX(inputw, textw(dc, item->text)); } } @@ -530,13 +530,5 @@ setup(void) { inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); - text[0] = '\0'; match(); } - -void -usage(void) { - fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" - " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); - exit(EXIT_FAILURE); -} diff --git a/draw.c b/draw.c index 28c658c..80a5074 100644 --- a/draw.c +++ b/draw.c @@ -100,16 +100,13 @@ initdc(void) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) weprintf("no locale support\n"); - if(!(dc = malloc(sizeof *dc))) + if(!(dc = calloc(1, sizeof *dc))) eprintf("cannot malloc %u bytes\n", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) eprintf("cannot open display\n"); dc->gc = XCreateGC(dc->dpy, DefaultRootWindow(dc->dpy), 0, NULL); XSetLineAttributes(dc->dpy, dc->gc, 1, LineSolid, CapButt, JoinMiter); - dc->font.xfont = NULL; - dc->font.set = NULL; - dc->canvas = None; return dc; } @@ -187,7 +184,7 @@ void weprintf(const char *fmt, ...) { va_list ap; - fprintf(stderr, "%s: warning: ", progname); + fprintf(stderr, "%s: ", progname); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); -- 2.20.1 From cd3b4915c3358b93f8dbff531bff82c0cd833c0b Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Fri, 6 May 2011 21:13:02 +0100 Subject: [PATCH 04/16] helpful errors --- dmenu.c | 4 ++-- draw.c | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dmenu.c b/dmenu.c index d8ef88f..5be73f7 100644 --- a/dmenu.c +++ b/dmenu.c @@ -440,9 +440,9 @@ readstdin(void) { if((p = strchr(buf, '\n'))) *p = '\0'; if(!(item = calloc(1, sizeof *item))) - eprintf("cannot malloc %u bytes\n", sizeof *item); + eprintf("cannot malloc %u bytes:", sizeof *item); if(!(item->text = strdup(buf))) - eprintf("cannot strdup %u bytes\n", strlen(buf)+1); + eprintf("cannot strdup %u bytes:", strlen(buf)+1); inputw = MAX(inputw, textw(dc, item->text)); } } diff --git a/draw.c b/draw.c index 80a5074..83ced4b 100644 --- a/draw.c +++ b/draw.c @@ -68,6 +68,11 @@ eprintf(const char *fmt, ...) { va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); + + if(fmt[strlen(fmt)-1] == ':') { + fputc(' ', stderr); + perror(NULL); + } exit(EXIT_FAILURE); } @@ -101,7 +106,7 @@ initdc(void) { if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) weprintf("no locale support\n"); if(!(dc = calloc(1, sizeof *dc))) - eprintf("cannot malloc %u bytes\n", sizeof *dc); + eprintf("cannot malloc %u bytes:", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) eprintf("cannot open display\n"); -- 2.20.1 From e0e6b071c63f960c398b43b2fbf0dec66a9b3ab6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sun, 8 May 2011 15:15:24 +0100 Subject: [PATCH 05/16] fast grab patch (thanks Rob) --- dmenu.1 | 22 +++++++++++++--------- dmenu.c | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/dmenu.1 b/dmenu.1 index d2a93d1..a4fcfd9 100644 --- a/dmenu.1 +++ b/dmenu.1 @@ -4,6 +4,7 @@ dmenu \- dynamic menu .SH SYNOPSIS .B dmenu .RB [ \-b ] +.RB [ \-f ] .RB [ \-i ] .RB [ \-l .IR lines ] @@ -32,9 +33,9 @@ is a dynamic menu for X, originally designed for .BR dwm (1). 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. +dmenu reads a list of newline-separated items from stdin and creates a menu. +When the user selects an item or enters any text and presses Return, their +choice is printed to stdout and dmenu terminates. .P .B dmenu_run is a dmenu script used by dwm which lists programs in the user's PATH and @@ -47,6 +48,10 @@ is a program used by dmenu_run to find and cache a list of executables. .B \-b dmenu appears at the bottom of the screen. .TP +.B \-f +dmenu grabs the keyboard before reading stdin. This is faster, but may lock up +X if stdin is from a terminal. +.TP .B \-i dmenu matches menu items case insensitively. .TP @@ -66,7 +71,7 @@ defines the font or font set used. defines the normal background color. .IR #RGB , .IR #RRGGBB , -and color names are supported. +and X color names are supported. .TP .BI \-nf " color" defines the normal foreground color. @@ -78,7 +83,7 @@ defines the selected background color. defines the selected foreground color. .TP .B \-v -prints version information to standard output, then exits. +prints version information to stdout, then exits. .SH USAGE dmenu is completely controlled by the keyboard. Besides standard Unix line editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the @@ -88,12 +93,11 @@ following keys are recognized: Copy the selected item to the input field. .TP .B Return (Control\-j) -Confirm selection. Prints the selected item to standard output and exits, -returning success. +Confirm selection. Prints the selected item to stdout and exits, returning +success. .TP .B Shift\-Return (Control\-Shift\-j) -Confirm input. Prints the input text to standard output and exits, returning -success. +Confirm input. Prints the input text to stdout and exits, returning success. .TP .B Escape (Control\-c) Exit without selecting an item, returning failure. diff --git a/dmenu.c b/dmenu.c index 5be73f7..2193f82 100644 --- a/dmenu.c +++ b/dmenu.c @@ -64,6 +64,7 @@ static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; int main(int argc, char *argv[]) { + Bool fast = False; int i; progname = "dmenu"; @@ -77,6 +78,8 @@ main(int argc, char *argv[]) { topbar = False; else if(!strcmp(argv[i], "-i")) fstrncmp = strncasecmp; + else if(!strcmp(argv[i], "-f")) + fast = True; else if(i == argc-1) goto usage; /* double flags */ @@ -101,13 +104,21 @@ main(int argc, char *argv[]) { dc = initdc(); initfont(dc, font); - readstdin(); - setup(); + + if(fast) { + setup(); + readstdin(); + } + else { + readstdin(); + setup(); + } + match(); run(); return EXIT_FAILURE; usage: - fputs("usage: dmenu [-b] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); return EXIT_FAILURE; } @@ -530,5 +541,4 @@ setup(void) { inputw = MIN(inputw, mw/3); promptw = prompt ? textw(dc, prompt) : 0; XMapRaised(dc->dpy, win); - match(); } -- 2.20.1 From 0291c722fb298768d1942824ea2900399566e8a1 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Wed, 11 May 2011 12:25:50 +0100 Subject: [PATCH 06/16] fixed -m bug (thanks Rob) --- dmenu.c | 18 +++++++++--------- draw.c | 6 +++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dmenu.c b/dmenu.c index 2193f82..3c83d73 100644 --- a/dmenu.c +++ b/dmenu.c @@ -76,10 +76,10 @@ main(int argc, char *argv[]) { } else if(!strcmp(argv[i], "-b")) topbar = False; - else if(!strcmp(argv[i], "-i")) - fstrncmp = strncasecmp; else if(!strcmp(argv[i], "-f")) fast = True; + else if(!strcmp(argv[i], "-i")) + fstrncmp = strncasecmp; else if(i == argc-1) goto usage; /* double flags */ @@ -506,18 +506,18 @@ setup(void) { mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { - int i, di; + int i, m, di; unsigned int du; Window dw; XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); - for(i = 0; i < n; i++) + for(i = 0, m = -1; i < n; i++) if((monitor == info[i].screen_number) - || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) - break; - x = info[i].x_org; - y = info[i].y_org + (topbar ? 0 : info[i].height - mh); - mw = info[i].width; + || (m < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + m = i; + x = info[m].x_org; + y = info[m].y_org + (topbar ? 0 : info[m].height - mh); + mw = info[m].width; XFree(info); } else diff --git a/draw.c b/draw.c index 83ced4b..d35d4c2 100644 --- a/draw.c +++ b/draw.c @@ -7,9 +7,9 @@ #include #include "draw.h" -#define MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#define DEFFONT "fixed" +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define DEFFONT "fixed" static Bool loadfont(DC *dc, const char *fontstr); -- 2.20.1 From 86019c58555b5d9514cfe2eba14248588a812f16 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Thu, 12 May 2011 13:17:41 +0100 Subject: [PATCH 07/16] fixed xinerama corner case --- dmenu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dmenu.c b/dmenu.c index 3c83d73..6d35430 100644 --- a/dmenu.c +++ b/dmenu.c @@ -506,18 +506,18 @@ setup(void) { mh = (lines + 1) * bh; #ifdef XINERAMA if((info = XineramaQueryScreens(dc->dpy, &n))) { - int i, m, di; + int i, di; unsigned int du; Window dw; XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); - for(i = 0, m = -1; i < n; i++) + for(i = 0; i < n-1; i++) if((monitor == info[i].screen_number) - || (m < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) - m = i; - x = info[m].x_org; - y = info[m].y_org + (topbar ? 0 : info[m].height - mh); - mw = info[m].width; + || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) + break; + x = info[i].x_org; + y = info[i].y_org + (topbar ? 0 : info[i].height - mh); + mw = info[i].width; XFree(info); } else -- 2.20.1 From 3c067598fc3070243ae0c784bfea906dce0a6fbb Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 17:46:20 +0100 Subject: [PATCH 08/16] use array for items --- dmenu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dmenu.c b/dmenu.c index 6d35430..2684c91 100644 --- a/dmenu.c +++ b/dmenu.c @@ -1,4 +1,4 @@ -/* See LICENSE file for copyright and license details. */ +/* See LICENSE file for copynext and license details. */ #include #include #include @@ -19,8 +19,7 @@ typedef struct Item Item; struct Item { char *text; - Item *next; /* traverses all items */ - Item *left, *right; /* traverses matching items */ + Item *left, *right; }; static void appenditem(Item *item, Item **list, Item **last); @@ -386,7 +385,7 @@ match(void) { len = strlen(text); matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; - for(item = items; item; item = item->next) + for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); else if(!fstrncmp(text, item->text, len)) @@ -445,16 +444,17 @@ paste(void) { void readstdin(void) { char buf[sizeof text], *p; - Item *item, **end; + size_t i, size = 0; - for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) { + for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { + if(i+1 == size / sizeof *items || !items) + if(!(items = realloc(items, (size += BUFSIZ)))) + eprintf("cannot realloc %u bytes:", size); if((p = strchr(buf, '\n'))) *p = '\0'; - if(!(item = calloc(1, sizeof *item))) - eprintf("cannot malloc %u bytes:", sizeof *item); - if(!(item->text = strdup(buf))) + if(!(items[i].text = strdup(buf))) eprintf("cannot strdup %u bytes:", strlen(buf)+1); - inputw = MAX(inputw, textw(dc, item->text)); + inputw = MAX(inputw, textw(dc, items[i].text)); } } -- 2.20.1 From be9afce03548e8110744064d1c9c67795c13cdb6 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 17:47:12 +0100 Subject: [PATCH 09/16] fix typo --- dmenu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenu.c b/dmenu.c index 2684c91..68fc9ff 100644 --- a/dmenu.c +++ b/dmenu.c @@ -1,4 +1,4 @@ -/* See LICENSE file for copynext and license details. */ +/* See LICENSE file for copyright and license details. */ #include #include #include -- 2.20.1 From 86468aafe52a94ce6ba1a3601a587c65724a61aa Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 18:39:27 +0100 Subject: [PATCH 10/16] instant ^E --- dmenu.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/dmenu.c b/dmenu.c index 68fc9ff..b6f1ef2 100644 --- a/dmenu.c +++ b/dmenu.c @@ -55,8 +55,8 @@ static Atom utf8; static Bool topbar = True; static DC *dc; static Item *items = NULL; -static Item *matches, *sel; -static Item *prev, *curr, *next; +static Item *matches, *matchend; +static Item *prev, *curr, *next, *sel; static Window root, win; static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; @@ -308,12 +308,15 @@ keypress(XKeyEvent *ev) { cursor = len; break; } - while(next) { - sel = curr = next; + if(next) { + curr = matchend; calcoffsets(); + curr = prev; + calcoffsets(); + while(next && (curr = curr->right)) + calcoffsets(); } - while(sel && sel->right) - sel = sel->right; + sel = matchend; break; case XK_Escape: exit(EXIT_FAILURE); @@ -381,10 +384,10 @@ keypress(XKeyEvent *ev) { void match(void) { size_t len; - Item *item, *itemend, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; + Item *item, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; len = strlen(text); - matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; + matches = lexact = lprefix = lsubstr = matchend = exactend = prefixend = substrend = NULL; for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) appenditem(item, &lexact, &exactend); @@ -395,24 +398,25 @@ match(void) { if(lexact) { matches = lexact; - itemend = exactend; + matchend = exactend; } if(lprefix) { - if(itemend) { - itemend->right = lprefix; - lprefix->left = itemend; + if(matchend) { + matchend->right = lprefix; + lprefix->left = matchend; } else matches = lprefix; - itemend = prefixend; + matchend = prefixend; } if(lsubstr) { - if(itemend) { - itemend->right = lsubstr; - lsubstr->left = itemend; + if(matchend) { + matchend->right = lsubstr; + lsubstr->left = matchend; } else matches = lsubstr; + matchend = substrend; } curr = sel = matches; calcoffsets(); -- 2.20.1 From 15505bd711d77fbd88dbdcbc464c78d863e03250 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 20:43:11 +0100 Subject: [PATCH 11/16] fast dmenu_path script --- Makefile | 10 ++---- dmenu.1 | 2 +- dmenu_path | 9 +++++ dmenu_path.c | 100 --------------------------------------------------- 4 files changed, 13 insertions(+), 108 deletions(-) create mode 100755 dmenu_path delete mode 100644 dmenu_path.c diff --git a/Makefile b/Makefile index dd744e1..60e53d1 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -all: options dmenu dmenu_path +all: options dmenu options: @echo dmenu build options: @@ -15,22 +15,18 @@ dmenu: dmenu.o draw.o @echo CC -o $@ @${CC} -o $@ dmenu.o draw.o ${LDFLAGS} -dmenu_path: dmenu_path.o - @echo CC -o $@ - @${CC} -o $@ dmenu_path.o ${LDFLAGS} - .c.o: config.mk @echo CC -c $< @${CC} -c $< ${CFLAGS} clean: @echo cleaning - @rm -f dmenu dmenu.o draw.o dmenu_path dmenu_path.o dmenu-${VERSION}.tar.gz + @rm -f dmenu dmenu.o draw.o dmenu-${VERSION}.tar.gz dist: clean @echo creating dist tarball @mkdir -p dmenu-${VERSION} - @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path.c dmenu_run dmenu-${VERSION} + @cp LICENSE Makefile README config.mk dmenu.1 dmenu.c draw.c draw.h dmenu_path dmenu_run dmenu-${VERSION} @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} @gzip dmenu-${VERSION}.tar @rm -rf dmenu-${VERSION} diff --git a/dmenu.1 b/dmenu.1 index a4fcfd9..5f138c8 100644 --- a/dmenu.1 +++ b/dmenu.1 @@ -42,7 +42,7 @@ 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 program used by dmenu_run to find and cache a list of executables. +is a script used by dmenu_run to find and cache a list of executables. .SH OPTIONS .TP .B \-b diff --git a/dmenu_path b/dmenu_path new file mode 100755 index 0000000..f3a4701 --- /dev/null +++ b/dmenu_path @@ -0,0 +1,9 @@ +#!/bin/sh +CACHE=$HOME/.dmenu_cache +IFS=: + +if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then + find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sort -u > "$CACHE" +fi + +cat "$CACHE" diff --git a/dmenu_path.c b/dmenu_path.c deleted file mode 100644 index 407477a..0000000 --- a/dmenu_path.c +++ /dev/null @@ -1,100 +0,0 @@ -/* See LICENSE file for copyright and license details. */ -#include -#include -#include -#include -#include -#include -#include - -static void die(const char *s); -static int qstrcmp(const void *a, const void *b); -static void scan(void); -static int uptodate(void); - -static char **items = NULL; -static const char *home, *path; - -int -main(void) { - if(!(home = getenv("HOME"))) - die("no $HOME"); - if(!(path = getenv("PATH"))) - die("no $PATH"); - if(chdir(home) < 0) - die("chdir failed"); - if(uptodate()) { - execl("/bin/cat", "cat", CACHE, NULL); - die("exec failed"); - } - scan(); - return EXIT_SUCCESS; -} - -void -die(const char *s) { - fprintf(stderr, "dmenu_path: %s\n", s); - exit(EXIT_FAILURE); -} - -int -qstrcmp(const void *a, const void *b) { - return strcmp(*(const char **)a, *(const char **)b); -} - -void -scan(void) { - char buf[PATH_MAX]; - char *dir, *p; - size_t i, count; - struct dirent *ent; - DIR *dp; - FILE *cache; - - count = 0; - if(!(p = strdup(path))) - die("strdup failed"); - for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) { - if(!(dp = opendir(dir))) - continue; - while((ent = readdir(dp))) { - snprintf(buf, sizeof buf, "%s/%s", dir, ent->d_name); - if(ent->d_name[0] == '.' || access(buf, X_OK) < 0) - continue; - if(!(items = realloc(items, ++count * sizeof *items))) - die("malloc failed"); - if(!(items[count-1] = strdup(ent->d_name))) - die("strdup failed"); - } - closedir(dp); - } - qsort(items, count, sizeof *items, qstrcmp); - if(!(cache = fopen(CACHE, "w"))) - die("open failed"); - for(i = 0; i < count; i++) { - if(i > 0 && !strcmp(items[i], items[i-1])) - continue; - fprintf(cache, "%s\n", items[i]); - fprintf(stdout, "%s\n", items[i]); - } - fclose(cache); - free(p); -} - -int -uptodate(void) { - char *dir, *p; - time_t mtime; - struct stat st; - - if(stat(CACHE, &st) < 0) - return 0; - mtime = st.st_mtime; - if(!(p = strdup(path))) - die("strdup failed"); - for(dir = strtok(p, ":"); dir; dir = strtok(NULL, ":")) - if(!stat(dir, &st) && st.st_mtime > mtime) - return 0; - free(p); - return 1; -} -- 2.20.1 From 26236a4900657e8e6e9c5fcf277b51ca242fa3e8 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 22:12:28 +0100 Subject: [PATCH 12/16] whoops, wrong dmenu_path version --- dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenu_path b/dmenu_path index f3a4701..c1d3357 100755 --- a/dmenu_path +++ b/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sort -u > "$CACHE" + find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" -- 2.20.1 From d066975e78d98f368ab0e3106e00804a28697373 Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 22:43:42 +0100 Subject: [PATCH 13/16] cleanup --- dmenu.c | 7 ++----- draw.c | 24 +++++------------------- draw.h | 9 +++------ 3 files changed, 10 insertions(+), 30 deletions(-) diff --git a/dmenu.c b/dmenu.c index b6f1ef2..40b220c 100644 --- a/dmenu.c +++ b/dmenu.c @@ -66,7 +66,6 @@ main(int argc, char *argv[]) { Bool fast = False; int i; - progname = "dmenu"; for(i = 1; i < argc; i++) /* single flags */ if(!strcmp(argv[i], "-v")) { @@ -383,10 +382,9 @@ keypress(XKeyEvent *ev) { void match(void) { - size_t len; + size_t len = strlen(text); Item *item, *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; - len = strlen(text); matches = lexact = lprefix = lsubstr = matchend = exactend = prefixend = substrend = NULL; for(item = items; item && item->text; item++) if(!fstrncmp(text, item->text, len + 1)) @@ -424,9 +422,8 @@ match(void) { size_t nextrune(int incr) { - size_t n, len; + size_t n, len = strlen(text); - len = strlen(text); for(n = cursor + incr; n >= 0 && n < len && (text[n] & 0xc0) == 0x80; n += incr); return n; } diff --git a/draw.c b/draw.c index d35d4c2..f9b8957 100644 --- a/draw.c +++ b/draw.c @@ -29,10 +29,9 @@ drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign void drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { char buf[256]; - size_t n, mn; + size_t mn, n = strlen(text); /* shorten text if necessary */ - n = strlen(text); for(mn = MIN(n, sizeof buf); textnw(dc, text, mn) > dc->w - dc->font.height/2; mn--) if(mn == 0) return; @@ -46,10 +45,8 @@ drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { - int x, y; - - x = dc->x + dc->font.height/2; - y = dc->y + dc->font.ascent+1; + int x = dc->x + dc->font.height/2; + int y = dc->y + dc->font.ascent+1; XSetForeground(dc->dpy, dc->gc, FG(dc, col)); if(dc->font.set) @@ -64,7 +61,6 @@ void eprintf(const char *fmt, ...) { va_list ap; - fprintf(stderr, "%s: ", progname); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); @@ -104,7 +100,7 @@ initdc(void) { DC *dc; if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - weprintf("no locale support\n"); + fprintf(stderr, "no locale support\n"); if(!(dc = calloc(1, sizeof *dc))) eprintf("cannot malloc %u bytes:", sizeof *dc); if(!(dc->dpy = XOpenDisplay(NULL))) @@ -119,7 +115,7 @@ void initfont(DC *dc, const char *fontstr) { if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) { if(fontstr != NULL) - weprintf("cannot load font '%s'\n", fontstr); + fprintf(stderr, "cannot load font '%s'\n", fontstr); if(fontstr == NULL || !loadfont(dc, DEFFONT)) eprintf("cannot load font '%s'\n", DEFFONT); } @@ -184,13 +180,3 @@ int textw(DC *dc, const char *text) { return textnw(dc, text, strlen(text)) + dc->font.height; } - -void -weprintf(const char *fmt, ...) { - va_list ap; - - fprintf(stderr, "%s: ", progname); - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} diff --git a/draw.h b/draw.h index ac3943f..247c0b3 100644 --- a/draw.h +++ b/draw.h @@ -20,18 +20,15 @@ typedef struct { } font; } DC; /* draw context */ -unsigned long getcolor(DC *dc, const char *colstr); void drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color); void drawtext(DC *dc, const char *text, unsigned long col[ColLast]); void drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]); -void initfont(DC *dc, const char *fontstr); +void eprintf(const char *fmt, ...); void freedc(DC *dc); +unsigned long getcolor(DC *dc, const char *colstr); DC *initdc(void); +void initfont(DC *dc, const char *fontstr); void mapdc(DC *dc, Window win, unsigned int w, unsigned int h); void resizedc(DC *dc, unsigned int w, unsigned int h); int textnw(DC *dc, const char *text, size_t len); int textw(DC *dc, const char *text); -void eprintf(const char *fmt, ...); -void weprintf(const char *fmt, ...); - -const char *progname; -- 2.20.1 From a662fc6e0abeacb64b5b37cedccaeee782f9454e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 23:14:31 +0100 Subject: [PATCH 14/16] follow symlinks --- dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenu_path b/dmenu_path index c1d3357..59fe64d 100755 --- a/dmenu_path +++ b/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" + find -L $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" -- 2.20.1 From b2bb6ebec9054f5e3106abcea90c3ba1386acdeb Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 23:21:38 +0100 Subject: [PATCH 15/16] only match links --- dmenu_path | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmenu_path b/dmenu_path index 59fe64d..1b1b241 100755 --- a/dmenu_path +++ b/dmenu_path @@ -3,7 +3,7 @@ CACHE=$HOME/.dmenu_cache IFS=: if ! test -f "$CACHE" || find $PATH -type d -newer "$CACHE" | grep -q .; then - find -L $PATH -type f \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" + find $PATH ! -type d \( -perm -1 -o -perm -10 -o -perm -100 \) | sed 's/.*\///' | sort -u > "$CACHE" fi cat "$CACHE" -- 2.20.1 From 6cc0b0dc086feaf944b166d0b459ac407192ea5e Mon Sep 17 00:00:00 2001 From: Connor Lane Smith Date: Sat, 14 May 2011 23:26:41 +0100 Subject: [PATCH 16/16] increment version --- config.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.mk b/config.mk index 08ea1bf..aedd13c 100644 --- a/config.mk +++ b/config.mk @@ -1,5 +1,5 @@ # dmenu version -VERSION = 4.2.1 +VERSION = 4.3 # dmenu_path cache (absolute or relative to $HOME) CACHE = .dmenu_cache -- 2.20.1