dmenu-nonblockingstdin-4.9.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dmenu-nonblockingstdin-4.9.diff (6538B) | |
--- | |
1 From 0c22fa69134c8b1547a5518b5a22d0c49ef56ed1 Mon Sep 17 00:00:00 2001 | |
2 From: Miles Alan <[email protected]> | |
3 Date: Mon, 12 Aug 2019 16:35:36 -0500 | |
4 Subject: [PATCH] Nonblocking stdin patch; port to 4.9 | |
5 | |
6 --- | |
7 dmenu.1 | 6 +-- | |
8 dmenu.c | 122 ++++++++++++++++++++++++++++++++++---------------------- | |
9 2 files changed, 76 insertions(+), 52 deletions(-) | |
10 | |
11 diff --git a/dmenu.1 b/dmenu.1 | |
12 index 323f93c..a07532d 100644 | |
13 --- a/dmenu.1 | |
14 +++ b/dmenu.1 | |
15 @@ -3,7 +3,7 @@ | |
16 dmenu \- dynamic menu | |
17 .SH SYNOPSIS | |
18 .B dmenu | |
19 -.RB [ \-bfiv ] | |
20 +.RB [ \-biv ] | |
21 .RB [ \-l | |
22 .IR lines ] | |
23 .RB [ \-m | |
24 @@ -40,10 +40,6 @@ which lists programs in the user's $PATH and runs the… | |
25 .B \-b | |
26 dmenu appears at the bottom of the screen. | |
27 .TP | |
28 -.B \-f | |
29 -dmenu grabs the keyboard before reading stdin if not reading from a tty… | |
30 -is faster, but will lock up X until stdin reaches end\-of\-file. | |
31 -.TP | |
32 .B \-i | |
33 dmenu matches menu items case insensitively. | |
34 .TP | |
35 diff --git a/dmenu.c b/dmenu.c | |
36 index 6b8f51b..479a4c8 100644 | |
37 --- a/dmenu.c | |
38 +++ b/dmenu.c | |
39 @@ -1,5 +1,6 @@ | |
40 /* See LICENSE file for copyright and license details. */ | |
41 #include <ctype.h> | |
42 +#include <fcntl.h> | |
43 #include <locale.h> | |
44 #include <stdio.h> | |
45 #include <stdlib.h> | |
46 @@ -8,6 +9,7 @@ | |
47 #include <time.h> | |
48 #include <unistd.h> | |
49 | |
50 +#include <sys/select.h> | |
51 #include <X11/Xlib.h> | |
52 #include <X11/Xatom.h> | |
53 #include <X11/Xutil.h> | |
54 @@ -31,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast };… | |
55 struct item { | |
56 char *text; | |
57 struct item *left, *right; | |
58 + struct item *next; | |
59 int out; | |
60 }; | |
61 | |
62 @@ -173,6 +176,7 @@ drawmenu(void) | |
63 } | |
64 } | |
65 drw_map(drw, win, 0, 0, mw, mh); | |
66 + XFlush(dpy); | |
67 } | |
68 | |
69 static void | |
70 @@ -220,6 +224,7 @@ match(void) | |
71 int i, tokc = 0; | |
72 size_t len, textsize; | |
73 struct item *item, *lprefix, *lsubstr, *prefixend, *substrend; | |
74 + int preserve = 0; | |
75 | |
76 strcpy(buf, text); | |
77 /* separate input text into tokens to be matched individually */ | |
78 @@ -230,19 +235,23 @@ match(void) | |
79 | |
80 matches = lprefix = lsubstr = matchend = prefixend = substrend … | |
81 textsize = strlen(text) + 1; | |
82 - for (item = items; item && item->text; item++) { | |
83 + for (item = items; item; item = item->next) { | |
84 for (i = 0; i < tokc; i++) | |
85 if (!fstrstr(item->text, tokv[i])) | |
86 break; | |
87 if (i != tokc) /* not all tokens match */ | |
88 continue; | |
89 /* exact matches go first, then prefixes, then substrin… | |
90 - if (!tokc || !fstrncmp(text, item->text, textsize)) | |
91 + if (!tokc || !fstrncmp(text, item->text, textsize)) { | |
92 appenditem(item, &matches, &matchend); | |
93 - else if (!fstrncmp(tokv[0], item->text, len)) | |
94 + if (sel == item) preserve = 1; | |
95 + } else if (!fstrncmp(tokv[0], item->text, len)) { | |
96 appenditem(item, &lprefix, &prefixend); | |
97 - else | |
98 + if (sel == item) preserve = 1; | |
99 + } else { | |
100 appenditem(item, &lsubstr, &substrend); | |
101 + if (sel == item) preserve = 1; | |
102 + } | |
103 } | |
104 if (lprefix) { | |
105 if (matches) { | |
106 @@ -260,7 +269,9 @@ match(void) | |
107 matches = lsubstr; | |
108 matchend = substrend; | |
109 } | |
110 - curr = sel = matches; | |
111 + if (!preserve) | |
112 + curr = sel = matches; | |
113 + | |
114 calcoffsets(); | |
115 } | |
116 | |
117 @@ -519,40 +530,11 @@ paste(void) | |
118 } | |
119 | |
120 static void | |
121 -readstdin(void) | |
122 -{ | |
123 - char buf[sizeof text], *p; | |
124 - size_t i, imax = 0, size = 0; | |
125 - unsigned int tmpmax = 0; | |
126 - | |
127 - /* read each line from stdin and add it to the item list */ | |
128 - for (i = 0; fgets(buf, sizeof buf, stdin); i++) { | |
129 - if (i + 1 >= size / sizeof *items) | |
130 - if (!(items = realloc(items, (size += BUFSIZ)))) | |
131 - die("cannot realloc %u bytes:", size); | |
132 - if ((p = strchr(buf, '\n'))) | |
133 - *p = '\0'; | |
134 - if (!(items[i].text = strdup(buf))) | |
135 - die("cannot strdup %u bytes:", strlen(buf) + 1); | |
136 - items[i].out = 0; | |
137 - drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax,… | |
138 - if (tmpmax > inputw) { | |
139 - inputw = tmpmax; | |
140 - imax = i; | |
141 - } | |
142 - } | |
143 - if (items) | |
144 - items[i].text = NULL; | |
145 - inputw = items ? TEXTW(items[imax].text) : 0; | |
146 - lines = MIN(lines, i); | |
147 -} | |
148 - | |
149 -static void | |
150 -run(void) | |
151 +readevent(void) | |
152 { | |
153 XEvent ev; | |
154 | |
155 - while (!XNextEvent(dpy, &ev)) { | |
156 + while (XPending(dpy) && !XNextEvent(dpy, &ev)) { | |
157 if (XFilterEvent(&ev, None)) | |
158 continue; | |
159 switch(ev.type) { | |
160 @@ -580,6 +562,60 @@ run(void) | |
161 } | |
162 } | |
163 | |
164 +static void | |
165 +readstdin(void) | |
166 +{ | |
167 + static size_t max = 0; | |
168 + static struct item **end = &items; | |
169 + | |
170 + char buf[sizeof text], *p, *maxstr; | |
171 + struct item *item; | |
172 + | |
173 + /* read each line from stdin and add it to the item list */ | |
174 + while (fgets(buf, sizeof buf, stdin)) { | |
175 + if (!(item = malloc(sizeof *item))) | |
176 + die("cannot malloc %u bytes:", sizeof *item); | |
177 + if ((p = strchr(buf, '\n'))) | |
178 + *p = '\0'; | |
179 + if (!(item->text = strdup(buf))) | |
180 + die("cannot strdup %u bytes:", strlen(buf)+1); | |
181 + if (strlen(item->text) > max) { | |
182 + max = strlen(maxstr = item->text); | |
183 + inputw = maxstr ? TEXTW(maxstr) : 0; | |
184 + } | |
185 + *end = item; | |
186 + end = &item->next; | |
187 + item->next = NULL; | |
188 + item->out = 0; | |
189 + } | |
190 + match(); | |
191 + drawmenu(); | |
192 +} | |
193 + | |
194 +static void | |
195 +run(void) | |
196 +{ | |
197 + fd_set fds; | |
198 + int flags, xfd = XConnectionNumber(dpy); | |
199 + | |
200 + if ((flags = fcntl(0, F_GETFL)) == -1) | |
201 + die("cannot get stdin control flags:"); | |
202 + if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1) | |
203 + die("cannot set stdin control flags:"); | |
204 + for (;;) { | |
205 + FD_ZERO(&fds); | |
206 + FD_SET(xfd, &fds); | |
207 + if (!feof(stdin)) | |
208 + FD_SET(0, &fds); | |
209 + if (select(xfd + 1, &fds, NULL, NULL, NULL) == -1) | |
210 + die("cannot multiplex input:"); | |
211 + if (FD_ISSET(xfd, &fds)) | |
212 + readevent(); | |
213 + if (FD_ISSET(0, &fds)) | |
214 + readstdin(); | |
215 + } | |
216 +} | |
217 + | |
218 static void | |
219 setup(void) | |
220 { | |
221 @@ -682,7 +718,7 @@ setup(void) | |
222 static void | |
223 usage(void) | |
224 { | |
225 - fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [… | |
226 + fputs("usage: dmenu [-biv] [-l lines] [-p prompt] [-fn font] [-… | |
227 " [-nb color] [-nf color] [-sb color] [-sf co… | |
228 exit(1); | |
229 } | |
230 @@ -691,7 +727,7 @@ int | |
231 main(int argc, char *argv[]) | |
232 { | |
233 XWindowAttributes wa; | |
234 - int i, fast = 0; | |
235 + int i; | |
236 | |
237 for (i = 1; i < argc; i++) | |
238 /* these options take no arguments */ | |
239 @@ -700,8 +736,6 @@ main(int argc, char *argv[]) | |
240 exit(0); | |
241 } else if (!strcmp(argv[i], "-b")) /* appears at the bo… | |
242 topbar = 0; | |
243 - else if (!strcmp(argv[i], "-f")) /* grabs keyboard be… | |
244 - fast = 1; | |
245 else if (!strcmp(argv[i], "-i")) { /* case-insensitive … | |
246 fstrncmp = strncasecmp; | |
247 fstrstr = cistrstr; | |
248 @@ -752,13 +786,7 @@ main(int argc, char *argv[]) | |
249 die("pledge"); | |
250 #endif | |
251 | |
252 - if (fast && !isatty(0)) { | |
253 - grabkeyboard(); | |
254 - readstdin(); | |
255 - } else { | |
256 - readstdin(); | |
257 - grabkeyboard(); | |
258 - } | |
259 + grabkeyboard(); | |
260 setup(); | |
261 run(); | |
262 | |
263 -- | |
264 2.19.2 | |
265 |