commit 77526f756e23e362081ac807521f901f2e5cd5e6
Author:     NRK <n...@disroot.org>
AuthorDate: Thu Mar 24 00:37:55 2022 +0600
Commit:     Hiltjo Posthuma <hil...@codemadness.org>
CommitDate: Fri Mar 25 22:49:07 2022 +0100

    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.

diff --git a/dmenu.c b/dmenu.c
index cde394b..d989d39 100644
--- 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 */

Reply via email to