aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgtags1
-rw-r--r--Makefile4
-rw-r--r--config.mk2
-rw-r--r--dmenu.115
-rw-r--r--dmenu.c186
-rwxr-xr-xdmenu_run2
-rw-r--r--draw.c22
-rw-r--r--draw.h1
-rw-r--r--lsx.c4
9 files changed, 118 insertions, 119 deletions
diff --git a/.hgtags b/.hgtags
index dcceb88..c92818f 100644
--- a/.hgtags
+++ b/.hgtags
@@ -46,3 +46,4 @@ e4c81a78ffbad6ba4d1ad119cc654da6eca63a4c 3.2
46abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1 46abb6579a324fffdf6a23c2fa4c32911277da594a 4.2.1
4714c79f054bdf43ff3213af8e60a783192e92a018 4.3 4714c79f054bdf43ff3213af8e60a783192e92a018 4.3
4834a2d77049a95b02f3332a0b88f9370965ebcfad 4.3.1 4834a2d77049a95b02f3332a0b88f9370965ebcfad 4.3.1
492b105eaae8315b076da93056da9ecd60de5a7ac9 4.4
diff --git a/Makefile b/Makefile
index f3f6b3d..1135d65 100644
--- a/Makefile
+++ b/Makefile
@@ -30,12 +30,12 @@ lsx: lsx.o
30 30
31clean: 31clean:
32 @echo cleaning 32 @echo cleaning
33 @rm -f dmenu ${OBJ} dmenu-${VERSION}.tar.gz 33 @rm -f dmenu lsx ${OBJ} dmenu-${VERSION}.tar.gz
34 34
35dist: clean 35dist: clean
36 @echo creating dist tarball 36 @echo creating dist tarball
37 @mkdir -p dmenu-${VERSION} 37 @mkdir -p dmenu-${VERSION}
38 @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run ${SRC} dmenu-${VERSION} 38 @cp LICENSE Makefile README config.mk dmenu.1 draw.h dmenu_run lsx.1 ${SRC} dmenu-${VERSION}
39 @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION} 39 @tar -cf dmenu-${VERSION}.tar dmenu-${VERSION}
40 @gzip dmenu-${VERSION}.tar 40 @gzip dmenu-${VERSION}.tar
41 @rm -rf dmenu-${VERSION} 41 @rm -rf dmenu-${VERSION}
diff --git a/config.mk b/config.mk
index 70c9e36..f66389d 100644
--- a/config.mk
+++ b/config.mk
@@ -1,5 +1,5 @@
1# dmenu version 1# dmenu version
2VERSION = 4.3.1 2VERSION = hg
3 3
4# paths 4# paths
5PREFIX = /usr/local 5PREFIX = /usr/local
diff --git a/dmenu.1 b/dmenu.1
index 616a2a5..7243a36 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -25,13 +25,10 @@ dmenu \- dynamic menu
25.BR dmenu_run " ..." 25.BR dmenu_run " ..."
26.SH DESCRIPTION 26.SH DESCRIPTION
27.B dmenu 27.B dmenu
28is a dynamic menu for X, originally designed for 28is a dynamic menu for X, which reads a list of newline\-separated items from
29.IR dwm (1). 29stdin. When the user selects an item and presses Return, their choice is printed
30It manages huge numbers of user\-defined menu items efficiently. 30to stdout and dmenu terminates. Entering text will narrow the items to those
31.P 31matching the tokens in the input.
32dmenu reads a list of newline\-separated items from stdin and creates a menu.
33When the user selects an item or enters any text and presses Return, their
34choice is printed to stdout and dmenu terminates.
35.P 32.P
36.B dmenu_run 33.B dmenu_run
37is a dmenu script used by dwm which lists programs in the user's $PATH and 34is a dmenu script used by dwm which lists programs in the user's $PATH and
@@ -42,8 +39,8 @@ executes the selected item.
42dmenu appears at the bottom of the screen. 39dmenu appears at the bottom of the screen.
43.TP 40.TP
44.B \-f 41.B \-f
45dmenu grabs the keyboard before reading stdin. This is faster, but may lock up 42dmenu grabs the keyboard before reading stdin. This is faster, but will lock up
46X if stdin is from a terminal. 43X until stdin reaches end\-of\-file.
47.TP 44.TP
48.B \-i 45.B \-i
49dmenu matches menu items case insensitively. 46dmenu matches menu items case insensitively.
diff --git a/dmenu.c b/dmenu.c
index d03087f..f105b56 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -25,12 +25,12 @@ struct Item {
25 25
26static void appenditem(Item *item, Item **list, Item **last); 26static void appenditem(Item *item, Item **list, Item **last);
27static void calcoffsets(void); 27static void calcoffsets(void);
28static char *cistrstr(const char *s, const char *sub);
28static void drawmenu(void); 29static void drawmenu(void);
29static char *fstrstr(const char *s, const char *sub);
30static void grabkeyboard(void); 30static void grabkeyboard(void);
31static void insert(const char *str, ssize_t n); 31static void insert(const char *str, ssize_t n);
32static void keypress(XKeyEvent *ev); 32static void keypress(XKeyEvent *ev);
33static void match(Bool sub); 33static void match(void);
34static size_t nextrune(int inc); 34static size_t nextrune(int inc);
35static void paste(void); 35static void paste(void);
36static void readstdin(void); 36static void readstdin(void);
@@ -60,6 +60,7 @@ static Item *prev, *curr, *next, *sel;
60static Window win; 60static Window win;
61 61
62static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; 62static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
63static char *(*fstrstr)(const char *, const char *) = strstr;
63 64
64int 65int
65main(int argc, char *argv[]) { 66main(int argc, char *argv[]) {
@@ -76,8 +77,10 @@ main(int argc, char *argv[]) {
76 topbar = False; 77 topbar = False;
77 else if(!strcmp(argv[i], "-f")) 78 else if(!strcmp(argv[i], "-f"))
78 fast = True; 79 fast = True;
79 else if(!strcmp(argv[i], "-i")) 80 else if(!strcmp(argv[i], "-i")) {
80 fstrncmp = strncasecmp; 81 fstrncmp = strncasecmp;
82 fstrstr = cistrstr;
83 }
81 else if(i+1 == argc) 84 else if(i+1 == argc)
82 usage(); 85 usage();
83 /* double flags */ 86 /* double flags */
@@ -112,15 +115,16 @@ main(int argc, char *argv[]) {
112 setup(); 115 setup();
113 run(); 116 run();
114 117
115 return EXIT_FAILURE; /* should not reach */ 118 return EXIT_FAILURE; /* unreachable */
116} 119}
117 120
118void 121void
119appenditem(Item *item, Item **list, Item **last) { 122appenditem(Item *item, Item **list, Item **last) {
120 if(!*last) 123 if(*last)
121 *list = item;
122 else
123 (*last)->right = item; 124 (*last)->right = item;
125 else
126 *list = item;
127
124 item->left = *last; 128 item->left = *last;
125 item->right = NULL; 129 item->right = NULL;
126 *last = item; 130 *last = item;
@@ -143,6 +147,16 @@ calcoffsets(void) {
143 break; 147 break;
144} 148}
145 149
150char *
151cistrstr(const char *s, const char *sub) {
152 size_t len;
153
154 for(len = strlen(sub); *s; s++)
155 if(!strncasecmp(s, sub, len))
156 return (char *)s;
157 return NULL;
158}
159
146void 160void
147drawmenu(void) { 161drawmenu(void) {
148 int curpos; 162 int curpos;
@@ -188,16 +202,6 @@ drawmenu(void) {
188 mapdc(dc, win, mw, mh); 202 mapdc(dc, win, mw, mh);
189} 203}
190 204
191char *
192fstrstr(const char *s, const char *sub) {
193 size_t len;
194
195 for(len = strlen(sub); *s; s++)
196 if(!fstrncmp(s, sub, len))
197 return (char *)s;
198 return NULL;
199}
200
201void 205void
202grabkeyboard(void) { 206grabkeyboard(void) {
203 int i; 207 int i;
@@ -219,7 +223,7 @@ insert(const char *str, ssize_t n) {
219 if(n > 0) 223 if(n > 0)
220 memcpy(&text[cursor], str, n); 224 memcpy(&text[cursor], str, n);
221 cursor += n; 225 cursor += n;
222 match(n > 0 && text[cursor] == '\0'); 226 match();
223} 227}
224 228
225void 229void
@@ -233,58 +237,37 @@ keypress(XKeyEvent *ev) {
233 237
234 XConvertCase(ksym, &lower, &upper); 238 XConvertCase(ksym, &lower, &upper);
235 switch(lower) { 239 switch(lower) {
236 default: 240 case XK_a: ksym = XK_Home; break;
237 return; 241 case XK_b: ksym = XK_Left; break;
238 case XK_a: 242 case XK_c: ksym = XK_Escape; break;
239 ksym = XK_Home; 243 case XK_d: ksym = XK_Delete; break;
240 break; 244 case XK_e: ksym = XK_End; break;
241 case XK_b: 245 case XK_f: ksym = XK_Right; break;
242 ksym = XK_Left; 246 case XK_h: ksym = XK_BackSpace; break;
243 break; 247 case XK_i: ksym = XK_Tab; break;
244 case XK_c: 248 case XK_j: ksym = XK_Return; break;
245 ksym = XK_Escape; 249 case XK_m: ksym = XK_Return; break;
246 break; 250 case XK_n: ksym = XK_Up; break;
247 case XK_d: 251 case XK_p: ksym = XK_Down; break;
248 ksym = XK_Delete; 252
249 break; 253 case XK_k: /* delete right */
250 case XK_e:
251 ksym = XK_End;
252 break;
253 case XK_f:
254 ksym = XK_Right;
255 break;
256 case XK_h:
257 ksym = XK_BackSpace;
258 break;
259 case XK_i:
260 ksym = XK_Tab;
261 break;
262 case XK_j:
263 case XK_m:
264 ksym = XK_Return;
265 break;
266 case XK_k: /* delete right */
267 text[cursor] = '\0'; 254 text[cursor] = '\0';
268 match(False); 255 match();
269 break;
270 case XK_n:
271 ksym = XK_Down;
272 break;
273 case XK_p:
274 ksym = XK_Up;
275 break; 256 break;
276 case XK_u: /* delete left */ 257 case XK_u: /* delete left */
277 insert(NULL, 0 - cursor); 258 insert(NULL, 0 - cursor);
278 break; 259 break;
279 case XK_w: /* delete word */ 260 case XK_w: /* delete word */
280 while(cursor > 0 && text[nextrune(-1)] == ' ') 261 while(cursor > 0 && text[nextrune(-1)] == ' ')
281 insert(NULL, nextrune(-1) - cursor); 262 insert(NULL, nextrune(-1) - cursor);
282 while(cursor > 0 && text[nextrune(-1)] != ' ') 263 while(cursor > 0 && text[nextrune(-1)] != ' ')
283 insert(NULL, nextrune(-1) - cursor); 264 insert(NULL, nextrune(-1) - cursor);
284 break; 265 break;
285 case XK_y: /* paste selection */ 266 case XK_y: /* paste selection */
286 XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime); 267 XConvertSelection(dc->dpy, XA_PRIMARY, utf8, utf8, win, CurrentTime);
287 return; 268 return;
269 default:
270 return;
288 } 271 }
289 } 272 }
290 switch(ksym) { 273 switch(ksym) {
@@ -296,9 +279,11 @@ keypress(XKeyEvent *ev) {
296 if(text[cursor] == '\0') 279 if(text[cursor] == '\0')
297 return; 280 return;
298 cursor = nextrune(+1); 281 cursor = nextrune(+1);
282 /* fallthrough */
299 case XK_BackSpace: 283 case XK_BackSpace:
300 if(cursor > 0) 284 if(cursor == 0)
301 insert(NULL, nextrune(-1) - cursor); 285 return;
286 insert(NULL, nextrune(-1) - cursor);
302 break; 287 break;
303 case XK_End: 288 case XK_End:
304 if(text[cursor] != '\0') { 289 if(text[cursor] != '\0') {
@@ -330,8 +315,7 @@ keypress(XKeyEvent *ev) {
330 cursor = nextrune(-1); 315 cursor = nextrune(-1);
331 break; 316 break;
332 } 317 }
333 else if(lines > 0) 318 /* fallthrough */
334 return;
335 case XK_Up: 319 case XK_Up:
336 if(sel && sel->left && (sel = sel->left)->right == curr) { 320 if(sel && sel->left && (sel = sel->left)->right == curr) {
337 curr = prev; 321 curr = prev;
@@ -352,15 +336,14 @@ keypress(XKeyEvent *ev) {
352 break; 336 break;
353 case XK_Return: 337 case XK_Return:
354 case XK_KP_Enter: 338 case XK_KP_Enter:
355 fputs((sel && !(ev->state & ShiftMask)) ? sel->text : text, stdout); 339 puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
356 exit(EXIT_SUCCESS); 340 exit(EXIT_SUCCESS);
357 case XK_Right: 341 case XK_Right:
358 if(text[cursor] != '\0') { 342 if(text[cursor] != '\0') {
359 cursor = nextrune(+1); 343 cursor = nextrune(+1);
360 break; 344 break;
361 } 345 }
362 else if(lines > 0) 346 /* fallthrough */
363 return;
364 case XK_Down: 347 case XK_Down:
365 if(sel && sel->right && (sel = sel->right) == next) { 348 if(sel && sel->right && (sel = sel->right) == next) {
366 curr = next; 349 curr = next;
@@ -372,33 +355,44 @@ keypress(XKeyEvent *ev) {
372 return; 355 return;
373 strncpy(text, sel->text, sizeof text); 356 strncpy(text, sel->text, sizeof text);
374 cursor = strlen(text); 357 cursor = strlen(text);
375 match(True); 358 match();
376 break; 359 break;
377 } 360 }
378 drawmenu(); 361 drawmenu();
379} 362}
380 363
381void 364void
382match(Bool sub) { 365match(void) {
383 size_t len = strlen(text); 366 static char **tokv = NULL;
384 Item *lexact, *lprefix, *lsubstr, *exactend, *prefixend, *substrend; 367 static int tokn = 0;
385 Item *item, *lnext; 368
386 369 char buf[sizeof text], *s;
387 lexact = lprefix = lsubstr = exactend = prefixend = substrend = NULL; 370 int i, tokc = 0;
388 for(item = sub ? matches : items; item && item->text; item = lnext) { 371 size_t len;
389 lnext = sub ? item->right : item + 1; 372 Item *item, *lprefix, *lsubstr, *prefixend, *substrend;
390 if(!fstrncmp(text, item->text, len + 1)) 373
391 appenditem(item, &lexact, &exactend); 374 strcpy(buf, text);
392 else if(!fstrncmp(text, item->text, len)) 375 for(s = strtok(buf, " "); s; tokv[tokc-1] = s, s = strtok(NULL, " "))
376 if(++tokc > tokn && !(tokv = realloc(tokv, ++tokn * sizeof *tokv)))
377 eprintf("cannot realloc %u bytes\n", tokn * sizeof *tokv);
378 len = tokc ? strlen(tokv[0]) : 0;
379
380 matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
381 for(item = items; item && item->text; item++) {
382 for(i = 0; i < tokc; i++)
383 if(!fstrstr(item->text, tokv[i]))
384 break;
385 if(i != tokc)
386 continue;
387 if(!tokc || !fstrncmp(tokv[0], item->text, len+1))
388 appenditem(item, &matches, &matchend);
389 else if(!fstrncmp(tokv[0], item->text, len))
393 appenditem(item, &lprefix, &prefixend); 390 appenditem(item, &lprefix, &prefixend);
394 else if(fstrstr(item->text, text)) 391 else
395 appenditem(item, &lsubstr, &substrend); 392 appenditem(item, &lsubstr, &substrend);
396 } 393 }
397 matches = lexact;
398 matchend = exactend;
399
400 if(lprefix) { 394 if(lprefix) {
401 if(matchend) { 395 if(matches) {
402 matchend->right = lprefix; 396 matchend->right = lprefix;
403 lprefix->left = matchend; 397 lprefix->left = matchend;
404 } 398 }
@@ -407,7 +401,7 @@ match(Bool sub) {
407 matchend = prefixend; 401 matchend = prefixend;
408 } 402 }
409 if(lsubstr) { 403 if(lsubstr) {
410 if(matchend) { 404 if(matches) {
411 matchend->right = lsubstr; 405 matchend->right = lsubstr;
412 lsubstr->left = matchend; 406 lsubstr->left = matchend;
413 } 407 }
@@ -460,6 +454,7 @@ readstdin(void) {
460 if(items) 454 if(items)
461 items[i].text = NULL; 455 items[i].text = NULL;
462 inputw = maxstr ? textw(dc, maxstr) : 0; 456 inputw = maxstr ? textw(dc, maxstr) : 0;
457 lines = MIN(lines, i);
463} 458}
464 459
465void 460void
@@ -470,7 +465,7 @@ run(void) {
470 switch(ev.type) { 465 switch(ev.type) {
471 case Expose: 466 case Expose:
472 if(ev.xexpose.count == 0) 467 if(ev.xexpose.count == 0)
473 drawmenu(); 468 mapdc(dc, win, mw, mh);
474 break; 469 break;
475 case KeyPress: 470 case KeyPress:
476 keypress(&ev.xkey); 471 keypress(&ev.xkey);
@@ -490,7 +485,7 @@ void
490setup(void) { 485setup(void) {
491 int x, y, screen = DefaultScreen(dc->dpy); 486 int x, y, screen = DefaultScreen(dc->dpy);
492 Window root = RootWindow(dc->dpy, screen); 487 Window root = RootWindow(dc->dpy, screen);
493 XSetWindowAttributes wa; 488 XSetWindowAttributes swa;
494#ifdef XINERAMA 489#ifdef XINERAMA
495 int n; 490 int n;
496 XineramaScreenInfo *info; 491 XineramaScreenInfo *info;
@@ -511,9 +506,14 @@ setup(void) {
511 if((info = XineramaQueryScreens(dc->dpy, &n))) { 506 if((info = XineramaQueryScreens(dc->dpy, &n))) {
512 int i, di; 507 int i, di;
513 unsigned int du; 508 unsigned int du;
514 Window dw; 509 Window w, dw;
510 XWindowAttributes wa;
515 511
516 XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); 512 XGetInputFocus(dc->dpy, &w, &di);
513 if(w != root && w != PointerRoot && w != None && XGetWindowAttributes(dc->dpy, w, &wa))
514 XTranslateCoordinates(dc->dpy, w, root, wa.x, wa.y, &x, &y, &dw);
515 else
516 XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du);
517 for(i = 0; i < n-1; i++) 517 for(i = 0; i < n-1; i++)
518 if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) 518 if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
519 break; 519 break;
@@ -531,16 +531,16 @@ setup(void) {
531 } 531 }
532 promptw = prompt ? textw(dc, prompt) : 0; 532 promptw = prompt ? textw(dc, prompt) : 0;
533 inputw = MIN(inputw, mw/3); 533 inputw = MIN(inputw, mw/3);
534 match(False); 534 match();
535 535
536 /* menu window */ 536 /* menu window */
537 wa.override_redirect = True; 537 swa.override_redirect = True;
538 wa.background_pixmap = ParentRelative; 538 swa.background_pixmap = ParentRelative;
539 wa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; 539 swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
540 win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0, 540 win = XCreateWindow(dc->dpy, root, x, y, mw, mh, 0,
541 DefaultDepth(dc->dpy, screen), CopyFromParent, 541 DefaultDepth(dc->dpy, screen), CopyFromParent,
542 DefaultVisual(dc->dpy, screen), 542 DefaultVisual(dc->dpy, screen),
543 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); 543 CWOverrideRedirect | CWBackPixmap | CWEventMask, &swa);
544 544
545 XMapRaised(dc->dpy, win); 545 XMapRaised(dc->dpy, win);
546 resizedc(dc, mw, mh); 546 resizedc(dc, mw, mh);
diff --git a/dmenu_run b/dmenu_run
index 6e96b38..2d12243 100755
--- a/dmenu_run
+++ b/dmenu_run
@@ -6,4 +6,4 @@ CACHE=${XDG_CACHE_HOME:-"$HOME/.cache"}/dmenu_run
6 mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE" 6 mkdir -p "`dirname "$CACHE"`" && lsx $PATH | sort -u > "$CACHE"
7 fi 7 fi
8) 8)
9cmd=`dmenu "$@" < "$CACHE"` && exec $cmd 9cmd=`dmenu "$@" < "$CACHE"` && exec sh -c "$cmd"
diff --git a/draw.c b/draw.c
index f952b53..76f0c54 100644
--- a/draw.c
+++ b/draw.c
@@ -96,7 +96,7 @@ initdc(void) {
96 DC *dc; 96 DC *dc;
97 97
98 if(!setlocale(LC_CTYPE, "") || !XSupportsLocale()) 98 if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
99 fprintf(stderr, "no locale support\n"); 99 fputs("no locale support\n", stderr);
100 if(!(dc = calloc(1, sizeof *dc))) 100 if(!(dc = calloc(1, sizeof *dc)))
101 eprintf("cannot malloc %u bytes:", sizeof *dc); 101 eprintf("cannot malloc %u bytes:", sizeof *dc);
102 if(!(dc->dpy = XOpenDisplay(NULL))) 102 if(!(dc->dpy = XOpenDisplay(NULL)))
@@ -120,28 +120,28 @@ initfont(DC *dc, const char *fontstr) {
120 120
121Bool 121Bool
122loadfont(DC *dc, const char *fontstr) { 122loadfont(DC *dc, const char *fontstr) {
123 char *def, **missing; 123 char *def, **missing, **names;
124 int i, n; 124 int i, n;
125 XFontStruct **xfonts;
125 126
126 if(!*fontstr) 127 if(!*fontstr)
127 return False; 128 return False;
128 if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { 129 if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) {
129 char **names;
130 XFontStruct **xfonts;
131
132 n = XFontsOfFontSet(dc->font.set, &xfonts, &names); 130 n = XFontsOfFontSet(dc->font.set, &xfonts, &names);
133 for(i = dc->font.ascent = dc->font.descent = 0; i < n; i++) { 131 for(i = 0; i < n; i++) {
134 dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent); 132 dc->font.ascent = MAX(dc->font.ascent, xfonts[i]->ascent);
135 dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); 133 dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent);
134 dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width);
136 } 135 }
137 } 136 }
138 else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { 137 else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) {
139 dc->font.ascent = dc->font.xfont->ascent; 138 dc->font.ascent = dc->font.xfont->ascent;
140 dc->font.descent = dc->font.xfont->descent; 139 dc->font.descent = dc->font.xfont->descent;
140 dc->font.width = dc->font.xfont->max_bounds.width;
141 } 141 }
142 if(missing) 142 if(missing)
143 XFreeStringList(missing); 143 XFreeStringList(missing);
144 return (dc->font.set || dc->font.xfont); 144 return dc->font.set || dc->font.xfont;
145} 145}
146 146
147void 147void
@@ -154,10 +154,10 @@ resizedc(DC *dc, unsigned int w, unsigned int h) {
154 if(dc->canvas) 154 if(dc->canvas)
155 XFreePixmap(dc->dpy, dc->canvas); 155 XFreePixmap(dc->dpy, dc->canvas);
156 156
157 dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
158 DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
159 dc->w = w; 157 dc->w = w;
160 dc->h = h; 158 dc->h = h;
159 dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h,
160 DefaultDepth(dc->dpy, DefaultScreen(dc->dpy)));
161} 161}
162 162
163int 163int
diff --git a/draw.h b/draw.h
index 247c0b3..43a57bf 100644
--- a/draw.h
+++ b/draw.h
@@ -15,6 +15,7 @@ typedef struct {
15 int ascent; 15 int ascent;
16 int descent; 16 int descent;
17 int height; 17 int height;
18 int width;
18 XFontSet set; 19 XFontSet set;
19 XFontStruct *xfont; 20 XFontStruct *xfont;
20 } font; 21 } font;
diff --git a/lsx.c b/lsx.c
index e5b5c0b..f337a4a 100644
--- a/lsx.c
+++ b/lsx.c
@@ -1,8 +1,8 @@
1/* See LICENSE file for copyright and license details. */ 1/* See LICENSE file for copyright and license details. */
2#include <dirent.h> 2#include <dirent.h>
3#include <limits.h>
3#include <stdio.h> 4#include <stdio.h>
4#include <stdlib.h> 5#include <stdlib.h>
5#include <string.h>
6#include <unistd.h> 6#include <unistd.h>
7#include <sys/stat.h> 7#include <sys/stat.h>
8 8
@@ -31,7 +31,7 @@ lsx(const char *dir) {
31 return; 31 return;
32 } 32 }
33 while((d = readdir(dp))) 33 while((d = readdir(dp)))
34 if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < sizeof buf 34 if(snprintf(buf, sizeof buf, "%s/%s", dir, d->d_name) < (int)sizeof buf
35 && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0) 35 && !stat(buf, &st) && S_ISREG(st.st_mode) && access(buf, X_OK) == 0)
36 puts(d->d_name); 36 puts(d->d_name);
37 closedir(dp); 37 closedir(dp);