mousesupport.c (5502B)
1 void 2 buttonpress(XEvent *e) 3 { 4 struct item *item; 5 XButtonPressedEvent *ev = &e->xbutton; 6 int x = 0, y = 0, h = bh, w; 7 #if GRID_PATCH 8 int i, cols; 9 #endif // GRID_PATCH 10 11 if (ev->window != win) { 12 /* automatically close dmenu if the user clicks outside of dmenu, but 13 * ignore the scroll wheel and buttons above that */ 14 if (ev->button <= Button3) { 15 exit(1); 16 } 17 return; 18 } 19 20 /* right-click: exit */ 21 if (ev->button == Button3) 22 exit(1); 23 24 if (prompt && *prompt) 25 x += promptw; 26 27 /* input field */ 28 w = (lines > 0 || !matches) ? mw - x : inputw; 29 30 /* left-click on input: clear input, 31 * NOTE: if there is no left-arrow the space for < is reserved so 32 * add that to the input width */ 33 #if SYMBOLS_PATCH 34 if (ev->button == Button1 && 35 ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + 36 ((!prev || !curr->left) ? TEXTW(symbol_1) : 0)) || 37 (lines > 0 && ev->y >= y && ev->y <= y + h))) { 38 insert(NULL, -cursor); 39 drawmenu(); 40 return; 41 } 42 #else 43 if (ev->button == Button1 && 44 ((lines <= 0 && ev->x >= 0 && ev->x <= x + w + 45 ((!prev || !curr->left) ? TEXTW("<") : 0)) || 46 (lines > 0 && ev->y >= y && ev->y <= y + h))) { 47 insert(NULL, -cursor); 48 drawmenu(); 49 return; 50 } 51 #endif // SYMBOLS_PATCH 52 /* middle-mouse click: paste selection */ 53 if (ev->button == Button2) { 54 XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY, 55 utf8, utf8, win, CurrentTime); 56 drawmenu(); 57 return; 58 } 59 /* scroll up */ 60 if (ev->button == Button4 && prev) { 61 sel = curr = prev; 62 calcoffsets(); 63 drawmenu(); 64 return; 65 } 66 /* scroll down */ 67 if (ev->button == Button5 && next) { 68 sel = curr = next; 69 calcoffsets(); 70 drawmenu(); 71 return; 72 } 73 if (ev->button != Button1) 74 return; 75 if (ev->state & ShiftMask) 76 return; 77 if (lines > 0) { 78 #if GRID_PATCH 79 cols = columns ? columns : 1; 80 for (i = 0, item = curr; item != next; item = item->right, i++) { 81 if ( 82 (ev->y >= y + ((i % lines) + 1) * bh) && // line y start 83 (ev->y <= y + ((i % lines) + 2) * bh) && // line y end 84 (ev->x >= x + ((i / lines) * (w / cols))) && // column x start 85 (ev->x <= x + ((i / lines + 1) * (w / cols))) // column x end 86 ) { 87 clickitem(item, ev); 88 return; 89 } 90 } 91 #else 92 /* vertical list: (ctrl)left-click on item */ 93 for (item = curr; item != next; item = item->right) { 94 y += h; 95 if (ev->y >= y && ev->y <= (y + h)) { 96 clickitem(item, ev); 97 return; 98 } 99 } 100 #endif // GRID_PATCH 101 } else if (matches) { 102 /* left-click on left arrow */ 103 x += inputw; 104 #if SYMBOLS_PATCH 105 w = TEXTW(symbol_1); 106 #else 107 w = TEXTW("<"); 108 #endif // SYMBOLS_PATCH 109 if (prev && curr->left) { 110 if (ev->x >= x && ev->x <= x + w) { 111 sel = curr = prev; 112 calcoffsets(); 113 drawmenu(); 114 return; 115 } 116 } 117 /* horizontal list: (ctrl)left-click on item */ 118 for (item = curr; item != next; item = item->right) { 119 x += w; 120 #if SYMBOLS_PATCH 121 w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2)); 122 #else 123 w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); 124 #endif // SYMBOLS_PATCH 125 if (ev->x >= x && ev->x <= x + w) { 126 clickitem(item, ev); 127 return; 128 } 129 } 130 /* left-click on right arrow */ 131 #if SYMBOLS_PATCH 132 w = TEXTW(symbol_2); 133 #else 134 w = TEXTW(">"); 135 #endif // SYMBOLS_PATCH 136 x = mw - w; 137 if (next && ev->x >= x && ev->x <= x + w) { 138 sel = curr = next; 139 calcoffsets(); 140 drawmenu(); 141 return; 142 } 143 } 144 } 145 146 static void 147 clickitem(struct item *item, XButtonEvent *ev) 148 { 149 #if RESTRICT_RETURN_PATCH 150 if (restrict_return && (ev->state & (ShiftMask | ControlMask))) 151 return; 152 #endif // RESTRICT_RETURN_PATCH 153 154 #if !MULTI_SELECTION_PATCH 155 printitem(item); 156 #endif // MULTI_SELECTION_PATCH 157 158 sel = item; 159 if (!(ev->state & ControlMask)) { 160 #if MULTI_SELECTION_PATCH 161 printselected(ev->state); 162 #endif // MULTI_SELECTION_PATCH 163 cleanup(); 164 exit(0); 165 } 166 167 #if MULTI_SELECTION_PATCH 168 selsel(); 169 #else 170 sel->out = 1; 171 #endif // MULTI_SELECTION_PATCH 172 drawmenu(); 173 } 174 175 #if MOTION_SUPPORT_PATCH 176 void 177 motionevent(XButtonEvent *ev) 178 { 179 struct item *item; 180 int x = 0, y = 0, w; 181 #if GRID_PATCH 182 int i, cols; 183 #endif // GRID_PATCH 184 185 if (ev->window != win || matches == 0) 186 return; 187 188 if (prompt && *prompt) 189 x += promptw; 190 191 if (lines > 0) { 192 /* input field */ 193 w = mw - x; 194 #if GRID_PATCH 195 cols = columns ? columns : 1; 196 /* grid view or vertical list */ 197 for (i = 0, item = curr; item != next; item = item->right, i++) { 198 if ( 199 (ev->y >= y + ((i % lines) + 1) * bh) && // line y start 200 (ev->y <= y + ((i % lines) + 2) * bh) && // line y end 201 (ev->x >= x + ((i / lines) * (w / cols))) && // column x start 202 (ev->x <= x + ((i / lines + 1) * (w / cols))) // column x end 203 ) { 204 sel = item; 205 calcoffsets(); 206 drawmenu(); 207 break; 208 } 209 } 210 #else 211 /* vertical list */ 212 w = mw - x; 213 for (item = curr; item != next; item = item->right) { 214 y += bh; 215 if (ev->y >= y && ev->y <= (y + bh)) { 216 sel = item; 217 calcoffsets(); 218 drawmenu(); 219 break; 220 } 221 } 222 #endif // GRID_PATCH 223 return; 224 } 225 226 /* left-click on left arrow */ 227 x += inputw; 228 #if SYMBOLS_PATCH 229 w = TEXTW(symbol_1); 230 #else 231 w = TEXTW("<"); 232 #endif // SYMBOLS_PATCH 233 /* horizontal list */ 234 for (item = curr; item != next; item = item->right) { 235 x += w; 236 #if SYMBOLS_PATCH 237 w = MIN(TEXTW(item->text), mw - x - TEXTW(symbol_2)); 238 #else 239 w = MIN(TEXTW(item->text), mw - x - TEXTW(">")); 240 #endif // SYMBOLS_PATCH 241 if (ev->x >= x && ev->x <= x + w) { 242 sel = item; 243 calcoffsets(); 244 drawmenu(); 245 break; 246 } 247 } 248 } 249 #endif