diff options
-rw-r--r-- | dmenu.c | 90 |
1 files changed, 32 insertions, 58 deletions
@@ -111,45 +111,30 @@ appenditem(Item *i, Item **list, Item **last) { | |||
111 | 111 | ||
112 | void | 112 | void |
113 | calcoffsetsh(void) { | 113 | calcoffsetsh(void) { |
114 | int tw; | ||
115 | unsigned int w; | 114 | unsigned int w; |
116 | 115 | ||
117 | if(!curr) | 116 | if(!curr) |
118 | return; | 117 | return; |
119 | w = promptw + cmdw + 2 * spaceitem; | 118 | w = promptw + cmdw + 2 * spaceitem; |
120 | for(next = curr; next; next=next->right) { | 119 | for(next = curr; next && w < mw; next=next->right) |
121 | tw = MIN(textw(next->text), mw / 3); | 120 | w += MIN(textw(next->text), mw / 3); |
122 | w += tw; | ||
123 | if(w > mw) | ||
124 | break; | ||
125 | } | ||
126 | w = promptw + cmdw + 2 * spaceitem; | 121 | w = promptw + cmdw + 2 * spaceitem; |
127 | for(prev = curr; prev && prev->left; prev=prev->left) { | 122 | for(prev = curr; prev && prev->left && w < mw; prev=prev->left) |
128 | tw = MIN(textw(prev->left->text), mw / 3); | 123 | w += MIN(textw(prev->left->text), mw / 3); |
129 | w += tw; | ||
130 | if(w > mw) | ||
131 | break; | ||
132 | } | ||
133 | } | 124 | } |
134 | 125 | ||
135 | void | 126 | void |
136 | calcoffsetsv(void) { | 127 | calcoffsetsv(void) { |
137 | static unsigned int h; | 128 | unsigned int h; |
138 | 129 | ||
139 | if(!curr) | 130 | if(!curr) |
140 | return; | 131 | return; |
141 | h = (dc.font.height + 2) * (lines + 1); | 132 | h = (dc.font.height + 2) * lines; |
142 | for(next = curr; next; next=next->right) { | 133 | for(next = curr; next && h > 0; next = next->right) |
143 | h -= dc.font.height + 2; | 134 | h -= dc.font.height + 2; |
144 | if(h <= 0) | 135 | h = (dc.font.height + 2) * lines; |
145 | break; | 136 | for(prev = curr; prev && prev->left && h > 0; prev = prev->left) |
146 | } | ||
147 | h = (dc.font.height + 2) * (lines + 1); | ||
148 | for(prev = curr; prev && prev->left; prev=prev->left) { | ||
149 | h -= dc.font.height + 2; | 137 | h -= dc.font.height + 2; |
150 | if(h <= 0) | ||
151 | break; | ||
152 | } | ||
153 | } | 138 | } |
154 | 139 | ||
155 | char * | 140 | char * |
@@ -177,14 +162,6 @@ cistrstr(const char *s, const char *sub) { | |||
177 | 162 | ||
178 | void | 163 | void |
179 | cleanup(void) { | 164 | cleanup(void) { |
180 | Item *itm; | ||
181 | |||
182 | while(allitems) { | ||
183 | itm = allitems->next; | ||
184 | free(allitems->text); | ||
185 | free(allitems); | ||
186 | allitems = itm; | ||
187 | } | ||
188 | if(dc.font.set) | 165 | if(dc.font.set) |
189 | XFreeFontSet(dpy, dc.font.set); | 166 | XFreeFontSet(dpy, dc.font.set); |
190 | else | 167 | else |
@@ -257,11 +234,13 @@ drawmenuv(void) { | |||
257 | Item *i; | 234 | Item *i; |
258 | 235 | ||
259 | dc.w = mw - dc.x; | 236 | dc.w = mw - dc.x; |
260 | dc.y += dc.font.height + 2; | 237 | dc.h = dc.font.height + 2; |
238 | dc.y = dc.h; | ||
261 | for(i = curr; i != next; i=i->right) { | 239 | for(i = curr; i != next; i=i->right) { |
262 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); | 240 | drawtext(i->text, (sel == i) ? dc.sel : dc.norm); |
263 | dc.y += dc.font.height + 2; | 241 | dc.y += dc.h; |
264 | } | 242 | } |
243 | dc.h = mh - dc.y; | ||
265 | drawtext(NULL, dc.norm); | 244 | drawtext(NULL, dc.norm); |
266 | } | 245 | } |
267 | 246 | ||
@@ -309,7 +288,7 @@ getcolor(const char *colstr) { | |||
309 | XColor color; | 288 | XColor color; |
310 | 289 | ||
311 | if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) | 290 | if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) |
312 | eprint("error, cannot allocate color '%s'\n", colstr); | 291 | eprint("dmenu: cannot allocate color '%s'\n", colstr); |
313 | return color.pixel; | 292 | return color.pixel; |
314 | } | 293 | } |
315 | 294 | ||
@@ -328,12 +307,11 @@ grabkeyboard(void) { | |||
328 | 307 | ||
329 | void | 308 | void |
330 | initfont(const char *fontstr) { | 309 | initfont(const char *fontstr) { |
331 | char *def, **missing; | 310 | char *def, **missing = NULL; |
332 | int i, n; | 311 | int i, n; |
333 | 312 | ||
334 | if(!fontstr || fontstr[0] == '\0') | 313 | if(!fontstr || fontstr[0] == '\0') |
335 | eprint("error, cannot load font: '%s'\n", fontstr); | 314 | eprint("dmenu: cannot load font: '%s'\n", fontstr); |
336 | missing = NULL; | ||
337 | dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); | 315 | dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); |
338 | if(missing) | 316 | if(missing) |
339 | XFreeStringList(missing); | 317 | XFreeStringList(missing); |
@@ -351,7 +329,7 @@ initfont(const char *fontstr) { | |||
351 | else { | 329 | else { |
352 | if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) | 330 | if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) |
353 | && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) | 331 | && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) |
354 | eprint("error, cannot load font: '%s'\n", fontstr); | 332 | eprint("dmenu: cannot load font: '%s'\n", fontstr); |
355 | dc.font.ascent = dc.font.xfont->ascent; | 333 | dc.font.ascent = dc.font.xfont->ascent; |
356 | dc.font.descent = dc.font.xfont->descent; | 334 | dc.font.descent = dc.font.xfont->descent; |
357 | } | 335 | } |
@@ -361,12 +339,11 @@ initfont(const char *fontstr) { | |||
361 | void | 339 | void |
362 | kpress(XKeyEvent * e) { | 340 | kpress(XKeyEvent * e) { |
363 | char buf[sizeof text]; | 341 | char buf[sizeof text]; |
364 | int i, num, off; | 342 | int i, num; |
365 | unsigned int len; | 343 | unsigned int len; |
366 | KeySym ksym; | 344 | KeySym ksym; |
367 | 345 | ||
368 | len = strlen(text); | 346 | len = strlen(text); |
369 | buf[0] = '\0'; | ||
370 | num = XLookupString(e, buf, sizeof buf, &ksym, NULL); | 347 | num = XLookupString(e, buf, sizeof buf, &ksym, NULL); |
371 | if(IsKeypadKey(ksym)) { | 348 | if(IsKeypadKey(ksym)) { |
372 | if(ksym == XK_KP_Enter) | 349 | if(ksym == XK_KP_Enter) |
@@ -451,8 +428,8 @@ kpress(XKeyEvent * e) { | |||
451 | { | 428 | { |
452 | FILE *fp; | 429 | FILE *fp; |
453 | char *s; | 430 | char *s; |
454 | if(!(fp = (FILE*)popen("sselp", "r"))) | 431 | if(!(fp = popen("sselp", "r"))) |
455 | eprint("dmenu: Could not popen sselp\n"); | 432 | eprint("dmenu: cannot popen sselp\n"); |
456 | s = fgets(buf, sizeof buf, fp); | 433 | s = fgets(buf, sizeof buf, fp); |
457 | pclose(fp); | 434 | pclose(fp); |
458 | if(s == NULL) | 435 | if(s == NULL) |
@@ -470,25 +447,21 @@ kpress(XKeyEvent * e) { | |||
470 | if(num && !iscntrl((int) buf[0])) { | 447 | if(num && !iscntrl((int) buf[0])) { |
471 | memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); | 448 | memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); |
472 | memcpy(text + cursor, buf, num); | 449 | memcpy(text + cursor, buf, num); |
473 | cursor+=num; | 450 | cursor += num; |
474 | match(text); | 451 | match(text); |
475 | } | 452 | } |
476 | break; | 453 | break; |
477 | case XK_BackSpace: | 454 | case XK_BackSpace: |
478 | if(cursor > 0) { | 455 | if(cursor > 0) { |
479 | off = 1; | 456 | for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); |
480 | while(cursor > off && !IS_UTF8_1ST_CHAR(text[cursor - off])) | 457 | memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); |
481 | off++; | 458 | cursor -= i; |
482 | memmove(text + cursor - off, text + cursor, sizeof text - cursor + off); | ||
483 | cursor -= off; | ||
484 | match(text); | 459 | match(text); |
485 | } | 460 | } |
486 | break; | 461 | break; |
487 | case XK_Delete: | 462 | case XK_Delete: |
488 | off = 1; | 463 | for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); |
489 | while(cursor + off < sizeof text - 1 && !IS_UTF8_1ST_CHAR(text[cursor + off])) | 464 | memmove(text + cursor, text + cursor + i, sizeof text - cursor); |
490 | off++; | ||
491 | memmove(text + cursor, text + cursor + off, sizeof text - cursor); | ||
492 | match(text); | 465 | match(text); |
493 | break; | 466 | break; |
494 | case XK_End: | 467 | case XK_End: |
@@ -631,13 +604,13 @@ readstdin(void) { | |||
631 | if(buf[len-1] == '\n') | 604 | if(buf[len-1] == '\n') |
632 | buf[--len] = '\0'; | 605 | buf[--len] = '\0'; |
633 | if(!(p = strdup(buf))) | 606 | if(!(p = strdup(buf))) |
634 | eprint("fatal: could not strdup() %u bytes\n", len); | 607 | eprint("dmenu: cannot strdup %u bytes\n", len); |
635 | if(max < len || !maxname) { | 608 | if(max < len || !maxname) { |
636 | maxname = p; | 609 | maxname = p; |
637 | max = len; | 610 | max = len; |
638 | } | 611 | } |
639 | if(!(new = (Item *)malloc(sizeof(Item)))) | 612 | if(!(new = malloc(sizeof *new))) |
640 | eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); | 613 | eprint("dmenu: cannot malloc %u bytes\n", sizeof *new); |
641 | new->next = new->left = new->right = NULL; | 614 | new->next = new->left = new->right = NULL; |
642 | new->text = p; | 615 | new->text = p; |
643 | if(!i) | 616 | if(!i) |
@@ -785,8 +758,9 @@ main(int argc, char *argv[]) { | |||
785 | if(++i < argc) parent = atoi(argv[i]); | 758 | if(++i < argc) parent = atoi(argv[i]); |
786 | } | 759 | } |
787 | else if(!strcmp(argv[i], "-l")) { | 760 | else if(!strcmp(argv[i], "-l")) { |
788 | calcoffsets = calcoffsetsv; | ||
789 | if(++i < argc) lines = atoi(argv[i]); | 761 | if(++i < argc) lines = atoi(argv[i]); |
762 | if(lines > 0) | ||
763 | calcoffsets = calcoffsetsv; | ||
790 | } | 764 | } |
791 | else if(!strcmp(argv[i], "-fn")) { | 765 | else if(!strcmp(argv[i], "-fn")) { |
792 | if(++i < argc) font = argv[i]; | 766 | if(++i < argc) font = argv[i]; |
@@ -812,7 +786,7 @@ main(int argc, char *argv[]) { | |||
812 | eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" | 786 | eprint("usage: dmenu [-i] [-b] [-e <xid>] [-l <lines>] [-fn <font>] [-nb <color>]\n" |
813 | " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); | 787 | " [-nf <color>] [-p <prompt>] [-sb <color>] [-sf <color>] [-v]\n"); |
814 | if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) | 788 | if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) |
815 | fprintf(stderr, "warning: no locale support\n"); | 789 | fprintf(stderr, "dmenu: warning: no locale support\n"); |
816 | if(!(dpy = XOpenDisplay(NULL))) | 790 | if(!(dpy = XOpenDisplay(NULL))) |
817 | eprint("dmenu: cannot open display\n"); | 791 | eprint("dmenu: cannot open display\n"); |
818 | screen = DefaultScreen(dpy); | 792 | screen = DefaultScreen(dpy); |