[wiki] [sites] [patch][dmenu] Add port for nonblockingstdin to 4.9 || Miles Alan
commit fb3d82553025bddf916c0ed6b06d79895dc330ad
Author: Miles Alan <m_AT_milesalan.com>
Date: Mon Aug 12 16:49:31 2019 -0500
[patch][dmenu] Add port for nonblockingstdin to 4.9
diff --git a/tools.suckless.org/dmenu/patches/non_blocking_stdin/dmenu-nonblockingstdin-4.9.diff b/tools.suckless.org/dmenu/patches/non_blocking_stdin/dmenu-nonblockingstdin-4.9.diff
new file mode 100644
index 00000000..48bc37ec
--- /dev/null
+++ b/tools.suckless.org/dmenu/patches/non_blocking_stdin/dmenu-nonblockingstdin-4.9.diff
_AT_@ -0,0 +1,265 @@
+From 0c22fa69134c8b1547a5518b5a22d0c49ef56ed1 Mon Sep 17 00:00:00 2001
+From: Miles Alan <m_AT_milesalan.com>
+Date: Mon, 12 Aug 2019 16:35:36 -0500
+Subject: [PATCH] Nonblocking stdin patch; port to 4.9
+
+---
+ dmenu.1 | 6 +--
+ dmenu.c | 122 ++++++++++++++++++++++++++++++++++----------------------
+ 2 files changed, 76 insertions(+), 52 deletions(-)
+
+diff --git a/dmenu.1 b/dmenu.1
+index 323f93c..a07532d 100644
+--- a/dmenu.1
++++ b/dmenu.1
+_AT_@ -3,7 +3,7 @@
+ dmenu \- dynamic menu
+ .SH SYNOPSIS
+ .B dmenu
+-.RB [ \-bfiv ]
++.RB [ \-biv ]
+ .RB [ \-l
+ .IR lines ]
+ .RB [ \-m
+_AT_@ -40,10 +40,6 @@ which lists programs in the user's $PATH and runs the result in their $SHELL.
+ .B \-b
+ dmenu appears at the bottom of the screen.
+ .TP
+-.B \-f
+-dmenu grabs the keyboard before reading stdin if not reading from a tty. This
+-is faster, but will lock up X until stdin reaches end\-of\-file.
+-.TP
+ .B \-i
+ dmenu matches menu items case insensitively.
+ .TP
+diff --git a/dmenu.c b/dmenu.c
+index 6b8f51b..479a4c8 100644
+--- a/dmenu.c
++++ b/dmenu.c
+_AT_@ -1,5 +1,6 @@
+ /* See LICENSE file for copyright and license details. */
+ #include <ctype.h>
++#include <fcntl.h>
+ #include <locale.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+_AT_@ -8,6 +9,7 @@
+ #include <time.h>
+ #include <unistd.h>
+
++#include <sys/select.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xatom.h>
+ #include <X11/Xutil.h>
+_AT_@ -31,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
+ struct item {
+ char *text;
+ struct item *left, *right;
++ struct item *next;
+ int out;
+ };
+
+_AT_@ -173,6 +176,7 @@ drawmenu(void)
+ }
+ }
+ drw_map(drw, win, 0, 0, mw, mh);
++ XFlush(dpy);
+ }
+
+ static void
+_AT_@ -220,6 +224,7 @@ match(void)
+ int i, tokc = 0;
+ size_t len, textsize;
+ struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
++ int preserve = 0;
+
+ strcpy(buf, text);
+ /* separate input text into tokens to be matched individually */
+_AT_@ -230,19 +235,23 @@ match(void)
+
+ matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
+ textsize = strlen(text) + 1;
+- for (item = items; item && item->text; item++) {
++ for (item = items; item; item = item->next) {
+ for (i = 0; i < tokc; i++)
+ if (!fstrstr(item->text, tokv[i]))
+ break;
+ if (i != tokc) /* not all tokens match */
+ continue;
+ /* exact matches go first, then prefixes, then substrings */
+- if (!tokc || !fstrncmp(text, item->text, textsize))
++ if (!tokc || !fstrncmp(text, item->text, textsize)) {
+ appenditem(item, &matches, &matchend);
+- else if (!fstrncmp(tokv[0], item->text, len))
++ if (sel == item) preserve = 1;
++ } else if (!fstrncmp(tokv[0], item->text, len)) {
+ appenditem(item, &lprefix, &prefixend);
+- else
++ if (sel == item) preserve = 1;
++ } else {
+ appenditem(item, &lsubstr, &substrend);
++ if (sel == item) preserve = 1;
++ }
+ }
+ if (lprefix) {
+ if (matches) {
+_AT_@ -260,7 +269,9 @@ match(void)
+ matches = lsubstr;
+ matchend = substrend;
+ }
+- curr = sel = matches;
++ if (!preserve)
++ curr = sel = matches;
++
+ calcoffsets();
+ }
+
+_AT_@ -519,40 +530,11 @@ paste(void)
+ }
+
+ static void
+-readstdin(void)
+-{
+- char buf[sizeof text], *p;
+- size_t i, imax = 0, size = 0;
+- unsigned int tmpmax = 0;
+-
+- /* read each line from stdin and add it to the item list */
+- for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
+- if (i + 1 >= size / sizeof *items)
+- if (!(items = realloc(items, (size += BUFSIZ))))
+- die("cannot realloc %u bytes:", size);
+- if ((p = strchr(buf, '
')))
+- *p = '+- if (!(items[i].text = strdup(buf)))
+- die("cannot strdup %u bytes:", strlen(buf) + 1);
+- items[i].out = 0;
+- drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
+- if (tmpmax > inputw) {
+- inputw = tmpmax;
+- imax = i;
+- }
+- }
+- if (items)
+- items[i].text = NULL;
+- inputw = items ? TEXTW(items[imax].text) : 0;
+- lines = MIN(lines, i);
+-}
+-
+-static void
+-run(void)
++readevent(void)
+ {
+ XEvent ev;
+
+- while (!XNextEvent(dpy, &ev)) {
++ while (XPending(dpy) && !XNextEvent(dpy, &ev)) {
+ if (XFilterEvent(&ev, None))
+ continue;
+ switch(ev.type) {
+_AT_@ -580,6 +562,60 @@ run(void)
+ }
+ }
+
++static void
++readstdin(void)
++{
++ static size_t max = 0;
++ static struct item **end = &items;
++
++ char buf[sizeof text], *p, *maxstr;
++ struct item *item;
++
++ /* read each line from stdin and add it to the item list */
++ while (fgets(buf, sizeof buf, stdin)) {
++ if (!(item = malloc(sizeof *item)))
++ die("cannot malloc %u bytes:", sizeof *item);
++ if ((p = strchr(buf, '
')))
++ *p = '++ if (!(item->text = strdup(buf)))
++ die("cannot strdup %u bytes:", strlen(buf)+1);
++ if (strlen(item->text) > max) {
++ max = strlen(maxstr = item->text);
++ inputw = maxstr ? TEXTW(maxstr) : 0;
++ }
++ *end = item;
++ end = &item->next;
++ item->next = NULL;
++ item->out = 0;
++ }
++ match();
++ drawmenu();
++}
++
++static void
++run(void)
++{
++ fd_set fds;
++ int flags, xfd = XConnectionNumber(dpy);
++
++ if ((flags = fcntl(0, F_GETFL)) == -1)
++ die("cannot get stdin control flags:");
++ if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1)
++ die("cannot set stdin control flags:");
++ for (;;) {
++ FD_ZERO(&fds);
++ FD_SET(xfd, &fds);
++ if (!feof(stdin))
++ FD_SET(0, &fds);
++ if (select(xfd + 1, &fds, NULL, NULL, NULL) == -1)
++ die("cannot multiplex input:");
++ if (FD_ISSET(xfd, &fds))
++ readevent();
++ if (FD_ISSET(0, &fds))
++ readstdin();
++ }
++}
++
+ static void
+ setup(void)
+ {
+_AT_@ -682,7 +718,7 @@ setup(void)
+ static void
+ usage(void)
+ {
+- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]
"
++ fputs("usage: dmenu [-biv] [-l lines] [-p prompt] [-fn font] [-m monitor]
"
+ " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]
", stderr);
+ exit(1);
+ }
+_AT_@ -691,7 +727,7 @@ int
+ main(int argc, char *argv[])
+ {
+ XWindowAttributes wa;
+- int i, fast = 0;
++ int i;
+
+ for (i = 1; i < argc; i++)
+ /* these options take no arguments */
+_AT_@ -700,8 +736,6 @@ main(int argc, char *argv[])
+ exit(0);
+ } else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
+ topbar = 0;
+- else if (!strcmp(argv[i], "-f")) /* grabs keyboard before reading stdin */
+- fast = 1;
+ else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
+ fstrncmp = strncasecmp;
+ fstrstr = cistrstr;
+_AT_@ -752,13 +786,7 @@ main(int argc, char *argv[])
+ die("pledge");
+ #endif
+
+- if (fast && !isatty(0)) {
+- grabkeyboard();
+- readstdin();
+- } else {
+- readstdin();
+- grabkeyboard();
+- }
++ grabkeyboard();
+ setup();
+ run();
+
+--
+2.19.2
+
diff --git a/tools.suckless.org/dmenu/patches/non_blocking_stdin/index.md b/tools.suckless.org/dmenu/patches/non_blocking_stdin/index.md
index 23fc00c3..3e18fbdd 100644
--- a/tools.suckless.org/dmenu/patches/non_blocking_stdin/index.md
+++ b/tools.suckless.org/dmenu/patches/non_blocking_stdin/index.md
_AT_@ -10,9 +10,11 @@ patch, so that you can use stdout to feed stdin.
Download
--------
+* [dmenu-nonblockingstdin-4.9.diff](dmenu-nonblockingstdin-4.9.diff)
* [dmenu-nonblockingstdin-20160702-3c91eed.diff](dmenu-nonblockingstdin-20160702-3c91eed.diff)
Author
------
* Christophe-Marie Duquesne <chm.duquesne_AT_gmail.com>
* koniu at riseup.net (update for 20160615 git master)
+* Miles Alan - m_AT_milesalan.com (update for 4.9)
Received on Mon Aug 12 2019 - 23:50:33 CEST
This archive was generated by hypermail 2.3.0
: Tue Aug 13 2019 - 00:00:36 CEST