sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

dmenu-mousesupport-4.6.diff (3771B)


      1 From 66df5f738c17ba5cf23ba99ce18313a39fdfd291 Mon Sep 17 00:00:00 2001
      2 From: Hiltjo Posthuma <hiltjo@codemadness.org>
      3 Date: Fri, 17 Jun 2016 14:44:16 +0200
      4 Subject: [PATCH] dmenu mouse support
      5 
      6 ---
      7  dmenu.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
      8  1 file changed, 118 insertions(+), 1 deletion(-)
      9 
     10 diff --git a/dmenu.c b/dmenu.c
     11 index a07f8e3..b60037f 100644
     12 --- a/dmenu.c
     13 +++ b/dmenu.c
     14 @@ -449,6 +449,119 @@ keypress(XKeyEvent *ev)
     15  }
     16  
     17  static void
     18 +buttonpress(XEvent *e)
     19 +{
     20 +	struct item *item;
     21 +	XButtonPressedEvent *ev = &e->xbutton;
     22 +	int x = 0, y = 0, h = bh, w;
     23 +
     24 +	if (ev->window != win)
     25 +		return;
     26 +
     27 +	/* right-click: exit */
     28 +	if (ev->button == Button3)
     29 +		exit(1);
     30 +
     31 +	if (prompt && *prompt)
     32 +		x += promptw;
     33 +
     34 +	/* input field */
     35 +	w = (lines > 0 || !matches) ? mw - x : inputw;
     36 +
     37 +	/* left-click on input: clear input,
     38 +	 * NOTE: if there is no left-arrow the space for < is reserved so
     39 +	 *       add that to the input width */
     40 +	if (ev->button == Button1 &&
     41 +	   ((lines <= 0 && ev->x >= 0 && ev->x <= x + w +
     42 +	   ((!prev || !curr->left) ? TEXTW("<") : 0)) ||
     43 +	   (lines > 0 && ev->y >= y && ev->y <= y + h))) {
     44 +		insert(NULL, -cursor);
     45 +		drawmenu();
     46 +		return;
     47 +	}
     48 +	/* middle-mouse click: paste selection */
     49 +	if (ev->button == Button2) {
     50 +		XConvertSelection(dpy, (ev->state & ShiftMask) ? clip : XA_PRIMARY,
     51 +		                  utf8, utf8, win, CurrentTime);
     52 +		drawmenu();
     53 +		return;
     54 +	}
     55 +	/* scroll up */
     56 +	if (ev->button == Button4 && prev) {
     57 +		sel = curr = prev;
     58 +		calcoffsets();
     59 +		drawmenu();
     60 +		return;
     61 +	}
     62 +	/* scroll down */
     63 +	if (ev->button == Button5 && next) {
     64 +		sel = curr = next;
     65 +		calcoffsets();
     66 +		drawmenu();
     67 +		return;
     68 +	}
     69 +	if (ev->button != Button1)
     70 +		return;
     71 +	if (ev->state & ~ControlMask)
     72 +		return;
     73 +	if (lines > 0) {
     74 +		/* vertical list: (ctrl)left-click on item */
     75 +		w = mw - x;
     76 +		for (item = curr; item != next; item = item->right) {
     77 +			y += h;
     78 +			if (ev->y >= y && ev->y <= (y + h)) {
     79 +				puts(item->text);
     80 +				if (!(ev->state & ControlMask))
     81 +					exit(0);
     82 +				sel = item;
     83 +				if (sel) {
     84 +					sel->out = 1;
     85 +					drawmenu();
     86 +				}
     87 +				return;
     88 +			}
     89 +		}
     90 +	} else if (matches) {
     91 +		/* left-click on left arrow */
     92 +		x += inputw;
     93 +		w = TEXTW("<");
     94 +		if (prev && curr->left) {
     95 +			if (ev->x >= x && ev->x <= x + w) {
     96 +				sel = curr = prev;
     97 +				calcoffsets();
     98 +				drawmenu();
     99 +				return;
    100 +			}
    101 +		}
    102 +		/* horizontal list: (ctrl)left-click on item */
    103 +		for (item = curr; item != next; item = item->right) {
    104 +			x += w;
    105 +			w = MIN(TEXTW(item->text), mw - x - TEXTW(">"));
    106 +			if (ev->x >= x && ev->x <= x + w) {
    107 +				puts(item->text);
    108 +				if (!(ev->state & ControlMask))
    109 +					exit(0);
    110 +				sel = item;
    111 +				if (sel) {
    112 +					sel->out = 1;
    113 +					drawmenu();
    114 +				}
    115 +				return;
    116 +			}
    117 +		}
    118 +		/* left-click on right arrow */
    119 +		w = TEXTW(">");
    120 +		x = mw - w;
    121 +		if (next && ev->x >= x && ev->x <= x + w) {
    122 +			sel = curr = next;
    123 +			calcoffsets();
    124 +			drawmenu();
    125 +			return;
    126 +		}
    127 +	}
    128 +}
    129 +
    130 +static void
    131  paste(void)
    132  {
    133  	char *p, *q;
    134 @@ -498,6 +611,9 @@ run(void)
    135  		if (XFilterEvent(&ev, win))
    136  			continue;
    137  		switch(ev.type) {
    138 +		case ButtonPress:
    139 +			buttonpress(&ev);
    140 +			break;
    141  		case Expose:
    142  			if (ev.xexpose.count == 0)
    143  				drw_map(drw, win, 0, 0, mw, mh);
    144 @@ -589,7 +705,8 @@ setup(void)
    145  	/* create menu window */
    146  	swa.override_redirect = True;
    147  	swa.background_pixel = scheme[SchemeNorm].bg->pix;
    148 -	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask;
    149 +	swa.event_mask = ExposureMask | KeyPressMask | VisibilityChangeMask |
    150 +	                 ButtonPressMask;
    151  	win = XCreateWindow(dpy, root, x, y, mw, mh, 0,
    152  	                    DefaultDepth(dpy, screen), CopyFromParent,
    153  	                    DefaultVisual(dpy, screen),
    154 -- 
    155 2.8.4
    156