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;