Introduction
Introduction Statistics Contact Development Disclaimer Help
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
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.