|
|
- diff --git a/dmenu.c b/dmenu.c
- index 6b8f51b..6544112 100644
- --- a/dmenu.c
- +++ b/dmenu.c
- @@ -31,7 +31,8 @@ enum { SchemeNorm, SchemeSel, SchemeOut, SchemeLast }; /* color schemes */
- struct item {
- char *text;
- struct item *left, *right;
- - int out;
- +
- + int id; /* for multiselect */
- };
-
- static char text[BUFSIZ] = "";
- @@ -45,6 +46,9 @@ static struct item *matches, *matchend;
- static struct item *prev, *curr, *next, *sel;
- static int mon = -1, screen;
-
- +static int *selid = NULL;
- +static unsigned int selidsize = 0;
- +
- static Atom clip, utf8;
- static Display *dpy;
- static Window root, parentwin, win;
- @@ -58,6 +62,15 @@ static Clr *scheme[SchemeLast];
- static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
- 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
- appenditem(struct item *item, struct item **list, struct item **last)
- {
- @@ -100,6 +113,7 @@ cleanup(void)
- drw_free(drw);
- XSync(dpy, False);
- XCloseDisplay(dpy);
- + free(selid);
- }
-
- static char *
- @@ -118,7 +132,7 @@ drawitem(struct item *item, int x, int y, int w)
- {
- if (item == sel)
- drw_setscheme(drw, scheme[SchemeSel]);
- - else if (item->out)
- + else if (issel(item->id))
- drw_setscheme(drw, scheme[SchemeOut]);
- else
- drw_setscheme(drw, scheme[SchemeNorm]);
- @@ -367,6 +381,20 @@ keypress(XKeyEvent *ev)
- goto draw;
- case XK_Return:
- 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;
- case XK_bracketleft:
- cleanup();
- @@ -464,13 +492,17 @@ insert:
- break;
- case XK_Return:
- case XK_KP_Enter:
- - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
- 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();
- exit(0);
- }
- - if (sel)
- - sel->out = 1;
- break;
- case XK_Right:
- if (text[cursor] != '\0') {
- @@ -534,7 +566,7 @@ readstdin(void)
- *p = '\0';
- if (!(items[i].text = strdup(buf)))
- 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);
- if (tmpmax > inputw) {
- inputw = tmpmax;
|