aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dmenu.117
-rw-r--r--dmenu.c35
-rw-r--r--draw.c22
3 files changed, 33 insertions, 41 deletions
diff --git a/dmenu.1 b/dmenu.1
index e5aa8cd..8295d17 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -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"
59dmenu lists items vertically, with the given number of lines. 57dmenu lists items vertically, with the given number of lines.
60.TP 58.TP
61.BI \-m " monitor"
62dmenu appears on the given Xinerama screen.
63.TP
64.BI \-p " prompt" 59.BI \-p " prompt"
65defines the prompt to be displayed to the left of the input field. 60defines 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.
86prints version information to stdout, then exits. 81prints version information to stdout, then exits.
87.SH USAGE 82.SH USAGE
88dmenu is completely controlled by the keyboard. Besides standard Unix line 83dmenu is completely controlled by the keyboard. Besides standard Unix line
89editing and item selection (Up/Down/Left/Right, PageUp/PageDown, Home/End), the 84editing and item selection (arrow keys, page up/down, home and end), the
90following keys are recognized: 85following keys are recognized:
91.TP 86.TP
92.B Tab (Control\-i) 87.B Tab (Ctrl\-i)
93Copy the selected item to the input field. 88Copy the selected item to the input field.
94.TP 89.TP
95.B Return (Control\-j) 90.B Return (Ctrl\-j)
96Confirm selection. Prints the selected item to stdout and exits, returning 91Confirm selection. Prints the selected item to stdout and exits, returning
97success. 92success.
98.TP 93.TP
99.B Shift\-Return (Control\-Shift\-j) 94.B Shift\-Return (Ctrl\-Shift\-j)
100Confirm input. Prints the input text to stdout and exits, returning success. 95Confirm 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)
103Exit without selecting an item, returning failure. 98Exit without selecting an item, returning failure.
104.TP 99.TP
105.B Control\-y 100.B Ctrl\-y
106Paste the current X selection into the input field. 101Paste the current X selection into the input field.
107.SH SEE ALSO 102.SH SEE ALSO
108.BR dwm (1) 103.BR dwm (1)
diff --git a/dmenu.c b/dmenu.c
index c4b7908..da62705 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -36,13 +36,12 @@ static void paste(void);
36static void readstdin(void); 36static void readstdin(void);
37static void run(void); 37static void run(void);
38static void setup(void); 38static void setup(void);
39static void usage(void);
39 40
40static char text[BUFSIZ] = ""; 41static char text[BUFSIZ] = "";
41static int bh, mw, mh; 42static int bh, mw, mh;
42static int inputw; 43static int inputw, promptw;
43static int lines = 0; 44static int lines = 0;
44static int monitor = -1;
45static int promptw;
46static size_t cursor = 0; 45static size_t cursor = 0;
47static const char *font = NULL; 46static const char *font = NULL;
48static const char *prompt = NULL; 47static 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
119usage: 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
125void 118void
@@ -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
549void
550usage(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}
diff --git a/draw.c b/draw.c
index 351a43d..f952b53 100644
--- a/draw.c
+++ b/draw.c
@@ -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
14static Bool loadfont(DC *dc, const char *fontstr); 14static Bool loadfont(DC *dc, const char *fontstr);
15 15
16void 16void
17drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { 17drawrect(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
29void 25void
@@ -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
114void 110void
115initfont(DC *dc, const char *fontstr) { 111initfont(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}