dmenu-mousesupport-5.0.diff 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. diff --git a/dmenu.c b/dmenu.c
  2. index 65f25ce..dfa59db 100644
  3. --- a/dmenu.c
  4. +++ b/dmenu.c
  5. @@ -500,6 +500,119 @@ draw:
  6. drawmenu();
  7. }
  8. +static void
  9. +buttonpress(XEvent *e)
  10. +{
  11. + struct item *item;
  12. + XButtonPressedEvent *ev = &e->xbutton;
  13. + int x = 0, y = 0, h = bh, w;
  14. +
  15. + if (ev->window != win)
  16. + return;
  17. +
  18. + /* right-click: exit */
  19. + if (ev->button == Button3)
  20. + exit(1);
  21. +
  22. + if (prompt && *prompt)
  23. + x += promptw;
  24. +
  25. + /* input field */
  26. + w = (lines > 0 || !matches) ? mw - x : inputw;
  27. +
  28. + /* left-click on input: clear input,
  29. + * NOTE: if there is no left-arrow the space for < is reserved so
  30. + * add that to the input width */
  31. + if (ev->button == Button1 &&
  32. + ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
  33. + ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
  34. + (lines > 0 && ev->y >= y && ev->y <= y + h))) {
  35. + insert(NULL, -cursor);
  36. + drawmenu();
  37. + return;
  38. + }
  39. + /* middle-mouse click: paste selection */
  40. + if (ev->button == Button2) {
  41. + XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
  42. + utf8, utf8, win, CurrentTime);
  43. + drawmenu();
  44. + return;
  45. + }
  46. + /* scroll up */
  47. + if (ev->button == Button4 && prev) {
  48. + sel = curr = prev;
  49. + calcoffsets();
  50. + drawmenu();
  51. + return;
  52. + }
  53. + /* scroll down */
  54. + if (ev->button == Button5 && next) {
  55. + sel = curr = next;
  56. + calcoffsets();
  57. + drawmenu();
  58. + return;
  59. + }
  60. + if (ev->button != Button1)
  61. + return;
  62. + if (ev->state & ~ControlMask)
  63. + return;
  64. + if (lines > 0) {
  65. + /* vertical list: (ctrl)left-click on item */
  66. + w = mw - x;
  67. + for (item = curr; item != next; item = item->right) {
  68. + y += h;
  69. + if (ev->y >= y && ev->y <= (y + h)) {
  70. + puts(item->text);
  71. + if (!(ev->state & ControlMask))
  72. + exit(0);
  73. + sel = item;
  74. + if (sel) {
  75. + sel->out = 1;
  76. + drawmenu();
  77. + }
  78. + return;
  79. + }
  80. + }
  81. + } else if (matches) {
  82. + /* left-click on left arrow */
  83. + x += inputw;
  84. + w = TEXTW("<");
  85. + if (prev && curr->left) {
  86. + if (ev->x >= x && ev->x <= x + w) {
  87. + sel = curr = prev;
  88. + calcoffsets();
  89. + drawmenu();
  90. + return;
  91. + }
  92. + }
  93. + /* horizontal list: (ctrl)left-click on item */
  94. + for (item = curr; item != next; item = item->right) {
  95. + x += w;
  96. + w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
  97. + if (ev->x >= x && ev->x <= x + w) {
  98. + puts(item->text);
  99. + if (!(ev->state & ControlMask))
  100. + exit(0);
  101. + sel = item;
  102. + if (sel) {
  103. + sel->out = 1;
  104. + drawmenu();
  105. + }
  106. + return;
  107. + }
  108. + }
  109. + /* left-click on right arrow */
  110. + w = TEXTW(">");
  111. + x = mw - w;
  112. + if (next && ev->x >= x && ev->x <= x + w) {
  113. + sel = curr = next;
  114. + calcoffsets();
  115. + drawmenu();
  116. + return;
  117. + }
  118. + }
  119. +}
  120. +
  121. static void
  122. paste(void)
  123. {
  124. @@ -561,6 +674,9 @@ run(void)
  125. break;
  126. cleanup();
  127. exit(1);
  128. + case ButtonPress:
  129. + buttonpress(&ev);
  130. + break;
  131. case Expose:
  132. if (ev.xexpose.count == 0)
  133. drw_map(drw, win, 0, 0, mw, mh);
  134. @@ -658,7 +774,8 @@ setup(void)
  135. /* create menu window */
  136. swa.override_redirect = True;
  137. swa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
  138. - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
  139. + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
  140. + ButtonPressMask;
  141. win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0,
  142. CopyFromParent, CopyFromParent, CopyFromParent,
  143. CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);