URI: 
       inputw: improve correctness and startup performance - dmenu - dynamic menu
  HTML git clone git://git.suckless.org/dmenu
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
   DIR commit 77526f756e23e362081ac807521f901f2e5cd5e6
   DIR parent 7269c5355d257dd2ad2c53f15dc9c1cf6796aea5
  HTML Author: NRK <nrk@disroot.org>
       Date:   Thu, 24 Mar 2022 00:37:55 +0600
       
       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.
       
       Diffstat:
         M dmenu.c                             |      19 +++++++++----------
       
       1 file changed, 9 insertions(+), 10 deletions(-)
       ---
   DIR diff --git a/dmenu.c b/dmenu.c
       @@ -547,8 +547,7 @@ static void
        readstdin(void)
        {
                char buf[sizeof text], *p;
       -        size_t i, imax = 0, size = 0;
       -        unsigned int tmpmax = 0;
       +        size_t i, size = 0;
        
                /* read each line from stdin and add it to the item list */
                for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
       @@ -560,15 +559,9 @@ readstdin(void)
                        if (!(items[i].text = strdup(buf)))
                                die("cannot strdup %u bytes:", strlen(buf) + 1);
                        items[i].out = 0;
       -                drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
       -                if (tmpmax > inputw) {
       -                        inputw = tmpmax;
       -                        imax = i;
       -                }
                }
                if (items)
                        items[i].text = NULL;
       -        inputw = items ? TEXTW(items[imax].text) : 0;
                lines = MIN(lines, i);
        }
        
       @@ -614,12 +607,13 @@ static void
        setup(void)
        {
                int x, y, i, j;
       -        unsigned int du;
       +        unsigned int du, tmp;
                XSetWindowAttributes swa;
                XIM xim;
                Window w, dw, *dws;
                XWindowAttributes wa;
                XClassHint ch = {"dmenu", "dmenu"};
       +        struct item *item;
        #ifdef XINERAMA
                XineramaScreenInfo *info;
                Window pw;
       @@ -677,7 +671,12 @@ setup(void)
                        mw = wa.width;
                }
                promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
       -        inputw = MIN(inputw, mw/3);
       +        for (item = items; item && item->text; ++item) {
       +                if ((tmp = textw_clamp(item->text, mw/3)) > inputw) {
       +                        if ((inputw = tmp) == mw/3)
       +                                break;
       +                }
       +        }
                match();
        
                /* create menu window */