Return to repo list

suckless-gf-dmenu

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

multi-selection.patch (2833B)


      1 diff --git a/dmenu.c b/dmenu.c
      2 index 6b8f51b..6544112 100644
      3 --- a/dmenu.c
      4 +++ b/dmenu.c
      5 @@ -31,7 +31,8 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
      6  struct item {
      7  	char *text;
      8  	struct item *left, *right;
      9 -	int out;
     10 +
     11 +	int id; /* for multiselect */
     12  };
     13  
     14  static char text[BUFSIZ] = "";
     15 @@ -45,6 +46,9 @@ static struct item *matches, *matchend;
     16  static struct item *prev, *curr, *next, *sel;
     17  static int mon = -1, screen;
     18  
     19 +static int *selid = NULL;
     20 +static unsigned int selidsize = 0;
     21 +
     22  static Atom clip, utf8;
     23  static Display *dpy;
     24  static Window root, parentwin, win;
     25 @@ -58,6 +62,16 @@ static Clr *scheme[SchemeLast];
     26  static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
     27  static char *(*fstrstr)(const char *, const char *) = strstr;
     28  
     29 +static int
     30 +issel(size_t id)
     31 +{
     32 +   int i = 0;
     33 +	for (i;i < selidsize;i++)
     34 +		if (selid[i] == id)
     35 +			return 1;
     36 +	return 0;
     37 +}
     38 +
     39  static void
     40  appenditem(struct item *item, struct item **list, struct item **last)
     41  {
     42 @@ -100,6 +113,7 @@ cleanup(void)
     43  	drw_free(drw);
     44  	XSync(dpy, False);
     45  	XCloseDisplay(dpy);
     46 +	free(selid);
     47  }
     48  
     49  static char *
     50 @@ -118,7 +132,7 @@ drawitem(struct item *item, int x, int y, int w)
     51  {
     52  	if (item == sel)
     53  		drw_setscheme(drw, scheme[SchemeSel]);
     54 -	else if (item->out)
     55 +	else if (issel(item->id))
     56  		drw_setscheme(drw, scheme[SchemeOut]);
     57  	else
     58  		drw_setscheme(drw, scheme[SchemeNorm]);
     59 @@ -367,6 +381,22 @@ keypress(XKeyEvent *ev)
     60  			goto draw;
     61  		case XK_Return:
     62  		case XK_KP_Enter:
     63 +			if (sel && issel(sel->id)) {
     64 +               int i = 0;
     65 +				for (i;i < selidsize;i++)
     66 +					if (selid[i] == sel->id)
     67 +						selid[i] = -1;
     68 +			} else {
     69 +               int i = 0;
     70 +				for (i;i < selidsize;i++)
     71 +					if (selid[i] == -1) {
     72 +						selid[i] = sel->id;
     73 +						return;
     74 +					}
     75 +				selidsize++;
     76 +				selid = realloc(selid, (selidsize + 1) * sizeof(int));
     77 +				selid[selidsize - 1] = sel->id;
     78 +			}
     79  			break;
     80  		case XK_bracketleft:
     81  			cleanup();
     82 @@ -464,13 +492,18 @@ insert:
     83  		break;
     84  	case XK_Return:
     85  	case XK_KP_Enter:
     86 -		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
     87  		if (!(ev->state & ControlMask)) {
     88 +           int i = 0;
     89 +			for (i;i < selidsize;i++)
     90 +				if (selid[i] != -1 && (!sel || sel->id != selid[i]))
     91 +					puts(items[selid[i]].text);
     92 +			if (sel && !(ev->state & ShiftMask))
     93 +				puts(sel->text);
     94 +			else
     95 +				puts(text);
     96  			cleanup();
     97  			exit(0);
     98  		}
     99 -		if (sel)
    100 -			sel->out = 1;
    101  		break;
    102  	case XK_Right:
    103  		if (text[cursor] != '\0') {
    104 @@ -534,7 +566,7 @@ readstdin(void)
    105  			*p = '\0';
    106  		if (!(items[i].text = strdup(buf)))
    107  			die("cannot strdup %u bytes:", strlen(buf) + 1);
    108 -		items[i].out = 0;
    109 +		items[i].id = i; /* for multiselect */
    110  		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
    111  		if (tmpmax > inputw) {
    112  			inputw = tmpmax;