added multiselection patch

This commit is contained in:
Alexander Bocken 2021-01-02 16:57:31 +01:00
parent a414a7af4e
commit 005e613d94
Signed by: Alexander
GPG Key ID: 1D237BE83F9B05E8
2 changed files with 39 additions and 6 deletions

View File

@ -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
- initial text patch
- offset to match bar offset I use in dwm
- multiselection patch

44
dmenu.c
View File

@ -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]);
@ -374,6 +388,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();
@ -471,13 +499,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') {
@ -541,7 +573,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;