dmenu

Kris's build of dmenu
git clone git clone https://git.krisyotam.com/krisyotam/dmenu.git
Log | Files | Refs | README | LICENSE

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