Xinqi Bao's Git

avoid redraw when there's no change
[dmenu.git] / dmenu.c
diff --git a/dmenu.c b/dmenu.c
index cde394b..19f6385 100644 (file)
--- a/dmenu.c
+++ b/dmenu.c
@@ -104,6 +104,9 @@ cleanup(void)
        XUngrabKey(dpy, AnyKey, AnyModifier, root);
        for (i = 0; i < SchemeLast; i++)
                free(scheme[i]);
+       for (i = 0; items && items[i].text; ++i)
+               free(items[i].text);
+       free(items);
        drw_free(drw);
        XSync(dpy, False);
        XCloseDisplay(dpy);
@@ -239,7 +242,7 @@ match(void)
        /* separate input text into tokens to be matched individually */
        for (s = strtok(buf, " "); s; tokv[tokc - 1] = s, s = strtok(NULL, " "))
                if (++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
-                       die("cannot realloc %u bytes:", tokn * sizeof *tokv);
+                       die("cannot realloc %zu bytes:", tokn * sizeof *tokv);
        len = tokc ? strlen(tokv[0]) : 0;
 
        matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
@@ -412,8 +415,9 @@ keypress(XKeyEvent *ev)
        switch(ksym) {
        default:
 insert:
-               if (!iscntrl(*buf))
-                       insert(buf, len);
+               if (iscntrl((unsigned char)*buf))
+                       return;
+               insert(buf, len);
                break;
        case XK_Delete:
        case XK_KP_Delete:
@@ -547,28 +551,21 @@ 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++) {
                if (i + 1 >= size / sizeof *items)
                        if (!(items = realloc(items, (size += BUFSIZ))))
-                               die("cannot realloc %u bytes:", size);
+                               die("cannot realloc %zu bytes:", size);
                if ((p = strchr(buf, '\n')))
                        *p = '\0';
                if (!(items[i].text = strdup(buf)))
-                       die("cannot strdup %u bytes:", strlen(buf) + 1);
+                       die("cannot strdup %zu 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 +611,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 +675,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 */