added multiselection patch
This commit is contained in:
		@@ -28,3 +28,4 @@ This version of dmenu has a few personal changes:
 | 
				
			|||||||
- dmenu_run uses a history file, can launch a terminal with said command by appending "!" to it
 | 
					- dmenu_run uses a history file, can launch a terminal with said command by appending "!" to it
 | 
				
			||||||
- initial text patch
 | 
					- initial text patch
 | 
				
			||||||
- offset to match bar offset I use in dwm
 | 
					- offset to match bar offset I use in dwm
 | 
				
			||||||
 | 
					- multiselection patch
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								dmenu.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								dmenu.c
									
									
									
									
									
								
							@@ -31,7 +31,8 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
 | 
				
			|||||||
struct item {
 | 
					struct item {
 | 
				
			||||||
	char *text;
 | 
						char *text;
 | 
				
			||||||
	struct item *left, *right;
 | 
						struct item *left, *right;
 | 
				
			||||||
	int out;
 | 
					
 | 
				
			||||||
 | 
						int id; /* for multiselect */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char text[BUFSIZ] = "";
 | 
					static char text[BUFSIZ] = "";
 | 
				
			||||||
@@ -45,6 +46,9 @@ static struct item *matches, *matchend;
 | 
				
			|||||||
static struct item *prev, *curr, *next, *sel;
 | 
					static struct item *prev, *curr, *next, *sel;
 | 
				
			||||||
static int mon = -1, screen;
 | 
					static int mon = -1, screen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int *selid = NULL;
 | 
				
			||||||
 | 
					static unsigned int selidsize = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Atom clip, utf8;
 | 
					static Atom clip, utf8;
 | 
				
			||||||
static Display *dpy;
 | 
					static Display *dpy;
 | 
				
			||||||
static Window root, parentwin, win;
 | 
					static Window root, parentwin, win;
 | 
				
			||||||
@@ -58,6 +62,15 @@ static Clr *scheme[SchemeLast];
 | 
				
			|||||||
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
 | 
					static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
 | 
				
			||||||
static char *(*fstrstr)(const char *, const char *) = strstr;
 | 
					static char *(*fstrstr)(const char *, const char *) = strstr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int
 | 
				
			||||||
 | 
					issel(size_t id)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (int i = 0;i < selidsize;i++)
 | 
				
			||||||
 | 
							if (selid[i] == id)
 | 
				
			||||||
 | 
								return 1;
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void
 | 
					static void
 | 
				
			||||||
appenditem(struct item *item, struct item **list, struct item **last)
 | 
					appenditem(struct item *item, struct item **list, struct item **last)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -100,6 +113,7 @@ cleanup(void)
 | 
				
			|||||||
	drw_free(drw);
 | 
						drw_free(drw);
 | 
				
			||||||
	XSync(dpy, False);
 | 
						XSync(dpy, False);
 | 
				
			||||||
	XCloseDisplay(dpy);
 | 
						XCloseDisplay(dpy);
 | 
				
			||||||
 | 
						free(selid);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char *
 | 
					static char *
 | 
				
			||||||
@@ -118,7 +132,7 @@ drawitem(struct item *item, int x, int y, int w)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	if (item == sel)
 | 
						if (item == sel)
 | 
				
			||||||
		drw_setscheme(drw, scheme[SchemeSel]);
 | 
							drw_setscheme(drw, scheme[SchemeSel]);
 | 
				
			||||||
	else if (item->out)
 | 
						else if (issel(item->id))
 | 
				
			||||||
		drw_setscheme(drw, scheme[SchemeOut]);
 | 
							drw_setscheme(drw, scheme[SchemeOut]);
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		drw_setscheme(drw, scheme[SchemeNorm]);
 | 
							drw_setscheme(drw, scheme[SchemeNorm]);
 | 
				
			||||||
@@ -374,6 +388,20 @@ keypress(XKeyEvent *ev)
 | 
				
			|||||||
			goto draw;
 | 
								goto draw;
 | 
				
			||||||
		case XK_Return:
 | 
							case XK_Return:
 | 
				
			||||||
		case XK_KP_Enter:
 | 
							case XK_KP_Enter:
 | 
				
			||||||
 | 
								if (sel && issel(sel->id)) {
 | 
				
			||||||
 | 
									for (int i = 0;i < selidsize;i++)
 | 
				
			||||||
 | 
										if (selid[i] == sel->id)
 | 
				
			||||||
 | 
											selid[i] = -1;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									for (int i = 0;i < selidsize;i++)
 | 
				
			||||||
 | 
										if (selid[i] == -1) {
 | 
				
			||||||
 | 
											selid[i] = sel->id;
 | 
				
			||||||
 | 
											return;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									selidsize++;
 | 
				
			||||||
 | 
									selid = realloc(selid, (selidsize + 1) * sizeof(int));
 | 
				
			||||||
 | 
									selid[selidsize - 1] = sel->id;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case XK_bracketleft:
 | 
							case XK_bracketleft:
 | 
				
			||||||
			cleanup();
 | 
								cleanup();
 | 
				
			||||||
@@ -471,13 +499,17 @@ insert:
 | 
				
			|||||||
		break;
 | 
							break;
 | 
				
			||||||
	case XK_Return:
 | 
						case XK_Return:
 | 
				
			||||||
	case XK_KP_Enter:
 | 
						case XK_KP_Enter:
 | 
				
			||||||
		puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
 | 
					 | 
				
			||||||
		if (!(ev->state & ControlMask)) {
 | 
							if (!(ev->state & ControlMask)) {
 | 
				
			||||||
 | 
								for (int i = 0;i < selidsize;i++)
 | 
				
			||||||
 | 
									if (selid[i] != -1 && (!sel || sel->id != selid[i]))
 | 
				
			||||||
 | 
										puts(items[selid[i]].text);
 | 
				
			||||||
 | 
								if (sel && !(ev->state & ShiftMask))
 | 
				
			||||||
 | 
									puts(sel->text);
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									puts(text);
 | 
				
			||||||
			cleanup();
 | 
								cleanup();
 | 
				
			||||||
			exit(0);
 | 
								exit(0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (sel)
 | 
					 | 
				
			||||||
			sel->out = 1;
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case XK_Right:
 | 
						case XK_Right:
 | 
				
			||||||
		if (text[cursor] != '\0') {
 | 
							if (text[cursor] != '\0') {
 | 
				
			||||||
@@ -541,7 +573,7 @@ readstdin(void)
 | 
				
			|||||||
			*p = '\0';
 | 
								*p = '\0';
 | 
				
			||||||
		if (!(items[i].text = strdup(buf)))
 | 
							if (!(items[i].text = strdup(buf)))
 | 
				
			||||||
			die("cannot strdup %u bytes:", strlen(buf) + 1);
 | 
								die("cannot strdup %u bytes:", strlen(buf) + 1);
 | 
				
			||||||
		items[i].out = 0;
 | 
							items[i].id = i; /* for multiselect */
 | 
				
			||||||
		drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
 | 
							drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
 | 
				
			||||||
		if (tmpmax > inputw) {
 | 
							if (tmpmax > inputw) {
 | 
				
			||||||
			inputw = tmpmax;
 | 
								inputw = tmpmax;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user