X-Git-Url: https://git.armaanb.net/?a=blobdiff_plain;f=dmenu.c;h=8d9bbb65e868147e028df42954d77a867181b9eb;hb=5ed5e90bfb7760f24661281cf7156087afbe49d3;hp=6f6123d1c493df917d86e009eec2a5e03d9d1d05;hpb=d3e9bd152ed007682b339f3a07a5720ad53cb675;p=dmenu.git diff --git a/dmenu.c b/dmenu.c index 6f6123d..8d9bbb6 100644 --- a/dmenu.c +++ b/dmenu.c @@ -22,6 +22,7 @@ typedef struct Item Item; struct Item { char *text; Item *left, *right; + Bool out; }; static void appenditem(Item *item, Item **list, Item **last); @@ -43,23 +44,19 @@ static char text[BUFSIZ] = ""; static int bh, mw, mh; static int inputw, promptw; static size_t cursor = 0; -static const char *font = NULL; -static const char *prompt = NULL; -static const char *normbgcolor = "#222222"; -static const char *normfgcolor = "#bbbbbb"; -static const char *selbgcolor = "#005577"; -static const char *selfgcolor = "#eeeeee"; -static unsigned int lines = 0; static unsigned long normcol[ColLast]; static unsigned long selcol[ColLast]; +static unsigned long outcol[ColLast]; static Atom clip, utf8; -static Bool topbar = True; static DC *dc; static Item *items = NULL; static Item *matches, *matchend; static Item *prev, *curr, *next, *sel; static Window win; static XIC xic; +static int mon = -1; + +#include "config.h" static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; static char *(*fstrstr)(const char *, const char *) = strstr; @@ -88,6 +85,8 @@ main(int argc, char *argv[]) { /* these options take one argument */ else if(!strcmp(argv[i], "-l")) /* number of lines in vertical list */ lines = atoi(argv[++i]); + else if(!strcmp(argv[i], "-m")) + mon = atoi(argv[++i]); else if(!strcmp(argv[i], "-p")) /* adds prompt to left of input field */ prompt = argv[++i]; else if(!strcmp(argv[i], "-fn")) /* font or font set */ @@ -169,7 +168,7 @@ drawmenu(void) { dc->h = bh; drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol)); - if(prompt) { + if(prompt && *prompt) { dc->w = promptw; drawtext(dc, prompt, selcol); dc->x = dc->w; @@ -185,7 +184,8 @@ drawmenu(void) { dc->w = mw - dc->x; for(item = curr; item != next; item = item->right) { dc->y += dc->h; - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + drawtext(dc, item->text, (item == sel) ? selcol : + (item->out) ? outcol : normcol); } } else if(matches) { @@ -197,7 +197,8 @@ drawmenu(void) { for(item = curr; item != next; item = item->right) { dc->x += dc->w; dc->w = MIN(textw(dc, item->text), mw - dc->x - textw(dc, ">")); - drawtext(dc, item->text, (item == sel) ? selcol : normcol); + drawtext(dc, item->text, (item == sel) ? selcol : + (item->out) ? outcol : normcol); } dc->w = textw(dc, ">"); dc->x = mw - dc->w; @@ -251,10 +252,13 @@ keypress(XKeyEvent *ev) { case XK_d: ksym = XK_Delete; break; case XK_e: ksym = XK_End; break; case XK_f: ksym = XK_Right; break; + case XK_g: ksym = XK_Escape; break; case XK_h: ksym = XK_BackSpace; break; case XK_i: ksym = XK_Tab; break; - case XK_j: ksym = XK_Return; break; - case XK_m: ksym = XK_Return; break; + case XK_j: /* fallthrough */ + case XK_J: ksym = XK_Return; break; + case XK_m: /* fallthrough */ + case XK_M: ksym = XK_Return; break; case XK_n: ksym = XK_Down; break; case XK_p: ksym = XK_Up; break; @@ -275,6 +279,11 @@ keypress(XKeyEvent *ev) { XConvertSelection(dc->dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, utf8, utf8, win, CurrentTime); return; + case XK_Return: + case XK_KP_Enter: + break; + case XK_bracketleft: + exit(EXIT_FAILURE); default: return; } @@ -282,10 +291,10 @@ keypress(XKeyEvent *ev) { switch(ksym) { case XK_g: ksym = XK_Home; break; case XK_G: ksym = XK_End; break; - case XK_h: ksym = XK_Prior; break; - case XK_j: ksym = XK_Up; break; - case XK_k: ksym = XK_Down; break; - case XK_l: ksym = XK_Next; break; + case XK_h: ksym = XK_Up; break; + case XK_j: ksym = XK_Next; break; + case XK_k: ksym = XK_Prior; break; + case XK_l: ksym = XK_Down; break; default: return; } @@ -359,7 +368,10 @@ keypress(XKeyEvent *ev) { case XK_Return: case XK_KP_Enter: puts((sel && !(ev->state & ShiftMask)) ? sel->text : text); - exit(EXIT_SUCCESS); + if(!(ev->state & ControlMask)) + exit(EXIT_SUCCESS); + sel->out = True; + break; case XK_Right: if(text[cursor] != '\0') { cursor = nextrune(+1); @@ -377,7 +389,8 @@ keypress(XKeyEvent *ev) { case XK_Tab: if(!sel) return; - strncpy(text, sel->text, sizeof text); + strncpy(text, sel->text, sizeof text - 1); + text[sizeof text - 1] = '\0'; cursor = strlen(text); match(); break; @@ -477,6 +490,7 @@ readstdin(void) { *p = '\0'; if(!(items[i].text = strdup(buf))) eprintf("cannot strdup %u bytes:", strlen(buf)+1); + items[i].out = False; if(strlen(items[i].text) > max) max = strlen(maxstr = items[i].text); } @@ -528,6 +542,8 @@ setup(void) { normcol[ColFG] = getcolor(dc, normfgcolor); selcol[ColBG] = getcolor(dc, selbgcolor); selcol[ColFG] = getcolor(dc, selfgcolor); + outcol[ColBG] = getcolor(dc, outbgcolor); + outcol[ColFG] = getcolor(dc, outfgcolor); clip = XInternAtom(dc->dpy, "CLIPBOARD", False); utf8 = XInternAtom(dc->dpy, "UTF8_STRING", False); @@ -544,7 +560,9 @@ setup(void) { XWindowAttributes wa; XGetInputFocus(dc->dpy, &w, &di); - if(w != root && w != PointerRoot && w != None) { + if(mon != -1 && mon < n) + i = mon; + if(!i && w != root && w != PointerRoot && w != None) { /* find top-level window containing current input focus */ do { if(XQueryTree(dc->dpy, (pw = w), &dw, &w, &dws, &du) && dws) @@ -559,7 +577,7 @@ setup(void) { } } /* no focused window is on screen, so use pointer location instead */ - if(!area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) + if(mon == -1 && !area && XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du)) for(i = 0; i < n; i++) if(INTERSECT(x, y, 1, 1, info[i])) break; @@ -576,7 +594,7 @@ setup(void) { y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; mw = DisplayWidth(dc->dpy, screen); } - promptw = prompt ? textw(dc, prompt) : 0; + promptw = (prompt && *prompt) ? textw(dc, prompt) : 0; inputw = MIN(inputw, mw/3); match(); @@ -601,7 +619,7 @@ setup(void) { void usage(void) { - fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" + fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); exit(EXIT_FAILURE); }