add support for mouse scrolling (#26)

This commit is contained in:
phillbush 2021-02-13 20:36:55 -03:00
parent 88341d204b
commit 60ddf397e3
3 changed files with 66 additions and 29 deletions

View File

@ -190,7 +190,6 @@ or
.BR "\(dqright\(dq" , .BR "\(dqright\(dq" ,
text is aligned to the left, center, or right of the menu, respectively. text is aligned to the left, center, or right of the menu, respectively.
By default, text is aligned to the left. By default, text is aligned to the left.
.SH EXAMPLES .SH EXAMPLES
The following script illustrates the use of The following script illustrates the use of
.BR xmenu . .BR xmenu .

93
xmenu.c
View File

@ -1129,17 +1129,37 @@ itemcycle(struct Menu *currmenu, int direction)
return item; return item;
} }
/* check if button is used to scroll */
static int
isscrollbutton(unsigned int button)
{
if (button == Button4 || button == Button5)
return 1;
return 0;
}
/* check if button is used to open a item on click */ /* check if button is used to open a item on click */
static int static int
isclickbutton(unsigned int button) isclickbutton(unsigned int button)
{ {
if (button == Button1) if (button == Button1 || button == Button2)
return 1; return 1;
if (!rflag && button == Button3) if (!rflag && button == Button3)
return 1; return 1;
return 0; return 0;
} }
/* warp pointer to center of selected item */
static void
warppointer(struct Menu *menu, struct Item *item)
{
if (menu == NULL || item == NULL)
return;
if (menu->selected) {
XWarpPointer(dpy, None, menu->win, 0, 0, 0, 0, menu->w / 2, item->y + item->h / 2);
}
}
/* append buf into text */ /* append buf into text */
static int static int
append(char *text, char *buf, size_t textsize, size_t buflen) append(char *text, char *buf, size_t textsize, size_t buflen)
@ -1240,6 +1260,7 @@ run(struct Menu *currmenu)
KeySym ksym; KeySym ksym;
Status status; Status status;
XEvent ev; XEvent ev;
int warped = 0;
int action; int action;
int len; int len;
int i; int i;
@ -1256,38 +1277,50 @@ run(struct Menu *currmenu)
action = ACTION_DRAW; action = ACTION_DRAW;
break; break;
case MotionNotify: case MotionNotify:
menu = getmenu(currmenu, ev.xbutton.window); if (!warped) {
item = getitem(menu, ev.xbutton.y); menu = getmenu(currmenu, ev.xbutton.window);
if (menu == NULL || item == NULL || previtem == item) item = getitem(menu, ev.xbutton.y);
break; if (menu == NULL || item == NULL || previtem == item)
previtem = item; break;
select = menu->selected = item; previtem = item;
if (item->submenu != NULL) { select = menu->selected = item;
currmenu = item->submenu; if (item->submenu != NULL) {
select = NULL; currmenu = item->submenu;
} else { select = NULL;
currmenu = menu; } else {
currmenu = menu;
}
action = ACTION_CLEAR | ACTION_SELECT | ACTION_MAP | ACTION_DRAW;
} }
action = ACTION_CLEAR | ACTION_SELECT | ACTION_MAP | ACTION_DRAW; warped = 0;
break; break;
case ButtonRelease: case ButtonRelease:
if (!isclickbutton(ev.xbutton.button)) if (isscrollbutton(ev.xbutton.button)) {
break; if (ev.xbutton.button == Button4)
menu = getmenu(currmenu, ev.xbutton.window); select = itemcycle(currmenu, ITEMPREV);
item = getitem(menu, ev.xbutton.y); else
if (menu == NULL || item == NULL) select = itemcycle(currmenu, ITEMNEXT);
break; action = ACTION_CLEAR | ACTION_SELECT | ACTION_DRAW | ACTION_WARP;
} else if (isclickbutton(ev.xbutton.button)) {
menu = getmenu(currmenu, ev.xbutton.window);
item = getitem(menu, ev.xbutton.y);
if (menu == NULL || item == NULL)
break;
enteritem: enteritem:
if (item->label == NULL) if (item->label == NULL)
break; /* ignore separators */ break; /* ignore separators */
if (item->submenu != NULL) { if (item->submenu != NULL) {
currmenu = item->submenu; currmenu = item->submenu;
} else { } else {
printf("%s\n", item->output); printf("%s\n", item->output);
return; return;
}
select = currmenu->list;
action = ACTION_CLEAR | ACTION_SELECT | ACTION_MAP | ACTION_DRAW;
if (ev.xbutton.button == Button2) {
action |= ACTION_WARP;
}
} }
select = currmenu->list;
action = ACTION_CLEAR | ACTION_SELECT | ACTION_MAP | ACTION_DRAW;
break; break;
case ButtonPress: case ButtonPress:
menu = getmenu(currmenu, ev.xbutton.window); menu = getmenu(currmenu, ev.xbutton.window);
@ -1419,6 +1452,10 @@ append:
mapmenu(currmenu); mapmenu(currmenu);
if (action & ACTION_DRAW) if (action & ACTION_DRAW)
drawmenus(currmenu); drawmenus(currmenu);
if (action & ACTION_WARP) {
warppointer(currmenu, select);
warped = 1;
}
} }
} }

View File

@ -6,6 +6,7 @@
#define ACTION_SELECT 1<<1 /* select item */ #define ACTION_SELECT 1<<1 /* select item */
#define ACTION_MAP 1<<2 /* remap menu windows */ #define ACTION_MAP 1<<2 /* remap menu windows */
#define ACTION_DRAW 1<<3 /* redraw menu windows */ #define ACTION_DRAW 1<<3 /* redraw menu windows */
#define ACTION_WARP 1<<4 /* warp the pointer */
/* enum for keyboard menu navigation */ /* enum for keyboard menu navigation */
enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST }; enum { ITEMPREV, ITEMNEXT, ITEMFIRST, ITEMLAST };