mirror of
https://github.com/mintycube/dmenu.git
synced 2024-10-22 12:05:48 +00:00
Adding multi-select patch
This commit is contained in:
parent
841a0cff2b
commit
240cce1c1a
@ -15,7 +15,7 @@ Refer to [https://tools.suckless.org/dmenu/](https://tools.suckless.org/dmenu/)
|
||||
|
||||
### Changelog:
|
||||
|
||||
2020-08-08 - Added the symbols, managed, morecolor and preselect patches
|
||||
2020-08-08 - Added the symbols, managed, morecolor, multi-selection and preselect patches
|
||||
|
||||
2020-08-05 - Added the grid, highlight, highpriority, dynamic options and numbers patches
|
||||
|
||||
@ -95,6 +95,11 @@ Refer to [https://tools.suckless.org/dmenu/](https://tools.suckless.org/dmenu/)
|
||||
- [mouse-support](https://tools.suckless.org/dmenu/patches/mouse-support/)
|
||||
- adds basic mouse support for dmenu
|
||||
|
||||
- [multi-selection](https://tools.suckless.org/dmenu/patches/multi-selection/)
|
||||
- without this patch when you press `Ctrl+Enter` dmenu just outputs current item and it is not possible to undo that
|
||||
- with this patch dmenu will output all selected items only on exit
|
||||
- it is also possible to deselect any selected item
|
||||
|
||||
- [navhistory](https://tools.suckless.org/dmenu/patches/navhistory/)
|
||||
- provides dmenu the ability for history navigation similar to that of bash
|
||||
|
||||
|
@ -93,7 +93,7 @@ static int histnodup = 1; /* if 0, record repeated histories */
|
||||
* Characters not considered part of a word while deleting words
|
||||
* for example: " /?\"&[]"
|
||||
*/
|
||||
#if PIPEOUT_PATCH
|
||||
#if PIPEOUT_PATCH && !MULTI_SELECT_PATCH
|
||||
static const char startpipe[] = "#";
|
||||
#endif // PIPEOUT_PATCH
|
||||
static const char worddelimiters[] = " ";
|
||||
|
37
dmenu.c
37
dmenu.c
@ -59,7 +59,11 @@ struct item {
|
||||
#if NON_BLOCKING_STDIN_PATCH
|
||||
struct item *next;
|
||||
#endif // NON_BLOCKING_STDIN_PATCH
|
||||
#if MULTI_SELECT_PATCH
|
||||
int id; /* for multiselect */
|
||||
#else
|
||||
int out;
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
#if HIGHPRIORITY_PATCH
|
||||
int hp;
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
@ -69,7 +73,7 @@ struct item {
|
||||
};
|
||||
|
||||
static char text[BUFSIZ] = "";
|
||||
#if PIPEOUT_PATCH
|
||||
#if PIPEOUT_PATCH && !MULTI_SELECT_PATCH
|
||||
static char pipeout[8] = " | dmenu";
|
||||
#endif // PIPEOUT_PATCH
|
||||
static char *embed;
|
||||
@ -94,7 +98,11 @@ static int mon = -1, screen;
|
||||
#if MANAGED_PATCH
|
||||
static int managed = 0;
|
||||
#endif // MANAGED_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH
|
||||
#if MULTI_SELECT_PATCH
|
||||
static int *selid = NULL;
|
||||
static unsigned int selidsize = 0;
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH && !MULTI_SELECT_PATCH
|
||||
static int use_text_input = 0;
|
||||
#endif // PRINTINPUTTEXT_PATCH
|
||||
#if PRESELECT_PATCH
|
||||
@ -217,6 +225,9 @@ cleanup(void)
|
||||
drw_free(drw);
|
||||
XSync(dpy, False);
|
||||
XCloseDisplay(dpy);
|
||||
#if MULTI_SELECT_PATCH
|
||||
free(selid);
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -244,7 +255,11 @@ drawitem(struct item *item, int x, int y, int w)
|
||||
else if (item->left == sel || item->right == sel)
|
||||
drw_setscheme(drw, scheme[SchemeMid]);
|
||||
#endif // MORECOLOR_PATCH
|
||||
#if MULTI_SELECT_PATCH
|
||||
else if (issel(item->id))
|
||||
#else
|
||||
else if (item->out)
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
drw_setscheme(drw, scheme[SchemeOut]);
|
||||
else
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
@ -755,6 +770,9 @@ keypress(XKeyEvent *ev)
|
||||
goto draw;
|
||||
case XK_Return:
|
||||
case XK_KP_Enter:
|
||||
#if MULTI_SELECT_PATCH
|
||||
selsel();
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
break;
|
||||
case XK_bracketleft:
|
||||
cleanup();
|
||||
@ -856,6 +874,7 @@ insert:
|
||||
break;
|
||||
case XK_Return:
|
||||
case XK_KP_Enter:
|
||||
#if !MULTI_SELECT_PATCH
|
||||
#if PIPEOUT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH
|
||||
if (sel && (
|
||||
@ -886,16 +905,22 @@ insert:
|
||||
#else
|
||||
puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
|
||||
#endif // PIPEOUT_PATCH
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
if (!(ev->state & ControlMask)) {
|
||||
#if NAVHISTORY_PATCH
|
||||
savehistory((sel && !(ev->state & ShiftMask))
|
||||
? sel->text : text);
|
||||
#endif // NAVHISTORY_PATCH
|
||||
#if MULTI_SELECT_PATCH
|
||||
printsel(ev->state);
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
cleanup();
|
||||
exit(0);
|
||||
}
|
||||
#if !MULTI_SELECT_PATCH
|
||||
if (sel)
|
||||
sel->out = 1;
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
break;
|
||||
case XK_Right:
|
||||
if (text[cursor] != '\0') {
|
||||
@ -1026,7 +1051,11 @@ readstdin(void)
|
||||
*p = '\0';
|
||||
if (!(items[i].text = strdup(buf)))
|
||||
die("cannot strdup %u bytes:", strlen(buf) + 1);
|
||||
#if MULTI_SELECT_PATCH
|
||||
items[i].id = i; /* for multiselect */
|
||||
#else
|
||||
items[i].out = 0;
|
||||
#endif // items[i].out = 0;
|
||||
#if HIGHPRIORITY_PATCH
|
||||
items[i].hp = arrayhas(hpitems, hplength, items[i].text);
|
||||
#endif // HIGHPRIORITY_PATCH
|
||||
@ -1359,7 +1388,7 @@ usage(void)
|
||||
#if INSTANT_PATCH
|
||||
"n"
|
||||
#endif // INSTANT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH && !MULTI_SELECT_PATCH
|
||||
"t"
|
||||
#endif // PRINTINPUTTEXT_PATCH
|
||||
#if PREFIXCOMPLETION_PATCH
|
||||
@ -1465,7 +1494,7 @@ main(int argc, char *argv[])
|
||||
} else if (!strcmp(argv[i], "-n")) { /* instant select only match */
|
||||
instant = !instant;
|
||||
#endif // INSTANT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH
|
||||
#if PRINTINPUTTEXT_PATCH && !MULTI_SELECT_PATCH
|
||||
} else if (!strcmp(argv[i], "-t")) { /* favors text input over selection */
|
||||
use_text_input = 1;
|
||||
#endif // PRINTINPUTTEXT_PATCH
|
||||
|
@ -15,6 +15,9 @@
|
||||
#if HIGHPRIORITY_PATCH
|
||||
#include "highpriority.c"
|
||||
#endif
|
||||
#if MULTI_SELECT_PATCH
|
||||
#include "multiselect.c"
|
||||
#endif
|
||||
#if MOUSE_SUPPORT_PATCH
|
||||
#include "mousesupport.c"
|
||||
#endif
|
||||
|
@ -21,6 +21,16 @@ buttonpress(XEvent *e)
|
||||
/* left-click on input: clear input,
|
||||
* NOTE: if there is no left-arrow the space for < is reserved so
|
||||
* add that to the input width */
|
||||
#if SYMBOLS_PATCH
|
||||
if (ev->button == Button1 &&
|
||||
((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
|
||||
((!prev || !curr->left) ? TEXTW(symbol_1) : 0)) ||
|
||||
(lines > 0 && ev->y >= y && ev->y <= y + h))) {
|
||||
insert(NULL, -cursor);
|
||||
drawmenu();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (ev->button == Button1 &&
|
||||
((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
|
||||
((!prev || !curr->left) ? TEXTW("<") : 0)) ||
|
||||
@ -29,6 +39,7 @@ buttonpress(XEvent *e)
|
||||
drawmenu();
|
||||
return;
|
||||
}
|
||||
#endif // SYMBOLS_PATCH
|
||||
/* middle-mouse click: paste selection */
|
||||
if (ev->button == Button2) {
|
||||
XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
|
||||
@ -60,12 +71,24 @@ buttonpress(XEvent *e)
|
||||
for (item = curr; item != next; item = item->right) {
|
||||
y += h;
|
||||
if (ev->y >= y && ev->y <= (y + h)) {
|
||||
#if !MULTI_SELECT_PATCH
|
||||
puts(item->text);
|
||||
if (!(ev->state & ControlMask))
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
if (!(ev->state & ControlMask)) {
|
||||
#if MULTI_SELECT_PATCH
|
||||
sel = item;
|
||||
selsel();
|
||||
printsel(ev->state);
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
exit(0);
|
||||
}
|
||||
sel = item;
|
||||
if (sel) {
|
||||
#if MULTI_SELECT_PATCH
|
||||
selsel();
|
||||
#else
|
||||
sel->out = 1;
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
drawmenu();
|
||||
}
|
||||
return;
|
||||
@ -74,7 +97,11 @@ buttonpress(XEvent *e)
|
||||
} else if (matches) {
|
||||
/* left-click on left arrow */
|
||||
x += inputw;
|
||||
#if SYMBOLS_PATCH
|
||||
w = TEXTW(symbol_1);
|
||||
#else
|
||||
w = TEXTW("<");
|
||||
#endif // SYMBOLS_PATCH
|
||||
if (prev && curr->left) {
|
||||
if (ev->x >= x && ev->x <= x + w) {
|
||||
sel = curr = prev;
|
||||
@ -86,21 +113,41 @@ buttonpress(XEvent *e)
|
||||
/* horizontal list: (ctrl)left-click on item */
|
||||
for (item = curr; item != next; item = item->right) {
|
||||
x += w;
|
||||
#if SYMBOLS_PATCH
|
||||
w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2));
|
||||
#else
|
||||
w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
|
||||
#endif // SYMBOLS_PATCH
|
||||
if (ev->x >= x && ev->x <= x + w) {
|
||||
#if !MULTI_SELECT_PATCH
|
||||
puts(item->text);
|
||||
if (!(ev->state & ControlMask))
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
if (!(ev->state & ControlMask)) {
|
||||
#if MULTI_SELECT_PATCH
|
||||
sel = item;
|
||||
selsel();
|
||||
printsel(ev->state);
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
exit(0);
|
||||
}
|
||||
sel = item;
|
||||
if (sel) {
|
||||
#if MULTI_SELECT_PATCH
|
||||
selsel();
|
||||
#else
|
||||
sel->out = 1;
|
||||
#endif // MULTI_SELECT_PATCH
|
||||
drawmenu();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* left-click on right arrow */
|
||||
#if SYMBOLS_PATCH
|
||||
w = TEXTW(symbol_2);
|
||||
#else
|
||||
w = TEXTW(">");
|
||||
#endif // SYMBOLS_PATCH
|
||||
x = mw - w;
|
||||
if (next && ev->x >= x && ev->x <= x + w) {
|
||||
sel = curr = next;
|
||||
|
@ -110,6 +110,18 @@
|
||||
*/
|
||||
#define MOUSE_SUPPORT_PATCH 0
|
||||
|
||||
/* Without this patch when you press Ctrl+Enter dmenu just outputs current item and it is not
|
||||
* possible to undo that.
|
||||
* With this patch dmenu will output all selected items only on exit. It is also possible to
|
||||
* deselect any selected item.
|
||||
* Also refer to the dmenu_run replacement on the below URL that supports multiple selections.
|
||||
*
|
||||
* This patch is not compatible with the printinputtext and pipeout patches.
|
||||
*
|
||||
* https://tools.suckless.org/dmenu/patches/multi-selection/
|
||||
*/
|
||||
#define MULTI_SELECT_PATCH 0
|
||||
|
||||
/* This patch provides dmenu the ability for history navigation similar to that of bash.
|
||||
* https://tools.suckless.org/dmenu/patches/navhistory/
|
||||
*/
|
||||
@ -160,6 +172,9 @@
|
||||
/* This patch allows the selected text to be piped back out with dmenu. This can be useful if you
|
||||
* want to display the output of a command on the screen.
|
||||
* Only text starting with the character '#' is piped out by default.
|
||||
*
|
||||
* This patch is not compatible with the multi-select patch.
|
||||
*
|
||||
* https://tools.suckless.org/dmenu/patches/pipeout/
|
||||
*/
|
||||
#define PIPEOUT_PATCH 0
|
||||
@ -177,6 +192,9 @@
|
||||
|
||||
/* This patch adds a flag (-t) which makes Return key to ignore selection and print the input
|
||||
* text to stdout. The flag basically swaps the functions of Return and Shift+Return hotkeys.
|
||||
*
|
||||
* This patch is not compatible with the multi-select patch.
|
||||
*
|
||||
* https://tools.suckless.org/dmenu/patches/printinputtext/
|
||||
*/
|
||||
#define PRINTINPUTTEXT_PATCH 0
|
||||
|
Loading…
x
Reference in New Issue
Block a user