dmenu/center.diff (view raw)
1diff --git a/config.def.h b/config.def.h
2index 1edb647..7ee3247 100644
3--- a/config.def.h
4+++ b/config.def.h
5@@ -2,6 +2,7 @@
6 /* Default settings; can be overriden by command line. */
7
8 static int topbar = 1; /* -b option; if 0, dmenu appears at bottom */
9+static int centered = 0; /* -c option; centers dmenu on screen */
10 /* -fn option overrides fonts[0]; default X11 font or font set */
11 static const char *fonts[] = {
12 "monospace:size=10"
13diff --git a/dmenu.1 b/dmenu.1
14index 323f93c..c036baa 100644
15--- a/dmenu.1
16+++ b/dmenu.1
17@@ -40,6 +40,9 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
18 .B \-b
19 dmenu appears at the bottom of the screen.
20 .TP
21+.B \-c
22+dmenu appears centered on the screen.
23+.TP
24 .B \-f
25 dmenu grabs the keyboard before reading stdin if not reading from a tty. This
26 is faster, but will lock up X until stdin reaches end\-of\-file.
27diff --git a/dmenu.c b/dmenu.c
28index 65f25ce..bc7d087 100644
29--- a/dmenu.c
30+++ b/dmenu.c
31@@ -89,6 +89,15 @@ calcoffsets(void)
32 break;
33 }
34
35+static int
36+max_textw(void)
37+{
38+ int len = 0;
39+ for (struct item *item = items; item && item->text; item++)
40+ len = MAX(TEXTW(item->text), len);
41+ return len;
42+}
43+
44 static void
45 cleanup(void)
46 {
47@@ -611,6 +620,7 @@ setup(void)
48 bh = drw->fonts->h + 2;
49 lines = MAX(lines, 0);
50 mh = (lines + 1) * bh;
51+ promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
52 #ifdef XINERAMA
53 i = 0;
54 if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
55@@ -637,9 +647,16 @@ setup(void)
56 if (INTERSECT(x, y, 1, 1, info[i]))
57 break;
58
59- x = info[i].x_org;
60- y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
61- mw = info[i].width;
62+ if (centered) {
63+ mw = MIN(MAX(max_textw() + promptw, 100), info[i].width);
64+ x = info[i].x_org + ((info[i].width - mw) / 2);
65+ y = info[i].y_org + ((info[i].height - mh) / 2);
66+ } else {
67+ x = info[i].x_org;
68+ y = info[i].y_org + (topbar ? 0 : info[i].height - mh);
69+ mw = info[i].width;
70+ }
71+
72 XFree(info);
73 } else
74 #endif
75@@ -647,11 +664,17 @@ setup(void)
76 if (!XGetWindowAttributes(dpy, parentwin, &wa))
77 die("could not get embedding window attributes: 0x%lx",
78 parentwin);
79- x = 0;
80- y = topbar ? 0 : wa.height - mh;
81- mw = wa.width;
82+
83+ if (centered) {
84+ mw = MIN(MAX(max_textw() + promptw, 100), wa.width);
85+ x = (wa.width - mw) / 2;
86+ y = (wa.height - mh) / 2;
87+ } else {
88+ x = 0;
89+ y = topbar ? 0 : wa.height - mh;
90+ mw = wa.width;
91+ }
92 }
93- promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
94 inputw = MIN(inputw, mw/3);
95 match();
96
97@@ -709,6 +732,8 @@ main(int argc, char *argv[])
98 topbar = 0;
99 else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
100 fast = 1;
101+ else if (!strcmp(argv[i], "-c")) /* centers dmenu on screen */
102+ centered = 1;
103 else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
104 fstrncmp = strncasecmp;
105 fstrstr = cistrstr;