sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dmenu-multi-selection-4.9.diff (2773B)


      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,15 @@ 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 +	for (int i = 0;i < selidsize;i++)
     33 +		if (selid[i] == id)
     34 +			return 1;
     35 +	return 0;
     36 +}
     37 +
     38  static void
     39  appenditem(struct item *item, struct item **list, struct item **last)
     40  {
     41 @@ -100,6 +113,7 @@ cleanup(void)
     42  	drw_free(drw);
     43  	XSync(dpy, False);
     44  	XCloseDisplay(dpy);
     45 +	free(selid);
     46  }
     47  
     48  static char *
     49 @@ -118,7 +132,7 @@ drawitem(struct item *item, int x, int y, int w)
     50  {
     51  	if (item == sel)
     52  		drw_setscheme(drw, scheme[SchemeSel]);
     53 -	else if (item->out)
     54 +	else if (issel(item->id))
     55  		drw_setscheme(drw, scheme[SchemeOut]);
     56  	else
     57  		drw_setscheme(drw, scheme[SchemeNorm]);
     58 @@ -367,6 +381,20 @@ keypress(XKeyEvent *ev)
     59  			goto draw;
     60  		case XK_Return:
     61  		case XK_KP_Enter:
     62 +			if (sel && issel(sel->id)) {
     63 +				for (int i = 0;i < selidsize;i++)
     64 +					if (selid[i] == sel->id)
     65 +						selid[i] = -1;
     66 +			} else {
     67 +				for (int i = 0;i < selidsize;i++)
     68 +					if (selid[i] == -1) {
     69 +						selid[i] = sel->id;
     70 +						return;
     71 +					}
     72 +				selidsize++;
     73 +				selid = realloc(selid, (selidsize + 1) * sizeof(int));
     74 +				selid[selidsize - 1] = sel->id;
     75 +			}
     76  			break;
     77  		case XK_bracketleft:
     78  			cleanup();
     79 @@ -464,13 +492,17 @@ insert:
     80  		break;
     81  	case XK_Return:
     82  	case XK_KP_Enter:
     83 -		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
     84  		if (!(ev->state & ControlMask)) {
     85 +			for (int i = 0;i < selidsize;i++)
     86 +				if (selid[i] != -1 && (!sel || sel->id != selid[i]))
     87 +					puts(items[selid[i]].text);
     88 +			if (sel && !(ev->state & ShiftMask))
     89 +				puts(sel->text);
     90 +			else
     91 +				puts(text);
     92  			cleanup();
     93  			exit(0);
     94  		}
     95 -		if (sel)
     96 -			sel->out = 1;
     97  		break;
     98  	case XK_Right:
     99  		if (text[cursor] != '\0') {
    100 @@ -534,7 +566,7 @@ readstdin(void)
    101  			*p = '\0';
    102  		if (!(items[i].text = strdup(buf)))
    103  			die("cannot strdup %u bytes:", strlen(buf) + 1);
    104 -		items[i].out = 0;
    105 +		items[i].id = i; /* for multiselect */
    106  		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
    107  		if (tmpmax > inputw) {
    108  			inputw = tmpmax;