~proycon/sxmo-dmenu

65b3a6894450025d43f24aeaa7928b0ae36b9a6f — tetrakist 4 months ago cd84c75
Add slide-touch-based page up/down and home/end.

Signed-off-by: Anjandev Momi <anjan@momi.ca>
2 files changed, 72 insertions(+), 6 deletions(-)

M config.def.h
M dmenu.c
M config.def.h => config.def.h +3 -0
@@ 32,3 32,6 @@ static const unsigned int border_width = 5;

/* Whether to wrap around to the top and bottom of the menu */
static int wrap_around = 0;

/* height of each scroll region above and below the menu, in units of menu items */
static int scrollregion = 4;

M dmenu.c => dmenu.c +69 -6
@@ 47,7 47,7 @@ static int lrpad; /* sum of left and right padding */
static size_t cursor;
static struct item *items = NULL;
static struct item *matches, *matchend;
static struct item *prev, *curr, *next, *sel;
static struct item *prev, *curr, *next, *sel, *nav;
static int mon = -1, screen;
static int use_text_input = 0;
static int initialindex;


@@ 621,7 621,10 @@ motionnotify(XEvent *e)
{
	struct item *item;
	XMotionEvent *ev = &e->xmotion;
	int x = 0, y = 0, h = bh, w;
	int y = 0, h = bh;
        char *pageup = "Page up",  *pagedown = "Page down";
        char *gotop = "Go to top",  *gobottom = "Go to bottom";
        char *alreadytop = "Already at top",  *alreadybottom = "Already at bottom";

	if (ev->window != win){
		return;


@@ 632,7 635,6 @@ motionnotify(XEvent *e)

	if (lines > 0) {
		/* vertical list: (ctrl)left-click on item */
		w = mw - x;
		for (item = curr; item != next; item = item->right) {
			y += h;
			if (ev->y >= y && ev->y <= (y + h)) {


@@ 641,6 643,34 @@ motionnotify(XEvent *e)
				return;
			}
		}
		/* display page up/down or jump top/bottom as appropriate */
		if(ev->y > mh || ev->y < 0){ 
			if (ev->y >= (mh)  && ev->y <= (mh + bh*scrollregion )) {
				nav->text = next ? pagedown : alreadybottom;
				drw_setscheme(drw, scheme[SchemeSel]);
				y=mh-bh;
			} else if (ev->y >= (mh + bh*scrollregion ) && ev->y < (mh + bh*scrollregion*2 )) {
				nav->text = next ? gobottom : alreadybottom;
				drw_setscheme(drw, scheme[SchemeSel]);
				y=mh-bh;
			} else if (ev->y >= (0 - h*scrollregion)  && ev->y <= (0)) {
				nav->text = curr != matches ? pageup : alreadytop;
				drw_setscheme(drw, scheme[SchemeSel]);
				y=0+bh;
			} else if (ev->y >= (0 - h*scrollregion*2) && ev->y <= (0 - h*scrollregion)) {
				nav->text = curr != matches ? gotop : alreadytop;
				drw_setscheme(drw, scheme[SchemeSel]);
				y=0+bh;
			} else {
				drawmenu();
				return;
			}
			drw_setscheme(drw, scheme[SchemeOut]);
			drw_text(drw, 0, y, mw, bh, lrpad / 2, nav->text, 0);
			drw_map(drw, win, 0, 0, mw, mh);
			XFlush(dpy);
			return;
		}
	}
	return;
}


@@ 684,20 714,48 @@ buttonpress(XEvent *e)
		drawmenu();
		return;
	}
	/* jump to top */
	if (ev->y >= (0 - h*scrollregion*2) && ev->y <= (0 - h*scrollregion)) {
		sel = curr = matches;
		calcoffsets();
		drawmenu();
		return;
	}
	/* scroll up */
	if (ev->button == Button4 && prev) {
	if (    (ev->button == Button4 && prev)
	     || (ev->y >= (0 - h*scrollregion)  && ev->y <= (0))
			) {
		sel = curr = prev;
		calcoffsets();
		drawmenu();
		return;
	}
	/* scroll down */
	if (ev->button == Button5 && next) {
		sel = curr = next;
	if (    (ev->button == Button5 && next)
	     || (ev->y >= (mh)  && ev->y <= (mh + bh*scrollregion ))
	) {
		if(next)
			sel = curr = next;
		calcoffsets();
		drawmenu();
		return;
	}
	/* jump to bottom */
	if (ev->y >= (mh + bh*scrollregion ) && ev->y < (mh + bh*scrollregion*2 )) {
		if (next) {
			/* jump to end of list and position items in reverse */
			curr = matchend;
			calcoffsets();
			curr = prev;
			calcoffsets();
			while (next && (curr = curr->right))
				calcoffsets();
		}
		sel = matchend;
		drawmenu();
		return;
	}

	if (ev->button != Button1)
		return;
	if (ev->state & ~ControlMask & ~Button1Mask)


@@ 990,6 1048,11 @@ setup(void)
		}
	}
	drawmenu();

	if (!(nav = malloc(sizeof *nav)))
		die("cannot malloc %u bytes:", sizeof *nav);
	nav->out = 1;

}

static void