summarylogtreecommitdiffstats
path: root/patchfile
blob: 307aa95d6d2c1e254f4be63c76506302c9f0f84d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
diff --git a/dmenu.1 b/dmenu.1
index 323f93c..6b83752 100644
--- a/dmenu.1
+++ b/dmenu.1
@@ -22,6 +22,16 @@ dmenu \- dynamic menu
 .IR color ]
 .RB [ \-w
 .IR windowid ]
+.RB [ \-X
+.IR position ]
+.RB [ \-Y
+.IR position ]
+.RB [ \-W
+.IR width ]
+.RB [ \-H
+.IR height ]
+.RB [ \-F
+.IR filter ]
 .P
 .BR dmenu_run " ..."
 .SH DESCRIPTION
@@ -80,11 +90,26 @@ prints version information to stdout, then exits.
 .TP
 .BI \-w " windowid"
 embed into windowid.
+.TP
+.BI \-X " position"
+override automatic x position of the menu.
+.TP
+.BI \-Y " position"
+override automatic y position of the menu.
+.TP
+.BI \-W " position"
+override automatic width of the menu.
+.TP
+.BI \-H " position"
+override automatic height of the menu.
+.TP
+.BI \-F " filter"
+filter will be pre entered as text.
 .SH USAGE
 dmenu is completely controlled by the keyboard.  Items are selected using the
-arrow keys, page up, page down, home, and end.
+arrow keys, tab, shift+tab, page up, page down, home, and end.
 .TP
-.B Tab
+.B Ctrl-Tab
 Copy the selected item to the input field.
 .TP
 .B Return
diff --git a/dmenu.c b/dmenu.c
index 62f1089..f427aea 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -27,6 +27,7 @@
 
 /* enums */
 enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
+enum { NotSet = -8210 };
 
 struct item {
 	char *text;
@@ -53,6 +54,12 @@ static XIC xic;
 static Drw *drw;
 static Clr *scheme[SchemeLast];
 
+/* geometry can be overridden with -X,-Y,-W,-H */
+static int bl_x = NotSet;
+static int bl_y = NotSet;
+static int bl_h = NotSet;
+static int bl_w = NotSet;
+
 #include "config.h"
 
 static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
@@ -171,7 +178,7 @@ drawmenu(void)
 	if (lines > 0) {
 		/* draw vertical list */
 		for (item = curr; item != next; item = item->right)
-			drawitem(item, x, y += bh, mw - x);
+			drawitem(item, 0, y += bh, mw);
 	} else if (matches) {
 		/* draw horizontal list */
 		x += inputw;
@@ -358,6 +365,15 @@ keypress(XKeyEvent *ev)
 		case XK_n: ksym = XK_Down;      break;
 		case XK_p: ksym = XK_Up;        break;
 
+		case XK_Tab: /* default dmenu tab behaviour (autocomplete) on ctrl+tab */
+			if (!sel)
+				return;
+			cursor = strnlen(sel->text, sizeof text - 1);
+			memcpy(text, sel->text, cursor);
+			text[cursor] = '\0';
+			match();
+			break;
+
 		case XK_k: /* delete right */
 			text[cursor] = '\0';
 			match();
@@ -469,6 +485,7 @@ insert:
 		/* fallthrough */
 	case XK_Up:
 	case XK_KP_Up:
+	case XK_ISO_Left_Tab:
 		if (sel && sel->left && (sel = sel->left)->right == curr) {
 			curr = prev;
 			calcoffsets();
@@ -509,19 +526,12 @@ insert:
 		/* fallthrough */
 	case XK_Down:
 	case XK_KP_Down:
+	case XK_Tab:
 		if (sel && sel->right && (sel = sel->right) == next) {
 			curr = next;
 			calcoffsets();
 		}
 		break;
-	case XK_Tab:
-		if (!sel)
-			return;
-		cursor = strnlen(sel->text, sizeof text - 1);
-		memcpy(text, sel->text, cursor);
-		text[cursor] = '\0';
-		match();
-		break;
 	}
 
 draw:
@@ -636,7 +646,13 @@ setup(void)
 	/* calculate menu geometry */
 	bh = drw->fonts->h + 2;
 	lines = MAX(lines, 0);
-	mh = (lines + 1) * bh;
+	
+	if (bl_h != NotSet) {
+		lines = MIN(bl_h/(bh+1), lines);
+		mh = bl_h;
+	} else
+		mh = (lines + 1) * bh;
+
 #ifdef XINERAMA
 	i = 0;
 	if (parentwin == root && (info = XineramaQueryScreens(dpy, &n))) {
@@ -677,6 +693,14 @@ setup(void)
 		y = topbar ? 0 : wa.height - mh;
 		mw = wa.width;
 	}
+
+	if (bl_x != NotSet)
+		x = bl_x;
+	if (bl_y != NotSet)
+		y = bl_y;
+	if (bl_w != NotSet)
+		mw = bl_w;
+
 	promptw = (prompt && *prompt) ? TEXTW(prompt) - lrpad / 4 : 0;
 	inputw = mw / 3; /* input width: ~33% of monitor width */
 	match();
@@ -717,7 +741,8 @@ static void
 usage(void)
 {
 	die("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n"
-	    "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]");
+		  "             [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n"
+		  "             [-X position] [-Y position] [-H height] [-W width] [-F filter]");
 }
 
 int
@@ -759,6 +784,19 @@ main(int argc, char *argv[])
 			colors[SchemeSel][ColFg] = argv[++i];
 		else if (!strcmp(argv[i], "-w"))   /* embedding window id */
 			embed = argv[++i];
+		else if (!strcmp(argv[i], "-X"))   /* forced X position */
+			bl_x = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-Y"))   /* forced Y postion */
+			bl_y = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-W"))   /* forced width */
+			bl_w = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-H"))   /* forced height */
+			bl_h = atoi(argv[++i]);
+		else if (!strcmp(argv[i], "-F")) { /* filter */
+		  strncpy(text, argv[++i], sizeof text - 1);
+		  text[sizeof text - 1] = '\0';
+		  cursor = strlen(text);
+		}
 		else
 			usage();