added multiselection patch
This commit is contained in:
parent
a414a7af4e
commit
005e613d94
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user