dmenu-mousesupportwithgrid-5.0.diff (3584B)
1 diff --git a/dmenu.c b/dmenu.c 2 index 76acee6..3588890 100644 3 --- a/dmenu.c 4 +++ b/dmenu.c 5 @@ -546,6 +546,125 @@ 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, item_num = 0; 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 + if (item_num++ == lines){ 70 + item_num = 1; 71 + x += w / columns; 72 + y = 0; 73 + } 74 + y += h; 75 + if (ev->y >= y && ev->y <= (y + h) && 76 + ev->x >= x && ev->x <= (x + w / columns)) { 77 + puts(item->text); 78 + if (!(ev->state & ControlMask)) 79 + exit(0); 80 + sel = item; 81 + if (sel) { 82 + sel->out = 1; 83 + drawmenu(); 84 + } 85 + return; 86 + } 87 + } 88 + } else if (matches) { 89 + /* left-click on left arrow */ 90 + x += inputw; 91 + w = TEXTW("<"); 92 + if (prev && curr->left) { 93 + if (ev->x >= x && ev->x <= x + w) { 94 + sel = curr = prev; 95 + calcoffsets(); 96 + drawmenu(); 97 + return; 98 + } 99 + } 100 + /* horizontal list: (ctrl)left-click on item */ 101 + for (item = curr; item != next; item = item->right) { 102 + x += w; 103 + w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); 104 + if (ev->x >= x && ev->x <= x + w) { 105 + puts(item->text); 106 + if (!(ev->state & ControlMask)) 107 + exit(0); 108 + sel = item; 109 + if (sel) { 110 + sel->out = 1; 111 + drawmenu(); 112 + } 113 + return; 114 + } 115 + } 116 + /* left-click on right arrow */ 117 + w = TEXTW(">"); 118 + x = mw - w; 119 + if (next && ev->x >= x && ev->x <= x + w) { 120 + sel = curr = next; 121 + calcoffsets(); 122 + drawmenu(); 123 + return; 124 + } 125 + } 126 +} 127 + 128 static void 129 paste(void) 130 { 131 @@ -607,6 +726,9 @@ run(void) 132 break; 133 cleanup(); 134 exit(1); 135 + case ButtonPress: 136 + buttonpress(&ev); 137 + break; 138 case Expose: 139 if (ev.xexpose.count == 0) 140 drw_map(drw, win, 0, 0, mw, mh); 141 @@ -704,7 +826,8 @@ setup(void) 142 /* create menu window */ 143 swa.override_redirect = True; 144 swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; 145 - swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask; 146 + swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask | 147 + ButtonPressMask; 148 win = XCreateWindow(dpy, parentwin, x, y, mw, mh, 0, 149 CopyFromParent, CopyFromParent, CopyFromParent, 150 CWOverrideRedirect | CWBackPixel | CWEventMask, &swa);