diff options
-rw-r--r-- | dmenu.1 | 17 | ||||
-rw-r--r-- | dmenu.c | 35 | ||||
-rw-r--r-- | draw.c | 22 |
3 files changed, 33 insertions, 41 deletions
@@ -8,8 +8,6 @@ dmenu \- dynamic menu | |||
8 | .RB [ \-i ] | 8 | .RB [ \-i ] |
9 | .RB [ \-l | 9 | .RB [ \-l |
10 | .IR lines ] | 10 | .IR lines ] |
11 | .RB [ \-m | ||
12 | .IR monitor ] | ||
13 | .RB [ \-p | 11 | .RB [ \-p |
14 | .IR prompt ] | 12 | .IR prompt ] |
15 | .RB [ \-fn | 13 | .RB [ \-fn |
@@ -58,9 +56,6 @@ dmenu matches menu items case insensitively. | |||
58 | .BI \-l " lines" | 56 | .BI \-l " lines" |
59 | dmenu lists items vertically, with the given number of lines. | 57 | dmenu lists items vertically, with the given number of lines. |
60 | .TP | 58 | .TP |
61 | .BI \-m " monitor" | ||
62 | dmenu appears on the given Xinerama screen. | ||
63 | .TP | ||
64 | .BI \-p " prompt" | 59 | .BI \-p " prompt" |
65 | defines the prompt to be displayed to the left of the input field. | 60 | defines the prompt to be displayed to the left of the input field. |
66 | .TP | 61 | .TP |
@@ -86,23 +81,23 @@ defines the selected foreground color. | |||
86 | prints version information to stdout, then exits. | 81 | prints version information to stdout, then exits. |
87 | .SH USAGE | 82 | .SH USAGE |
88 | dmenu is completely controlled by the keyboard. Besides standard Unix line | 83 | dmenu is completely controlled by the keyboard. Besides standard Unix line |
89 | editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the | 84 | editing and item selection (arrow keys, page up/down, home and end), the |
90 | following keys are recognized: | 85 | following keys are recognized: |
91 | .TP | 86 | .TP |
92 | .B Tab (Control\-i) | 87 | .B Tab (Ctrl\-i) |
93 | Copy the selected item to the input field. | 88 | Copy the selected item to the input field. |
94 | .TP | 89 | .TP |
95 | .B Return (Control\-j) | 90 | .B Return (Ctrl\-j) |
96 | Confirm selection. Prints the selected item to stdout and exits, returning | 91 | Confirm selection. Prints the selected item to stdout and exits, returning |
97 | success. | 92 | success. |
98 | .TP | 93 | .TP |
99 | .B Shift\-Return (Control\-Shift\-j) | 94 | .B Shift\-Return (Ctrl\-Shift\-j) |
100 | Confirm input. Prints the input text to stdout and exits, returning success. | 95 | Confirm input. Prints the input text to stdout and exits, returning success. |
101 | .TP | 96 | .TP |
102 | .B Escape (Control\-c) | 97 | .B Escape (Ctrl\-c) |
103 | Exit without selecting an item, returning failure. | 98 | Exit without selecting an item, returning failure. |
104 | .TP | 99 | .TP |
105 | .B Control\-y | 100 | .B Ctrl\-y |
106 | Paste the current X selection into the input field. | 101 | Paste the current X selection into the input field. |
107 | .SH SEE ALSO | 102 | .SH SEE ALSO |
108 | .BR dwm (1) | 103 | .BR dwm (1) |
@@ -36,13 +36,12 @@ static void paste(void); | |||
36 | static void readstdin(void); | 36 | static void readstdin(void); |
37 | static void run(void); | 37 | static void run(void); |
38 | static void setup(void); | 38 | static void setup(void); |
39 | static void usage(void); | ||
39 | 40 | ||
40 | static char text[BUFSIZ] = ""; | 41 | static char text[BUFSIZ] = ""; |
41 | static int bh, mw, mh; | 42 | static int bh, mw, mh; |
42 | static int inputw; | 43 | static int inputw, promptw; |
43 | static int lines = 0; | 44 | static int lines = 0; |
44 | static int monitor = -1; | ||
45 | static int promptw; | ||
46 | static size_t cursor = 0; | 45 | static size_t cursor = 0; |
47 | static const char *font = NULL; | 46 | static const char *font = NULL; |
48 | static const char *prompt = NULL; | 47 | static const char *prompt = NULL; |
@@ -70,7 +69,7 @@ main(int argc, char *argv[]) { | |||
70 | for(i = 1; i < argc; i++) | 69 | for(i = 1; i < argc; i++) |
71 | /* single flags */ | 70 | /* single flags */ |
72 | if(!strcmp(argv[i], "-v")) { | 71 | if(!strcmp(argv[i], "-v")) { |
73 | fputs("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details\n", stdout); | 72 | puts("dmenu-"VERSION", © 2006-2011 dmenu engineers, see LICENSE for details"); |
74 | exit(EXIT_SUCCESS); | 73 | exit(EXIT_SUCCESS); |
75 | } | 74 | } |
76 | else if(!strcmp(argv[i], "-b")) | 75 | else if(!strcmp(argv[i], "-b")) |
@@ -80,12 +79,10 @@ main(int argc, char *argv[]) { | |||
80 | else if(!strcmp(argv[i], "-i")) | 79 | else if(!strcmp(argv[i], "-i")) |
81 | fstrncmp = strncasecmp; | 80 | fstrncmp = strncasecmp; |
82 | else if(i+1 == argc) | 81 | else if(i+1 == argc) |
83 | goto usage; | 82 | usage(); |
84 | /* double flags */ | 83 | /* double flags */ |
85 | else if(!strcmp(argv[i], "-l")) | 84 | else if(!strcmp(argv[i], "-l")) |
86 | lines = atoi(argv[++i]); | 85 | lines = atoi(argv[++i]); |
87 | else if(!strcmp(argv[i], "-m")) | ||
88 | monitor = atoi(argv[++i]); | ||
89 | else if(!strcmp(argv[i], "-p")) | 86 | else if(!strcmp(argv[i], "-p")) |
90 | prompt = argv[++i]; | 87 | prompt = argv[++i]; |
91 | else if(!strcmp(argv[i], "-fn")) | 88 | else if(!strcmp(argv[i], "-fn")) |
@@ -99,7 +96,7 @@ main(int argc, char *argv[]) { | |||
99 | else if(!strcmp(argv[i], "-sf")) | 96 | else if(!strcmp(argv[i], "-sf")) |
100 | selfgcolor = argv[++i]; | 97 | selfgcolor = argv[++i]; |
101 | else | 98 | else |
102 | goto usage; | 99 | usage(); |
103 | 100 | ||
104 | dc = initdc(); | 101 | dc = initdc(); |
105 | initfont(dc, font); | 102 | initfont(dc, font); |
@@ -114,12 +111,8 @@ main(int argc, char *argv[]) { | |||
114 | } | 111 | } |
115 | setup(); | 112 | setup(); |
116 | run(); | 113 | run(); |
117 | return EXIT_FAILURE; | ||
118 | 114 | ||
119 | usage: | 115 | return EXIT_FAILURE; /* should not reach */ |
120 | fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-m monitor] [-p prompt] [-fn font]\n" | ||
121 | " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); | ||
122 | return EXIT_FAILURE; | ||
123 | } | 116 | } |
124 | 117 | ||
125 | void | 118 | void |
@@ -452,7 +445,7 @@ readstdin(void) { | |||
452 | char buf[sizeof text], *p, *maxstr = NULL; | 445 | char buf[sizeof text], *p, *maxstr = NULL; |
453 | size_t i, max = 0, size = 0; | 446 | size_t i, max = 0, size = 0; |
454 | 447 | ||
455 | for(i = 0; fgets(buf, sizeof buf, stdin); items[++i].text = NULL) { | 448 | for(i = 0; fgets(buf, sizeof buf, stdin); i++) { |
456 | if(i+1 >= size / sizeof *items) | 449 | if(i+1 >= size / sizeof *items) |
457 | if(!(items = realloc(items, (size += BUFSIZ)))) | 450 | if(!(items = realloc(items, (size += BUFSIZ)))) |
458 | eprintf("cannot realloc %u bytes:", size); | 451 | eprintf("cannot realloc %u bytes:", size); |
@@ -463,6 +456,8 @@ readstdin(void) { | |||
463 | if(strlen(items[i].text) > max) | 456 | if(strlen(items[i].text) > max) |
464 | max = strlen(maxstr = items[i].text); | 457 | max = strlen(maxstr = items[i].text); |
465 | } | 458 | } |
459 | if(items) | ||
460 | items[i].text = NULL; | ||
466 | inputw = maxstr ? textw(dc, maxstr) : 0; | 461 | inputw = maxstr ? textw(dc, maxstr) : 0; |
467 | } | 462 | } |
468 | 463 | ||
@@ -519,8 +514,7 @@ setup(void) { | |||
519 | 514 | ||
520 | XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); | 515 | XQueryPointer(dc->dpy, root, &dw, &dw, &x, &y, &di, &di, &du); |
521 | for(i = 0; i < n-1; i++) | 516 | for(i = 0; i < n-1; i++) |
522 | if((monitor == info[i].screen_number) | 517 | if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height)) |
523 | || (monitor < 0 && INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))) | ||
524 | break; | 518 | break; |
525 | x = info[i].x_org; | 519 | x = info[i].x_org; |
526 | y = info[i].y_org + (topbar ? 0 : info[i].height - mh); | 520 | y = info[i].y_org + (topbar ? 0 : info[i].height - mh); |
@@ -534,8 +528,8 @@ setup(void) { | |||
534 | y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; | 528 | y = topbar ? 0 : DisplayHeight(dc->dpy, screen) - mh; |
535 | mw = DisplayWidth(dc->dpy, screen); | 529 | mw = DisplayWidth(dc->dpy, screen); |
536 | } | 530 | } |
537 | inputw = MIN(inputw, mw/3); | ||
538 | promptw = prompt ? textw(dc, prompt) : 0; | 531 | promptw = prompt ? textw(dc, prompt) : 0; |
532 | inputw = MIN(inputw, mw/3); | ||
539 | match(False); | 533 | match(False); |
540 | 534 | ||
541 | /* menu window */ | 535 | /* menu window */ |
@@ -551,3 +545,10 @@ setup(void) { | |||
551 | resizedc(dc, mw, mh); | 545 | resizedc(dc, mw, mh); |
552 | drawmenu(); | 546 | drawmenu(); |
553 | } | 547 | } |
548 | |||
549 | void | ||
550 | usage(void) { | ||
551 | fputs("usage: dmenu [-b] [-f] [-i] [-l lines] [-p prompt] [-fn font]\n" | ||
552 | " [-nb color] [-nf color] [-sb color] [-sf color] [-v]\n", stderr); | ||
553 | exit(EXIT_FAILURE); | ||
554 | } | ||
@@ -9,21 +9,17 @@ | |||
9 | 9 | ||
10 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 10 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
11 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) | 11 | #define MIN(a, b) ((a) < (b) ? (a) : (b)) |
12 | #define DEFFONT "fixed" | 12 | #define DEFAULTFN "fixed" |
13 | 13 | ||
14 | static Bool loadfont(DC *dc, const char *fontstr); | 14 | static Bool loadfont(DC *dc, const char *fontstr); |
15 | 15 | ||
16 | void | 16 | void |
17 | drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { | 17 | drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { |
18 | XRectangle r; | ||
19 | |||
20 | r.x = dc->x + x; | ||
21 | r.y = dc->y + y; | ||
22 | r.width = fill ? w : w-1; | ||
23 | r.height = fill ? h : h-1; | ||
24 | |||
25 | XSetForeground(dc->dpy, dc->gc, color); | 18 | XSetForeground(dc->dpy, dc->gc, color); |
26 | (fill ? XFillRectangles : XDrawRectangles)(dc->dpy, dc->canvas, dc->gc, &r, 1); | 19 | if(fill) |
20 | XFillRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w, h); | ||
21 | else | ||
22 | XDrawRectangle(dc->dpy, dc->canvas, dc->gc, dc->x + x, dc->y + y, w-1, h-1); | ||
27 | } | 23 | } |
28 | 24 | ||
29 | void | 25 | void |
@@ -65,7 +61,7 @@ eprintf(const char *fmt, ...) { | |||
65 | vfprintf(stderr, fmt, ap); | 61 | vfprintf(stderr, fmt, ap); |
66 | va_end(ap); | 62 | va_end(ap); |
67 | 63 | ||
68 | if(fmt[strlen(fmt)-1] == ':') { | 64 | if(fmt[0] != '\0' && fmt[strlen(fmt)-1] == ':') { |
69 | fputc(' ', stderr); | 65 | fputc(' ', stderr); |
70 | perror(NULL); | 66 | perror(NULL); |
71 | } | 67 | } |
@@ -113,11 +109,11 @@ initdc(void) { | |||
113 | 109 | ||
114 | void | 110 | void |
115 | initfont(DC *dc, const char *fontstr) { | 111 | initfont(DC *dc, const char *fontstr) { |
116 | if(!loadfont(dc, fontstr ? fontstr : DEFFONT)) { | 112 | if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { |
117 | if(fontstr != NULL) | 113 | if(fontstr != NULL) |
118 | fprintf(stderr, "cannot load font '%s'\n", fontstr); | 114 | fprintf(stderr, "cannot load font '%s'\n", fontstr); |
119 | if(fontstr == NULL || !loadfont(dc, DEFFONT)) | 115 | if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) |
120 | eprintf("cannot load font '%s'\n", DEFFONT); | 116 | eprintf("cannot load font '%s'\n", DEFAULTFN); |
121 | } | 117 | } |
122 | dc->font.height = dc->font.ascent + dc->font.descent; | 118 | dc->font.height = dc->font.ascent + dc->font.descent; |
123 | } | 119 | } |