Another copy of my dotfiles. Because I don't completely trust GitHub.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.7 KiB

4 years ago
  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. static char text[BUFSIZ] = "";
  14. @@ -45,6 +46,9 @@ static struct item *matches, *matchend;
  15. static struct item *prev, *curr, *next, *sel;
  16. static int mon = -1, screen;
  17. +static int *selid = NULL;
  18. +static unsigned int selidsize = 0;
  19. +
  20. static Atom clip, utf8;
  21. static Display *dpy;
  22. static Window root, parentwin, win;
  23. @@ -58,6 +62,15 @@ static Clr *scheme[SchemeLast];
  24. static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
  25. static char *(*fstrstr)(const char *, const char *) = strstr;
  26. +static int
  27. +issel(size_t id)
  28. +{
  29. + for (int i = 0;i < selidsize;i++)
  30. + if (selid[i] == id)
  31. + return 1;
  32. + return 0;
  33. +}
  34. +
  35. static void
  36. appenditem(struct item *item, struct item **list, struct item **last)
  37. {
  38. @@ -100,6 +113,7 @@ cleanup(void)
  39. drw_free(drw);
  40. XSync(dpy, False);
  41. XCloseDisplay(dpy);
  42. + free(selid);
  43. }
  44. static char *
  45. @@ -118,7 +132,7 @@ drawitem(struct item *item, int x, int y, int w)
  46. {
  47. if (item == sel)
  48. drw_setscheme(drw, scheme[SchemeSel]);
  49. - else if (item->out)
  50. + else if (issel(item->id))
  51. drw_setscheme(drw, scheme[SchemeOut]);
  52. else
  53. drw_setscheme(drw, scheme[SchemeNorm]);
  54. @@ -367,6 +381,20 @@ keypress(XKeyEvent *ev)
  55. goto draw;
  56. case XK_Return:
  57. case XK_KP_Enter:
  58. + if (sel && issel(sel->id)) {
  59. + for (int i = 0;i < selidsize;i++)
  60. + if (selid[i] == sel->id)
  61. + selid[i] = -1;
  62. + } else {
  63. + for (int i = 0;i < selidsize;i++)
  64. + if (selid[i] == -1) {
  65. + selid[i] = sel->id;
  66. + return;
  67. + }
  68. + selidsize++;
  69. + selid = realloc(selid, (selidsize + 1) * sizeof(int));
  70. + selid[selidsize - 1] = sel->id;
  71. + }
  72. break;
  73. case XK_bracketleft:
  74. cleanup();
  75. @@ -464,13 +492,17 @@ insert:
  76. break;
  77. case XK_Return:
  78. case XK_KP_Enter:
  79. - puts((sel && !(ev->state & ShiftMask)) ? sel->text : text);
  80. if (!(ev->state & ControlMask)) {
  81. + for (int i = 0;i < selidsize;i++)
  82. + if (selid[i] != -1 && (!sel || sel->id != selid[i]))
  83. + puts(items[selid[i]].text);
  84. + if (sel && !(ev->state & ShiftMask))
  85. + puts(sel->text);
  86. + else
  87. + puts(text);
  88. cleanup();
  89. exit(0);
  90. }
  91. - if (sel)
  92. - sel->out = 1;
  93. break;
  94. case XK_Right:
  95. if (text[cursor] != '\0') {
  96. @@ -534,7 +566,7 @@ readstdin(void)
  97. *p = '\0';
  98. if (!(items[i].text = strdup(buf)))
  99. die("cannot strdup %u bytes:", strlen(buf) + 1);
  100. - items[i].out = 0;
  101. + items[i].id = i; /* for multiselect */
  102. drw_font_getexts(drw->fonts, buf, strlen(buf), &tmpmax, NULL);
  103. if (tmpmax > inputw) {
  104. inputw = tmpmax;