X-Git-Url: https://git.danieliu.xyz/?a=blobdiff_plain;f=dmenu.c;h=05d150672f150021382275c2fd7c85fc17cc6c4e;hb=6366f94e36e958d9856738a4dbed0a5e1c3926eb;hp=bebc2065031cfac2e2778af52ba7fbb9734f3680;hpb=5bc288b2b1270957baab2142e1e8b20b796fed11;p=dmenu.git diff --git a/dmenu.c b/dmenu.c index bebc206..05d1506 100644 --- a/dmenu.c +++ b/dmenu.c @@ -19,6 +19,7 @@ #define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define IS_UTF8_1ST_CHAR(c) ((((c) & 0xc0) == 0xc0) || !((c) & 0x80)) /* enums */ enum { ColFG, ColBG, ColLast }; @@ -42,8 +43,8 @@ typedef struct { typedef struct Item Item; struct Item { char *text; - Item *next; /* traverses all items */ - Item *left, *right; /* traverses items matching current search pattern */ + Item *next; /* traverses all items */ + Item *left, *right; /* traverses items matching current search pattern */ }; /* forward declarations */ @@ -85,8 +86,8 @@ static unsigned int numlockmask = 0; static Bool running = True; static Display *dpy; static DC dc; -static Item *allitems = NULL; /* first of all items */ -static Item *item = NULL; /* first of pattern matching items */ +static Item *allitems = NULL; /* first of all items */ +static Item *item = NULL; /* first of pattern matching items */ static Item *sel = NULL; static Item *next = NULL; static Item *prev = NULL; @@ -110,45 +111,30 @@ appenditem(Item *i, Item **list, Item **last) { void calcoffsetsh(void) { - int tw; unsigned int w; if(!curr) return; w = promptw + cmdw + 2 * spaceitem; - for(next = curr; next; next=next->right) { - tw = MIN(textw(next->text), mw / 3); - w += tw; - if(w > mw) - break; - } + for(next = curr; next && w < mw; next=next->right) + w += MIN(textw(next->text), mw / 3); w = promptw + cmdw + 2 * spaceitem; - for(prev = curr; prev && prev->left; prev=prev->left) { - tw = MIN(textw(prev->left->text), mw / 3); - w += tw; - if(w > mw) - break; - } + for(prev = curr; prev && prev->left && w < mw; prev=prev->left) + w += MIN(textw(prev->left->text), mw / 3); } void calcoffsetsv(void) { - static unsigned int h; + unsigned int h; if(!curr) return; - h = (dc.font.height + 2) * (lines + 1); - for(next = curr; next; next=next->right) { + h = (dc.font.height + 2) * lines; + for(next = curr; next && h > 0; next = next->right) h -= dc.font.height + 2; - if(h <= 0) - break; - } - h = (dc.font.height + 2) * (lines + 1); - for(prev = curr; prev && prev->left; prev=prev->left) { + h = (dc.font.height + 2) * lines; + for(prev = curr; prev && prev->left && h > 0; prev = prev->left) h -= dc.font.height + 2; - if(h <= 0) - break; - } } char * @@ -176,14 +162,6 @@ cistrstr(const char *s, const char *sub) { void cleanup(void) { - Item *itm; - - while(allitems) { - itm = allitems->next; - free(allitems->text); - free(allitems); - allitems = itm; - } if(dc.font.set) XFreeFontSet(dpy, dc.font.set); else @@ -256,11 +234,13 @@ drawmenuv(void) { Item *i; dc.w = mw - dc.x; - dc.y += dc.font.height + 2; + dc.h = dc.font.height + 2; + dc.y = dc.h; for(i = curr; i != next; i=i->right) { drawtext(i->text, (sel == i) ? dc.sel : dc.norm); - dc.y += dc.font.height + 2; + dc.y += dc.h; } + dc.h = mh - dc.y; drawtext(NULL, dc.norm); } @@ -308,7 +288,7 @@ getcolor(const char *colstr) { XColor color; if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) - eprint("error, cannot allocate color '%s'\n", colstr); + eprint("dmenu: cannot allocate color '%s'\n", colstr); return color.pixel; } @@ -327,12 +307,11 @@ grabkeyboard(void) { void initfont(const char *fontstr) { - char *def, **missing; + char *def, **missing = NULL; int i, n; if(!fontstr || fontstr[0] == '\0') - eprint("error, cannot load font: '%s'\n", fontstr); - missing = NULL; + eprint("dmenu: cannot load font: '%s'\n", fontstr); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); if(missing) XFreeStringList(missing); @@ -350,7 +329,7 @@ initfont(const char *fontstr) { else { if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) - eprint("error, cannot load font: '%s'\n", fontstr); + eprint("dmenu: cannot load font: '%s'\n", fontstr); dc.font.ascent = dc.font.xfont->ascent; dc.font.descent = dc.font.xfont->descent; } @@ -365,7 +344,6 @@ kpress(XKeyEvent * e) { KeySym ksym; len = strlen(text); - buf[0] = '\0'; num = XLookupString(e, buf, sizeof buf, &ksym, NULL); if(IsKeypadKey(ksym)) { if(ksym == XK_KP_Enter) @@ -450,8 +428,8 @@ kpress(XKeyEvent * e) { { FILE *fp; char *s; - if(!(fp = (FILE*)popen("sselp", "r"))) - eprint("dmenu: Could not popen sselp\n"); + if(!(fp = popen("sselp", "r"))) + eprint("dmenu: cannot popen sselp\n"); s = fgets(buf, sizeof buf, fp); pclose(fp); if(s == NULL) @@ -469,19 +447,21 @@ kpress(XKeyEvent * e) { if(num && !iscntrl((int) buf[0])) { memmove(text + cursor + num, text + cursor, sizeof text - cursor - num); memcpy(text + cursor, buf, num); - cursor+=num; + cursor += num; match(text); } break; case XK_BackSpace: if(cursor > 0) { - memmove(text + cursor - 1, text + cursor, sizeof text - cursor + 1); - cursor--; + for(i = 1; cursor - i > 0 && !IS_UTF8_1ST_CHAR(text[cursor - i]); i++); + memmove(text + cursor - i, text + cursor, sizeof text - cursor + i); + cursor -= i; match(text); } break; case XK_Delete: - memmove(text + cursor, text + cursor + 1, sizeof text - cursor); + for(i = 1; cursor + i < len && !IS_UTF8_1ST_CHAR(text[cursor + i]); i++); + memmove(text + cursor, text + cursor + i, sizeof text - cursor); match(text); break; case XK_End: @@ -517,9 +497,11 @@ kpress(XKeyEvent * e) { calcoffsets(); } } - else if(cursor > 0) - cursor--; - else + else if(cursor > 0) { + do { + cursor--; + } while(cursor > 0 && !IS_UTF8_1ST_CHAR(text[cursor])); + } else return; break; case XK_Next: @@ -544,9 +526,11 @@ kpress(XKeyEvent * e) { break; case XK_Right: case XK_Down: - if(cursor < len) - cursor++; - else if(sel && sel->right) { + if(cursor < len) { + do { + cursor++; + } while(cursor < len && !IS_UTF8_1ST_CHAR(text[cursor])); + } else if(sel && sel->right) { sel=sel->right; if(sel == next) { curr = next; @@ -620,13 +604,13 @@ readstdin(void) { if(buf[len-1] == '\n') buf[--len] = '\0'; if(!(p = strdup(buf))) - eprint("fatal: could not strdup() %u bytes\n", len); + eprint("dmenu: cannot strdup %u bytes\n", len); if(max < len || !maxname) { maxname = p; max = len; } - if(!(new = (Item *)malloc(sizeof(Item)))) - eprint("fatal: could not malloc() %u bytes\n", sizeof(Item)); + if(!(new = malloc(sizeof *new))) + eprint("dmenu: cannot malloc %u bytes\n", sizeof *new); new->next = new->left = new->right = NULL; new->text = p; if(!i) @@ -774,8 +758,9 @@ main(int argc, char *argv[]) { if(++i < argc) parent = atoi(argv[i]); } else if(!strcmp(argv[i], "-l")) { - calcoffsets = calcoffsetsv; if(++i < argc) lines = atoi(argv[i]); + if(lines > 0) + calcoffsets = calcoffsetsv; } else if(!strcmp(argv[i], "-fn")) { if(++i < argc) font = argv[i]; @@ -801,7 +786,7 @@ main(int argc, char *argv[]) { eprint("usage: dmenu [-i] [-b] [-e ] [-l ] [-fn ] [-nb ]\n" " [-nf ] [-p ] [-sb ] [-sf ] [-v]\n"); if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fprintf(stderr, "warning: no locale support\n"); + fprintf(stderr, "dmenu: warning: no locale support\n"); if(!(dpy = XOpenDisplay(NULL))) eprint("dmenu: cannot open display\n"); screen = DefaultScreen(dpy);