Return to repo list

suckless-gf-dmenu

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

nonblockingstdin-nodoc.patch (5299B)


      1 diff --git a/dmenu.c b/dmenu.c
      2 index 6b8f51b..479a4c8 100644
      3 --- a/dmenu.c
      4 +++ b/dmenu.c
      5 @@ -1,5 +1,6 @@
      6  /* See LICENSE file for copyright and license details. */
      7  #include <ctype.h>
      8 +#include <fcntl.h>
      9  #include <locale.h>
     10  #include <stdio.h>
     11  #include <stdlib.h>
     12 @@ -8,6 +9,7 @@
     13  #include <time.h>
     14  #include <unistd.h>
     15  
     16 +#include <sys/select.h>
     17  #include <X11/Xlib.h>
     18  #include <X11/Xatom.h>
     19  #include <X11/Xutil.h>
     20 @@ -31,6 +33,7 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
     21  struct item {
     22  	char *text;
     23  	struct item *left, *right;
     24 +	struct item *next;
     25  	int out;
     26  };
     27  
     28 @@ -173,6 +176,7 @@ drawmenu(void)
     29  		}
     30  	}
     31  	drw_map(drw, win, 0, 0, mw, mh);
     32 +	XFlush(dpy);
     33  }
     34  
     35  static void
     36 @@ -220,6 +224,7 @@ match(void)
     37  	int i, tokc = 0;
     38  	size_t len, textsize;
     39  	struct item *item, *lprefix, *lsubstr, *prefixend, *substrend;
     40 +	int preserve = 0;
     41  
     42  	strcpy(buf, text);
     43  	/* separate input text into tokens to be matched individually */
     44 @@ -230,19 +235,23 @@ match(void)
     45  
     46  	matches = lprefix = lsubstr = matchend = prefixend = substrend = NULL;
     47  	textsize = strlen(text) + 1;
     48 -	for (item = items; item && item->text; item++) {
     49 +	for (item = items; item; item = item->next) {
     50  		for (i = 0; i < tokc; i++)
     51  			if (!fstrstr(item->text, tokv[i]))
     52  				break;
     53  		if (i != tokc) /* not all tokens match */
     54  			continue;
     55  		/* exact matches go first, then prefixes, then substrings */
     56 -		if (!tokc || !fstrncmp(text, item->text, textsize))
     57 +		if (!tokc || !fstrncmp(text, item->text, textsize)) {
     58  			appenditem(item, &matches, &matchend);
     59 -		else if (!fstrncmp(tokv[0], item->text, len))
     60 +			if (sel == item) preserve = 1;
     61 +		} else if (!fstrncmp(tokv[0], item->text, len)) {
     62  			appenditem(item, &lprefix, &prefixend);
     63 -		else
     64 +			if (sel == item) preserve = 1;
     65 +		} else {
     66  			appenditem(item, &lsubstr, &substrend);
     67 +			if (sel == item) preserve = 1;
     68 +		}
     69  	}
     70  	if (lprefix) {
     71  		if (matches) {
     72 @@ -260,7 +269,9 @@ match(void)
     73  			matches = lsubstr;
     74  		matchend = substrend;
     75  	}
     76 -	curr = sel = matches;
     77 +	if (!preserve)
     78 +		curr = sel = matches;
     79 +
     80  	calcoffsets();
     81  }
     82  
     83 @@ -519,40 +530,11 @@ paste(void)
     84  }
     85  
     86  static void
     87 -readstdin(void)
     88 -{
     89 -	char buf[sizeof text], *p;
     90 -	size_t i, imax = 0, size = 0;
     91 -	unsigned int tmpmax = 0;
     92 -
     93 -	/* read each line from stdin and add it to the item list */
     94 -	for (i = 0; fgets(buf, sizeof buf, stdin); i++) {
     95 -		if (i + 1 >= size / sizeof *items)
     96 -			if (!(items = realloc(items, (size += BUFSIZ))))
     97 -				die("cannot realloc %u bytes:", size);
     98 -		if ((p = strchr(buf, '\n')))
     99 -			*p = '\0';
    100 -		if (!(items[i].text = strdup(buf)))
    101 -			die("cannot strdup %u bytes:", strlen(buf) + 1);
    102 -		items[i].out = 0;
    103 -		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
    104 -		if (tmpmax > inputw) {
    105 -			inputw = tmpmax;
    106 -			imax = i;
    107 -		}
    108 -	}
    109 -	if (items)
    110 -		items[i].text = NULL;
    111 -	inputw = items ? TEXTW(items[imax].text) : 0;
    112 -	lines = MIN(lines, i);
    113 -}
    114 -
    115 -static void
    116 -run(void)
    117 +readevent(void)
    118  {
    119  	XEvent ev;
    120  
    121 -	while (!XNextEvent(dpy, &ev)) {
    122 +	while (XPending(dpy) && !XNextEvent(dpy, &ev)) {
    123  		if (XFilterEvent(&ev, win))
    124  			continue;
    125  		switch(ev.type) {
    126 @@ -580,6 +562,60 @@ run(void)
    127  	}
    128  }
    129  
    130 +static void
    131 +readstdin(void)
    132 +{
    133 +	static size_t max = 0;
    134 +	static struct item **end = &items;
    135 +
    136 +	char buf[sizeof text], *p, *maxstr;
    137 +	struct item *item;
    138 +
    139 +	/* read each line from stdin and add it to the item list */
    140 +	while (fgets(buf, sizeof buf, stdin)) {
    141 +		if (!(item = malloc(sizeof *item)))
    142 +			die("cannot malloc %u bytes:", sizeof *item);
    143 +		if ((p = strchr(buf, '\n')))
    144 +			*p = '\0';
    145 +		if (!(item->text = strdup(buf)))
    146 +			die("cannot strdup %u bytes:", strlen(buf)+1);
    147 +		if (strlen(item->text) > max) {
    148 +			max = strlen(maxstr = item->text);
    149 +			inputw = maxstr ? TEXTW(maxstr) : 0;
    150 +		}
    151 +		*end = item;
    152 +		end = &item->next;
    153 +		item->next = NULL;
    154 +		item->out = 0;
    155 +	}
    156 +	match();
    157 +	drawmenu();
    158 +}
    159 +
    160 +static void
    161 +run(void)
    162 +{
    163 +	fd_set fds;
    164 +	int flags, xfd = XConnectionNumber(dpy);
    165 +
    166 +	if ((flags = fcntl(0, F_GETFL)) == -1)
    167 +		die("cannot get stdin control flags:");
    168 +	if (fcntl(0, F_SETFL, flags | O_NONBLOCK) == -1)
    169 +		die("cannot set stdin control flags:");
    170 +	for (;;) {
    171 +		FD_ZERO(&fds);
    172 +		FD_SET(xfd, &fds);
    173 +		if (!feof(stdin))
    174 +			FD_SET(0, &fds);
    175 +		if (select(xfd + 1, &fds, NULL, NULL, NULL) == -1)
    176 +			die("cannot multiplex input:");
    177 +		if (FD_ISSET(xfd, &fds))
    178 +			readevent();
    179 +		if (FD_ISSET(0, &fds))
    180 +			readstdin();
    181 +	}
    182 +}
    183 +
    184  static void
    185  setup(void)
    186  {
    187 @@ -691,7 +727,7 @@ int
    188  main(int argc, char *argv[])
    189  {
    190  	XWindowAttributes wa;
    191 -	int i, fast = 0;
    192 +	int i;
    193  
    194  	for (i = 1; i < argc; i++)
    195  		/* these options take no arguments */
    196 @@ -700,8 +736,6 @@ main(int argc, char *argv[])
    197  			exit(0);
    198  		} else if (!strcmp(argv[i], "-b")) /* appears at the bottom of the screen */
    199  			topbar = 0;
    200 -		else if (!strcmp(argv[i], "-f"))   /* grabs keyboard before reading stdin */
    201 -			fast = 1;
    202  		else if (!strcmp(argv[i], "-i")) { /* case-insensitive item matching */
    203  			fstrncmp = strncasecmp;
    204  			fstrstr = cistrstr;
    205 @@ -752,13 +786,7 @@ main(int argc, char *argv[])
    206         die("no fonts could be loaded.");
    207     lrpad = drw->fonts->h;
    208  
    209 -	if (fast) {
    210 -		grabkeyboard();
    211 -		readstdin();
    212 -	} else {
    213 -		readstdin();
    214 -		grabkeyboard();
    215 -	}
    216 +	grabkeyboard();
    217  	setup();
    218  	run();
    219  
    220 -- 
    221 2.19.2
    222