diff -up a/config.def.h b/config.def.h --- a/config.def.h 2023-01-13 15:14:16.536118429 +0100 +++ b/config.def.h 2023-01-13 15:21:25.946360539 +0100 @@ -78,6 +78,7 @@ static const Key keys[] = { { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, { MODKEY, XK_space, setlayout, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_g, gesture, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY, XK_comma, focusmon, {.i = -1 } }, @@ -107,9 +108,21 @@ static const Button buttons[] = { { ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, MODKEY|ShiftMask,Button3, gesture, {0} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, { ClkTagBar, MODKEY, Button1, tag, {0} }, { ClkTagBar, MODKEY, Button3, toggletag, {0} }, }; +/* gestures + * u means up + * d means down + * l means left + * r means right + * ud means up and down + */ +static Gesture gestures[] = { + { "u", spawn, {.v = termcmd } }, + { "d", spawn, {.v = dmenucmd } }, +}; diff -up a/dwm.c b/dwm.c --- a/dwm.c 2023-01-13 15:14:16.536118429 +0100 +++ b/dwm.c 2023-01-13 15:14:41.094075080 +0100 @@ -75,6 +75,12 @@ typedef union { } Arg; typedef struct { + char *gname; + void (*func)(const Arg *arg); + const Arg arg; +} Gesture; + +typedef struct { unsigned int click; unsigned int mask; unsigned int button; @@ -183,6 +189,7 @@ static void mappingnotify(XEvent *e); static void maprequest(XEvent *e); static void monocle(Monitor *m); static void motionnotify(XEvent *e); +static void gesture(const Arg *arg); static void movemouse(const Arg *arg); static Client *nexttiled(Client *c); static void pop(Client *c); @@ -1134,6 +1141,68 @@ motionnotify(XEvent *e) } void +gesture(const Arg *arg) { + int x, y, dx, dy, q; + int valid=0, listpos=0, gestpos=0, count=0; + char move, currGest[10]; + XEvent ev; + + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, + None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + if(!getrootptr(&x, &y)) + return; + do { + XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); + switch (ev.type) { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if(count++ < 10) + break; + count = 0; + dx = ev.xmotion.x - x; + dy = ev.xmotion.y - y; + x = ev.xmotion.x; + y = ev.xmotion.y; + + if( abs(dx)/(abs(dy)+1) == 0 ) + move = dy<0?'u':'d'; + else + move = dx<0?'l':'r'; + + if(move!=currGest[gestpos-1]) + { + if(gestpos>9) + { ev.type++; + break; + } + + currGest[gestpos] = move; + currGest[++gestpos] = '\0'; + + valid = 0; + for(q = 0; q