diff options
| author | NRK <nrk@disroot.org> | 2022-03-24 00:37:55 +0600 | 
|---|---|---|
| committer | Hiltjo Posthuma <hiltjo@codemadness.org> | 2022-03-25 22:49:07 +0100 | 
| commit | 77526f756e23e362081ac807521f901f2e5cd5e6 (patch) | |
| tree | 4028e5ba2c5ad85e51fd1f17a124f0851289427b | |
| parent | 7269c5355d257dd2ad2c53f15dc9c1cf6796aea5 (diff) | |
inputw: improve correctness and startup performance
a massive amount of time inside readstdin() is spent trying to get the
max input width and then put it into inputw, only for it to get clamped
down to mw/3 inside setup().
it makes more sense to calculate inputw inside setup() once we have mw
available. similar to the last patch, i see noticeable startup
performance improvement:
before -> after
160ms  -> 60ms
additionally this will take fallback fonts into account compared to the
previous version, so it's not only more performant but also more correct.
| -rw-r--r-- | dmenu.c | 19 | 
1 files changed, 9 insertions, 10 deletions
| @@ -547,8 +547,7 @@ static void | |||
| 547 | readstdin(void) | 547 | readstdin(void) | 
| 548 | { | 548 | { | 
| 549 | char buf[sizeof text], *p; | 549 | char buf[sizeof text], *p; | 
| 550 | size_t i, imax = 0, size = 0; | 550 | size_t i, size = 0; | 
| 551 | unsigned int tmpmax = 0; | ||
| 552 | 551 | ||
| 553 | /* read each line from stdin and add it to the item list */ | 552 | /* read each line from stdin and add it to the item list */ | 
| 554 | for (i = 0; fgets(buf, sizeof buf, stdin); i++) { | 553 | for (i = 0; fgets(buf, sizeof buf, stdin); i++) { | 
| @@ -560,15 +559,9 @@ readstdin(void) | |||
| 560 | if (!(items[i].text = strdup(buf))) | 559 | if (!(items[i].text = strdup(buf))) | 
| 561 | die("cannot strdup %u bytes:", strlen(buf) + 1); | 560 | die("cannot strdup %u bytes:", strlen(buf) + 1); | 
| 562 | items[i].out = 0; | 561 | items[i].out = 0; | 
| 563 | drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL); | ||
| 564 | if (tmpmax > inputw) { | ||
| 565 | inputw = tmpmax; | ||
| 566 | imax = i; | ||
| 567 | } | ||
| 568 | } | 562 | } | 
| 569 | if (items) | 563 | if (items) | 
| 570 | items[i].text = NULL; | 564 | items[i].text = NULL; | 
| 571 | inputw = items ? TEXTW(items[imax].text) : 0; | ||
| 572 | lines = MIN(lines, i); | 565 | lines = MIN(lines, i); | 
| 573 | } | 566 | } | 
| 574 | 567 | ||
| @@ -614,12 +607,13 @@ static void | |||
| 614 | setup(void) | 607 | setup(void) | 
| 615 | { | 608 | { | 
| 616 | int x, y, i, j; | 609 | int x, y, i, j; | 
| 617 | unsigned int du; | 610 | unsigned int du, tmp; | 
| 618 | XSetWindowAttributes swa; | 611 | XSetWindowAttributes swa; | 
| 619 | XIM xim; | 612 | XIM xim; | 
| 620 | Window w, dw, *dws; | 613 | Window w, dw, *dws; | 
| 621 | XWindowAttributes wa; | 614 | XWindowAttributes wa; | 
| 622 | XClassHint ch = {"dmenu", "dmenu"}; | 615 | XClassHint ch = {"dmenu", "dmenu"}; | 
| 616 | struct item *item; | ||
| 623 | #ifdef XINERAMA | 617 | #ifdef XINERAMA | 
| 624 | XineramaScreenInfo *info; | 618 | XineramaScreenInfo *info; | 
| 625 | Window pw; | 619 | Window pw; | 
| @@ -677,7 +671,12 @@ setup(void) | |||
| 677 | mw = wa.width; | 671 | mw = wa.width; | 
| 678 | } | 672 | } | 
| 679 | promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; | 673 | promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0; | 
| 680 | inputw = MIN(inputw, mw/3); | 674 | for (item = items; item && item->text; ++item) { | 
| 675 | if ((tmp = textw_clamp(item->text, mw/3)) > inputw) { | ||
| 676 | if ((inputw = tmp) == mw/3) | ||
| 677 | break; | ||
| 678 | } | ||
| 679 | } | ||
| 681 | match(); | 680 | match(); | 
| 682 | 681 | ||
| 683 | /* create menu window */ | 682 | /* create menu window */ | 
