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); |
