1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
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<LENGTH(gestures); q++)
+ { if(!strcmp(currGest, gestures[q].gname))
+ { valid++;
+ listpos = q;
+ }
+ }
+ }
+
+ }
+ } while(ev.type != ButtonRelease);
+
+ if(valid)
+ gestures[listpos].func(&(gestures[listpos].arg));
+
+ XUngrabPointer(dpy, CurrentTime);
+}
+
+void
movemouse(const Arg *arg)
{
int x, y, ocx, ocy, nx, ny;
|