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;