dwm-torus-20240901-5687f46.diff - sites - public wiki contents of suckless.org | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
dwm-torus-20240901-5687f46.diff (7358B) | |
--- | |
1 From bdd2dcfc0d33b894c4bddb00008f33abcd3478a5 Mon Sep 17 00:00:00 2001 | |
2 From: Elizabeth Hunt <[email protected]> | |
3 Date: Sun, 1 Sep 2024 14:37:36 -0700 | |
4 Subject: [PATCH] wrap the cursor around the monitor(s) like a torus! | |
5 | |
6 --- | |
7 config.def.h | 3 ++ | |
8 config.mk | 8 +++- | |
9 dwm.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++- | |
10 3 files changed, 128 insertions(+), 3 deletions(-) | |
11 | |
12 diff --git a/config.def.h b/config.def.h | |
13 index 9efa774..8251624 100644 | |
14 --- a/config.def.h | |
15 +++ b/config.def.h | |
16 @@ -114,3 +114,6 @@ static const Button buttons[] = { | |
17 { ClkTagBar, MODKEY, Button3, togglet… | |
18 }; | |
19 | |
20 +/* torus config */ | |
21 +static int torusenabled = 1; | |
22 +static int wormholedelta = 1; // how close to the edge do we get before… | |
23 diff --git a/config.mk b/config.mk | |
24 index 8efca9a..5f7634f 100644 | |
25 --- a/config.mk | |
26 +++ b/config.mk | |
27 @@ -14,6 +14,10 @@ X11LIB = /usr/X11R6/lib | |
28 XINERAMALIBS = -lXinerama | |
29 XINERAMAFLAGS = -DXINERAMA | |
30 | |
31 +# Xinput extensions, comment if you don't want it | |
32 +XINPUTLIBS = -lXi | |
33 +XINPUTFLAGS = -DXINPUT | |
34 + | |
35 # freetype | |
36 FREETYPELIBS = -lfontconfig -lXft | |
37 FREETYPEINC = /usr/include/freetype2 | |
38 @@ -23,10 +27,10 @@ FREETYPEINC = /usr/include/freetype2 | |
39 | |
40 # includes and libs | |
41 INCS = -I${X11INC} -I${FREETYPEINC} | |
42 -LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} | |
43 +LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS} ${XINPUTLIBS} | |
44 | |
45 # flags | |
46 -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSI… | |
47 +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSI… | |
48 #CFLAGS = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS} | |
49 CFLAGS = -std=c99 -pedantic -Wall -Wno-deprecated-declarations -Os ${… | |
50 LDFLAGS = ${LIBS} | |
51 diff --git a/dwm.c b/dwm.c | |
52 index 67c6b2b..392496e 100644 | |
53 --- a/dwm.c | |
54 +++ b/dwm.c | |
55 @@ -39,6 +39,9 @@ | |
56 #ifdef XINERAMA | |
57 #include <X11/extensions/Xinerama.h> | |
58 #endif /* XINERAMA */ | |
59 +#ifdef XINPUT | |
60 +#include <X11/extensions/XInput2.h> | |
61 +#endif /* XINPUT */ | |
62 #include <X11/Xft/Xft.h> | |
63 | |
64 #include "drw.h" | |
65 @@ -183,12 +186,16 @@ static void mappingnotify(XEvent *e); | |
66 static void maprequest(XEvent *e); | |
67 static void monocle(Monitor *m); | |
68 static void motionnotify(XEvent *e); | |
69 +static void rawmotionnotify(XEvent *e); | |
70 +static void genericeventnotify(XEvent *e); | |
71 static void movemouse(const Arg *arg); | |
72 static Client *nexttiled(Client *c); | |
73 static void pop(Client *c); | |
74 static void propertynotify(XEvent *e); | |
75 static void quit(const Arg *arg); | |
76 static Monitor *recttomon(int x, int y, int w, int h); | |
77 +static Monitor *raycastx(Monitor *src, int y, int dx); | |
78 +static Monitor *raycasty(Monitor *src, int x, int dy); | |
79 static void resize(Client *c, int x, int y, int w, int h, int interact); | |
80 static void resizeclient(Client *c, int x, int y, int w, int h); | |
81 static void resizemouse(const Arg *arg); | |
82 @@ -242,6 +249,9 @@ static int sw, sh; /* X display screen geo… | |
83 static int bh; /* bar height */ | |
84 static int lrpad; /* sum of left and right padding for text … | |
85 static int (*xerrorxlib)(Display *, XErrorEvent *); | |
86 +#ifdef XINPUT | |
87 +static int xinputextensionop; | |
88 +#endif /* XINPUT */ | |
89 static unsigned int numlockmask = 0; | |
90 static void (*handler[LASTEvent]) (XEvent *) = { | |
91 [ButtonPress] = buttonpress, | |
92 @@ -257,7 +267,8 @@ static void (*handler[LASTEvent]) (XEvent *) = { | |
93 [MapRequest] = maprequest, | |
94 [MotionNotify] = motionnotify, | |
95 [PropertyNotify] = propertynotify, | |
96 - [UnmapNotify] = unmapnotify | |
97 + [UnmapNotify] = unmapnotify, | |
98 + [GenericEvent] = genericeventnotify, | |
99 }; | |
100 static Atom wmatom[WMLast], netatom[NetLast]; | |
101 static int running = 1; | |
102 @@ -1142,6 +1153,58 @@ motionnotify(XEvent *e) | |
103 mon = m; | |
104 } | |
105 | |
106 +void | |
107 +genericeventnotify(XEvent *e) | |
108 +{ | |
109 + if (e->xcookie.extension == xinputextensionop && | |
110 + e->xcookie.evtype == XI_RawMotion) { | |
111 + rawmotionnotify(e); | |
112 + } | |
113 +} | |
114 + | |
115 +void | |
116 +rawmotionnotify(XEvent *e) | |
117 +{ | |
118 + if (torusenabled == 0) return; | |
119 + | |
120 + int x, y; | |
121 + if (!getrootptr(&x, &y)) return; | |
122 + | |
123 + int warpx = x; | |
124 + int warpy = y; | |
125 + if (BETWEEN(x, selmon->mx, selmon->mx + wormholedelta)) { | |
126 + /* ensure there's no monitor to the left */ | |
127 + if (recttomon(selmon->mx - 1, y, 1, 1) != selmon) | |
128 + return; | |
129 + /* take the wormhole */ | |
130 + Monitor *farright = raycastx(selmon, y, 1); | |
131 + warpx = farright->mx + farright->mw - wormholedelta - 1; | |
132 + } else if (BETWEEN(x, selmon->mx + selmon->mw - wormholedelta, | |
133 + selmon->mx + selmon->mw)) { | |
134 + /* ensure there's no monitor to the right */ | |
135 + if (recttomon(selmon->mx + selmon->mw + 1, y, 1, 1) != … | |
136 + return; | |
137 + Monitor *farleft = raycastx(selmon, y, -1); | |
138 + warpx = farleft->mx + wormholedelta + 1; | |
139 + } else if (BETWEEN(y, selmon->my, selmon->my + wormholedelta)) { | |
140 + /* ensure there's no monitor under us */ | |
141 + if (recttomon(x, y, selmon->my - 1, 1) != selmon) | |
142 + return; | |
143 + Monitor *farup = raycasty(selmon, x, 1); | |
144 + warpy = farup->my + farup->mh - wormholedelta - 1; | |
145 + } else if (BETWEEN(y, selmon->my + selmon->mh - wormholedelta, | |
146 + selmon->my + selmon->mh)) { | |
147 + /* ensure there's no monitor above us */ | |
148 + if (recttomon(x, y, selmon->my + selmon->mh + 1, 1) != … | |
149 + return; | |
150 + Monitor *fardown = raycasty(selmon, x, -1); | |
151 + warpy = fardown->my + wormholedelta + 1; | |
152 + } | |
153 + | |
154 + if (warpx != x || warpy != y) | |
155 + XWarpPointer(dpy, None, root, 0, 0, 0, 0, warpx, warpy); | |
156 +} | |
157 + | |
158 void | |
159 movemouse(const Arg *arg) | |
160 { | |
161 @@ -1275,6 +1338,44 @@ recttomon(int x, int y, int w, int h) | |
162 return r; | |
163 } | |
164 | |
165 +Monitor * | |
166 +raycastx(Monitor *src, int y, int dx) | |
167 +{ | |
168 + Monitor *farthest = src; | |
169 + for (Monitor *m = mons; m; m = m->next) { | |
170 + int scansy = BETWEEN(y, m->my, m->my + m->mh); | |
171 + if (!scansy) { | |
172 + continue; | |
173 + } | |
174 + if (dx == 1 && (m->mx + m->mw > farthest->mx + farthest… | |
175 + farthest = m; | |
176 + } | |
177 + if (dx == -1 && (m->mx < farthest->mx)) { | |
178 + farthest = m; | |
179 + } | |
180 + } | |
181 + return farthest; | |
182 +} | |
183 + | |
184 +Monitor * | |
185 +raycasty(Monitor *src, int x, int dy) | |
186 +{ | |
187 + Monitor *farthest = src; | |
188 + for (Monitor *m = mons; m; m = m->next) { | |
189 + int scansx = BETWEEN(x, m->mx, m->mx + m->mw); | |
190 + if (!scansx) { | |
191 + continue; | |
192 + } | |
193 + if (dy == 1 && (m->my + m->mh > farthest->my + farthest… | |
194 + farthest = m; | |
195 + } | |
196 + if (dy == -1 && (m->my < farthest->my)) { | |
197 + farthest = m; | |
198 + } | |
199 + } | |
200 + return farthest; | |
201 +} | |
202 + | |
203 void | |
204 resize(Client *c, int x, int y, int w, int h, int interact) | |
205 { | |
206 @@ -1609,6 +1710,23 @@ setup(void) | |
207 |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; | |
208 XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); | |
209 XSelectInput(dpy, root, wa.event_mask); | |
210 +#ifdef XINPUT | |
211 + /* select XInput raw motion events; we can't hook into PointerM… | |
212 + size_t maskbyteslen = XIMaskLen(XI_RawMotion); | |
213 + unsigned char *maskbytes = calloc(maskbyteslen, sizeof(unsigned… | |
214 + XISetMask(maskbytes, XI_RawMotion); | |
215 + XIEventMask mask; | |
216 + int _unused; | |
217 + if (!XQueryExtension(dpy, "XInputExtension", &xinputextensionop, | |
218 + &_unused, &_unused)) { | |
219 + fprintf(stderr, "XInputExtension not found"); | |
220 + exit(1); | |
221 + } | |
222 + mask.deviceid = XIAllMasterDevices; | |
223 + mask.mask_len = maskbyteslen * sizeof(unsigned char); | |
224 + mask.mask = maskbytes; | |
225 + XISelectEvents(dpy, root, &mask, 1); | |
226 +#endif /* XINPUT */ | |
227 grabkeys(); | |
228 focus(NULL); | |
229 } | |
230 -- | |
231 2.46.0 | |
232 |