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