aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dmenu.c74
1 files changed, 34 insertions, 40 deletions
diff --git a/dmenu.c b/dmenu.c
index a8bdcb9..42022e9 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -13,7 +13,6 @@
13#include <draw.h> 13#include <draw.h>
14 14
15#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh)) 15#define INRECT(x,y,rx,ry,rw,rh) ((x) >= (rx) && (x) < (rx)+(rw) && (y) >= (ry) && (y) < (ry)+(rh))
16#define LINEH (dc->font.height + 2)
17#define MIN(a,b) ((a) < (b) ? (a) : (b)) 16#define MIN(a,b) ((a) < (b) ? (a) : (b))
18#define MAX(a,b) ((a) > (b) ? (a) : (b)) 17#define MAX(a,b) ((a) > (b) ? (a) : (b))
19#define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80) 18#define UTF8_CODEPOINT(c) (((c) & 0xc0) != 0x80)
@@ -27,8 +26,8 @@ struct Item {
27 26
28static void appenditem(Item *item, Item **list, Item **last); 27static void appenditem(Item *item, Item **list, Item **last);
29static void calcoffsets(void); 28static void calcoffsets(void);
30static char *cistrstr(const char *s, const char *sub);
31static void drawmenu(void); 29static void drawmenu(void);
30static char *fstrstr(const char *s, const char *sub);
32static void grabkeyboard(void); 31static void grabkeyboard(void);
33static void insert(const char *s, ssize_t n); 32static void insert(const char *s, ssize_t n);
34static void keypress(XKeyEvent *ev); 33static void keypress(XKeyEvent *ev);
@@ -47,21 +46,21 @@ static const char *normbgcolor = "#cccccc";
47static const char *normfgcolor = "#000000"; 46static const char *normfgcolor = "#000000";
48static const char *selbgcolor = "#0066ff"; 47static const char *selbgcolor = "#0066ff";
49static const char *selfgcolor = "#ffffff"; 48static const char *selfgcolor = "#ffffff";
49static unsigned int bh, mw, mh;
50static unsigned int inputw = 0; 50static unsigned int inputw = 0;
51static unsigned int lines = 0; 51static unsigned int lines = 0;
52static unsigned int mw, mh;
53static unsigned int promptw; 52static unsigned int promptw;
54static unsigned long normcol[ColLast]; 53static unsigned long normcol[ColLast];
55static unsigned long selcol[ColLast]; 54static unsigned long selcol[ColLast];
56static Atom utf8; 55static Atom utf8;
57static Bool topbar = True; 56static Bool topbar = True;
58static DC *dc; 57static DC *dc;
59static Item *allitems, *matches; 58static Item *items = NULL;
60static Item *curr, *prev, *next, *sel; 59static Item *matches, *sel;
60static Item *prev, *curr, *next;
61static Window root, win; 61static Window root, win;
62 62
63static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; 63static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
64static char *(*fstrstr)(const char *, const char *) = strstr;
65 64
66void 65void
67appenditem(Item *item, Item **list, Item **last) { 66appenditem(Item *item, Item **list, Item **last) {
@@ -79,28 +78,18 @@ calcoffsets(void) {
79 unsigned int i, n; 78 unsigned int i, n;
80 79
81 if(lines > 0) 80 if(lines > 0)
82 n = lines * LINEH; 81 n = lines * bh;
83 else 82 else
84 n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">")); 83 n = mw - (promptw + inputw + textw(dc, "<") + textw(dc, ">"));
85 84
86 for(i = 0, next = curr; next; next = next->right) 85 for(i = 0, next = curr; next; next = next->right)
87 if((i += (lines > 0) ? LINEH : MIN(textw(dc, next->text), mw/3)) > n) 86 if((i += (lines > 0) ? bh : MIN(textw(dc, next->text), mw/3)) > n)
88 break; 87 break;
89 for(i = 0, prev = curr; prev && prev->left; prev = prev->left) 88 for(i = 0, prev = curr; prev && prev->left; prev = prev->left)
90 if((i += (lines > 0) ? LINEH : MIN(textw(dc, prev->left->text), mw/3)) > n) 89 if((i += (lines > 0) ? bh : MIN(textw(dc, prev->left->text), mw/3)) > n)
91 break; 90 break;
92} 91}
93 92
94char *
95cistrstr(const char *s, const char *sub) {
96 size_t len;
97
98 for(len = strlen(sub); *s; s++)
99 if(!strncasecmp(s, sub, len))
100 return (char *)s;
101 return NULL;
102}
103
104void 93void
105drawmenu(void) { 94drawmenu(void) {
106 int curpos; 95 int curpos;
@@ -108,8 +97,8 @@ drawmenu(void) {
108 97
109 dc->x = 0; 98 dc->x = 0;
110 dc->y = 0; 99 dc->y = 0;
111 dc->h = LINEH; 100 dc->h = bh;
112 drawrect(dc, 0, 0, mw, mh, BG(dc, normcol)); 101 drawrect(dc, 0, 0, mw, mh, True, BG(dc, normcol));
113 102
114 if(prompt) { 103 if(prompt) {
115 dc->w = promptw; 104 dc->w = promptw;
@@ -119,7 +108,7 @@ drawmenu(void) {
119 dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw; 108 dc->w = (lines > 0 || !matches) ? mw - dc->x : inputw;
120 drawtext(dc, text, normcol); 109 drawtext(dc, text, normcol);
121 if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w) 110 if((curpos = textnw(dc, text, cursor) + dc->h/2 - 2) < dc->w)
122 drawrect(dc, curpos, 2, 1, dc->h - 4, FG(dc, normcol)); 111 drawrect(dc, curpos, 2, 1, dc->h - 4, True, FG(dc, normcol));
123 112
124 if(lines > 0) { 113 if(lines > 0) {
125 dc->w = mw - dc->x; 114 dc->w = mw - dc->x;
@@ -143,7 +132,17 @@ drawmenu(void) {
143 if(next) 132 if(next)
144 drawtext(dc, ">", normcol); 133 drawtext(dc, ">", normcol);
145 } 134 }
146 commitdraw(dc, win); 135 commitdraw(dc, win, mw, mh);
136}
137
138char *
139fstrstr(const char *s, const char *sub) {
140 size_t len;
141
142 for(len = strlen(sub); *s; s++)
143 if(!fstrncmp(s, sub, len))
144 return (char *)s;
145 return NULL;
147} 146}
148 147
149void 148void
@@ -338,13 +337,14 @@ match(void) {
338 337
339 len = strlen(text); 338 len = strlen(text);
340 matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL; 339 matches = lexact = lprefix = lsubstr = itemend = exactend = prefixend = substrend = NULL;
341 for(item = allitems; item; item = item->next) 340 for(item = items; item; item = item->next)
342 if(!fstrncmp(text, item->text, len + 1)) 341 if(!fstrncmp(text, item->text, len + 1))
343 appenditem(item, &lexact, &exactend); 342 appenditem(item, &lexact, &exactend);
344 else if(!fstrncmp(text, item->text, len)) 343 else if(!fstrncmp(text, item->text, len))
345 appenditem(item, &lprefix, &prefixend); 344 appenditem(item, &lprefix, &prefixend);
346 else if(fstrstr(item->text, text)) 345 else if(fstrstr(item->text, text))
347 appenditem(item, &lsubstr, &substrend); 346 appenditem(item, &lsubstr, &substrend);
347
348 if(lexact) { 348 if(lexact) {
349 matches = lexact; 349 matches = lexact;
350 itemend = exactend; 350 itemend = exactend;
@@ -387,22 +387,17 @@ paste(void) {
387void 387void
388readstdin(void) { 388readstdin(void) {
389 char buf[sizeof text], *p; 389 char buf[sizeof text], *p;
390 Item *item, *new; 390 Item *item, **end;
391 391
392 allitems = NULL; 392 for(end = &items; fgets(buf, sizeof buf, stdin); *end = item, end = &item->next) {
393 for(item = NULL; fgets(buf, sizeof buf, stdin); item = new) {
394 if((p = strchr(buf, '\n'))) 393 if((p = strchr(buf, '\n')))
395 *p = '\0'; 394 *p = '\0';
396 if(!(new = malloc(sizeof *new))) 395 if(!(item = malloc(sizeof *item)))
397 eprintf("cannot malloc %u bytes\n", sizeof *new); 396 eprintf("cannot malloc %u bytes\n", sizeof *item);
398 if(!(new->text = strdup(buf))) 397 if(!(item->text = strdup(buf)))
399 eprintf("cannot strdup %u bytes\n", strlen(buf)+1); 398 eprintf("cannot strdup %u bytes\n", strlen(buf)+1);
400 inputw = MAX(inputw, textw(dc, new->text)); 399 inputw = MAX(inputw, textw(dc, item->text));
401 new->next = new->left = new->right = NULL; 400 item->next = item->left = item->right = NULL;
402 if(item)
403 item->next = new;
404 else
405 allitems = new;
406 } 401 }
407} 402}
408 403
@@ -449,7 +444,8 @@ setup(void) {
449 selcol[ColFG] = getcolor(dc, selfgcolor); 444 selcol[ColFG] = getcolor(dc, selfgcolor);
450 445
451 /* menu geometry */ 446 /* menu geometry */
452 mh = (lines + 1) * LINEH; 447 bh = dc->font.height + 2;
448 mh = (lines + 1) * bh;
453#ifdef XINERAMA 449#ifdef XINERAMA
454 if((info = XineramaQueryScreens(dc->dpy, &n))) { 450 if((info = XineramaQueryScreens(dc->dpy, &n))) {
455 int i, di; 451 int i, di;
@@ -510,10 +506,8 @@ main(int argc, char *argv[]) {
510 } 506 }
511 else if(!strcmp(argv[i], "-b")) 507 else if(!strcmp(argv[i], "-b"))
512 topbar = False; 508 topbar = False;
513 else if(!strcmp(argv[i], "-i")) { 509 else if(!strcmp(argv[i], "-i"))
514 fstrncmp = strncasecmp; 510 fstrncmp = strncasecmp;
515 fstrstr = cistrstr;
516 }
517 else if(i == argc-1) 511 else if(i == argc-1)
518 usage(); 512 usage();
519 /* double flags */ 513 /* double flags */