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