Return to repo list

suckless-gf-dmenu

Gentoo-friendly patches for Suckless's dmenu.
Return to HMagellan.com

commit 4d825beef3ec45c984e0a47590ceb38cbbe68b89
parent d491991a22af459398f22c9a118d23db370c455a
Author: Erik Letson <hmagellan@hmagellan.com>
Date:   Wed, 26 Aug 2020 16:40:12 -0500

added nonblockingstdin

Diffstat:
MREADME | 2+-
Apatches/nonblockingstdin/USAGE | 28++++++++++++++++++++++++++++
Apatches/nonblockingstdin/nonblockingstdin-nodoc.patch | 222+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apatches/nonblockingstdin/nonblockingstdin.patch | 265+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 516 insertions(+), 1 deletion(-)

diff --git a/README b/README @@ -42,7 +42,7 @@ patches! (1). https://tools.suckless.org/dmenu/patches/ - CURRENT PROGRESS: 16/32 patches supported + CURRENT PROGRESS: 17/32 patches supported 3/32 patches unsupported USUPPORTED PATCHES: diff --git a/patches/nonblockingstdin/USAGE b/patches/nonblockingstdin/USAGE @@ -0,0 +1,28 @@ +nonblockingstdin - Have dmenu read stdin in a non-blocking way +Source: https://tools.suckless.org/dmenu/patches/non_blocking_stdin/dmenu-nonblockingstdin-4.9.diff +Original Authors: Christophe-Marie Duquesne chm.duquesne@gmail.com + koniu at riseup.net (update for 20160615 git master) + Miles Alan - m@milesalan.com (update for 4.9) + +Description from source: + """ + A patch to have dmenu read stdin in a non blocking way, making it wait for input both from stdin and from X. This + way, you can continue feeding dmenu while you type. This patch is meant to be used along with the incremental patch, + so that you can use stdout to feed stdin. + """ + +== YOU MUST == +(1). Place the patch file in /etc/portage/patches/x11-misc/dmenu/ and run 'emerge dmenu' + +== YOU PROBABLY SHOULD == +(1). This patch removes the '-f' option, so you will no longer be able to use that. + +== PATCH MODIFICATIONS == +(1). Modified chunk #2 of the dmenu.1 diff to reflect the Gentoo version's code +(2). Modified chunks #8 and #13 of the dmenu.c diff to reflect the Gentoo version's code +(3). Added a 'nodoc' patch version which strips out added documentation + +== INCOMPATIBILITIES == +THIS PATCH MAKES CHANGES TO DMENU'S BUILT-IN DOCUMENTATION, WHICH CAN CAUSE CONFLICTS WITH OTHER PATCHES! +If you encounter such conflicts, try emerging with the 'nonblockingstdin-nodoc.patch' file instead. It is the +same as the 'nonblockingstdin.patch' file except it makes no changes to the documentation. diff --git a/patches/nonblockingstdin/nonblockingstdin-nodoc.patch b/patches/nonblockingstdin/nonblockingstdin-nodoc.patch @@ -0,0 +1,222 @@ +diff --git a/dmenu.c b/dmenu.c +index 6b8f51b..479a4c8 100644 +--- a/dmenu.c ++++ b/dmenu.c +@@ -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> +@@ -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> +@@ -31,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + struct item { + char *text; + struct item *left, *right; ++ struct item *next; + int out; + }; + +@@ -173,6 +176,7 @@ drawmenu(void) + } + } + drw_map(drw, win, 0, 0, mw, mh); ++ XFlush(dpy); + } + + static void +@@ -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 */ +@@ -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) { +@@ -260,7 +269,9 @@ match(void) + matches = lsubstr; + matchend = substrend; + } +- curr = sel = matches; ++ if (!preserve) ++ curr = sel = matches; ++ + calcoffsets(); + } + +@@ -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, '\n'))) +- *p = '\0'; +- 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, win)) + continue; + switch(ev.type) { +@@ -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, '\n'))) ++ *p = '\0'; ++ 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) + { +@@ -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 */ +@@ -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; +@@ -752,13 +786,7 @@ main(int argc, char *argv[]) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + +- if (fast) { +- grabkeyboard(); +- readstdin(); +- } else { +- readstdin(); +- grabkeyboard(); +- } ++ grabkeyboard(); + setup(); + run(); + +-- +2.19.2 + diff --git a/patches/nonblockingstdin/nonblockingstdin.patch b/patches/nonblockingstdin/nonblockingstdin.patch @@ -0,0 +1,265 @@ +From 0c22fa69134c8b1547a5518b5a22d0c49ef56ed1 Mon Sep 17 00:00:00 2001 +From: Miles Alan <m@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 +@@ -3,7 +3,7 @@ + dmenu \- dynamic menu + .SH SYNOPSIS + .B dmenu +-.RB [ \-bfiv ] ++.RB [ \-biv ] + .RB [ \-l + .IR lines ] + .RB [ \-m +@@ -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. 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 +@@ -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> +@@ -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> +@@ -31,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */ + struct item { + char *text; + struct item *left, *right; ++ struct item *next; + int out; + }; + +@@ -173,6 +176,7 @@ drawmenu(void) + } + } + drw_map(drw, win, 0, 0, mw, mh); ++ XFlush(dpy); + } + + static void +@@ -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 */ +@@ -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) { +@@ -260,7 +269,9 @@ match(void) + matches = lsubstr; + matchend = substrend; + } +- curr = sel = matches; ++ if (!preserve) ++ curr = sel = matches; ++ + calcoffsets(); + } + +@@ -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, '\n'))) +- *p = '\0'; +- 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, win)) + continue; + switch(ev.type) { +@@ -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, '\n'))) ++ *p = '\0'; ++ 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) + { +@@ -682,7 +718,7 @@ setup(void) + static void + usage(void) + { +- fputs("usage: dmenu [-bfiv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" ++ fputs("usage: dmenu [-biv] [-l lines] [-p prompt] [-fn font] [-m monitor]\n" + " [-nb color] [-nf color] [-sb color] [-sf color] [-w windowid]\n", stderr); + exit(1); + } +@@ -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 */ +@@ -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; +@@ -752,13 +786,7 @@ main(int argc, char *argv[]) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + +- if (fast) { +- grabkeyboard(); +- readstdin(); +- } else { +- readstdin(); +- grabkeyboard(); +- } ++ grabkeyboard(); + setup(); + run(); + +-- +2.19.2 +