dmenu-multi-selection-4.9.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) 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;