| Hash | Commit message | Author | Date | Files | + | - |
1 | commit 212e027e2a9169d075c5a21ca02ebca46154263b |
2 | Author: Connor Etherington <[email protected]> |
3 | Date: Thu Apr 11 22:28:06 2024 +0200 |
4 | |
5 | Auto-Commit Update 11.04.2024 - 22:28:06 |
6 | --- |
7 | etc/skel/.config/AutoLinux-DWM | 1 - |
8 | etc/skel/.config/AutoLinux-DWM/AutoLinux | Bin 0 -> 135824 bytes |
9 | etc/skel/.config/AutoLinux-DWM/AutoLinux.c | 2961 ++++++++++++++++++++ |
10 | etc/skel/.config/AutoLinux-DWM/AutoLinux.desktop | 6 + |
11 | etc/skel/.config/AutoLinux-DWM/AutoLinux.o | Bin 0 -> 132152 bytes |
12 | etc/skel/.config/AutoLinux-DWM/LICENSE | 39 + |
13 | etc/skel/.config/AutoLinux-DWM/Makefile | 53 + |
14 | etc/skel/.config/AutoLinux-DWM/PKGBUILD | 29 + |
15 | etc/skel/.config/AutoLinux-DWM/autostart.sh | 10 + |
16 | etc/skel/.config/AutoLinux-DWM/config.h | 593 ++++ |
17 | etc/skel/.config/AutoLinux-DWM/config.mk | 39 + |
18 | etc/skel/.config/AutoLinux-DWM/definitions.h | 13 + |
19 | etc/skel/.config/AutoLinux-DWM/drw.c | 424 +++ |
20 | etc/skel/.config/AutoLinux-DWM/drw.h | 57 + |
21 | etc/skel/.config/AutoLinux-DWM/drw.o | Bin 0 -> 10320 bytes |
22 | .../icons/hicolor/1024x1024/apps/AutoLinux.png | Bin 0 -> 162233 bytes |
23 | .../icons/hicolor/128x128/apps/AutoLinux.png | Bin 0 -> 15015 bytes |
24 | .../icons/hicolor/16x16/apps/AutoLinux.png | Bin 0 -> 1125 bytes |
25 | .../icons/hicolor/192x192/apps/AutoLinux.png | Bin 0 -> 23356 bytes |
26 | .../icons/hicolor/22x22/apps/AutoLinux.png | Bin 0 -> 1708 bytes |
27 | .../icons/hicolor/24x24/apps/AutoLinux.png | Bin 0 -> 1907 bytes |
28 | .../icons/hicolor/256x256/apps/AutoLinux.png | Bin 0 -> 33215 bytes |
29 | .../icons/hicolor/32x32/apps/AutoLinux.png | Bin 0 -> 2758 bytes |
30 | .../icons/hicolor/36x36/apps/AutoLinux.png | Bin 0 -> 3094 bytes |
31 | .../icons/hicolor/48x48/apps/AutoLinux.png | Bin 0 -> 4686 bytes |
32 | .../icons/hicolor/512x512/apps/AutoLinux.png | Bin 0 -> 72652 bytes |
33 | .../icons/hicolor/64x64/apps/AutoLinux.png | Bin 0 -> 6575 bytes |
34 | .../icons/hicolor/72x72/apps/AutoLinux.png | Bin 0 -> 7702 bytes |
35 | .../icons/hicolor/96x96/apps/AutoLinux.png | Bin 0 -> 10787 bytes |
36 | .../icons/hicolor/scalable/apps/AutoLinux.svg | 1 + |
37 | .../hicolor/symbolic/apps/AutoLinux-symbolic.svg | 1 + |
38 | etc/skel/.config/AutoLinux-DWM/logo.png | Bin 0 -> 23356 bytes |
39 | .../.config/AutoLinux-DWM/patch/bar_ltsymbol.c | 18 + |
40 | .../.config/AutoLinux-DWM/patch/bar_ltsymbol.h | 3 + |
41 | etc/skel/.config/AutoLinux-DWM/patch/bar_status.c | 19 + |
42 | etc/skel/.config/AutoLinux-DWM/patch/bar_status.h | 3 + |
43 | etc/skel/.config/AutoLinux-DWM/patch/bar_tags.c | 57 + |
44 | etc/skel/.config/AutoLinux-DWM/patch/bar_tags.h | 3 + |
45 | .../.config/AutoLinux-DWM/patch/bar_wintitle.c | 31 + |
46 | .../.config/AutoLinux-DWM/patch/bar_wintitle.h | 3 + |
47 | .../.config/AutoLinux-DWM/patch/cust/bar_date.c | 43 + |
48 | .../.config/AutoLinux-DWM/patch/cust/bar_date.h | 3 + |
49 | .../AutoLinux-DWM/patch/cust/bar_datetime.c | 34 + |
50 | .../AutoLinux-DWM/patch/cust/bar_datetime.h | 2 + |
51 | .../.config/AutoLinux-DWM/patch/cust/bar_time.c | 49 + |
52 | .../.config/AutoLinux-DWM/patch/cust/bar_time.h | 4 + |
53 | etc/skel/.config/AutoLinux-DWM/patch/functions.c | 21 + |
54 | etc/skel/.config/AutoLinux-DWM/patch/functions.h | 0 |
55 | etc/skel/.config/AutoLinux-DWM/patch/include.c | 9 + |
56 | etc/skel/.config/AutoLinux-DWM/patch/include.h | 8 + |
57 | etc/skel/.config/AutoLinux-DWM/shiftview.c | 64 + |
58 | etc/skel/.config/AutoLinux-DWM/transient.c | 42 + |
59 | etc/skel/.config/AutoLinux-DWM/util.c | 35 + |
60 | etc/skel/.config/AutoLinux-DWM/util.h | 8 + |
61 | etc/skel/.config/AutoLinux-DWM/util.o | Bin 0 -> 2224 bytes |
62 | etc/skel/.config/AutoLinux-DWM/vanitygaps.c | 542 ++++ |
63 | 56 files changed, 5227 insertions(+), 1 deletion(-) |
64 | |
65 | diff --git a/etc/skel/.config/AutoLinux-DWM b/etc/skel/.config/AutoLinux-DWM |
66 | deleted file mode 160000 |
67 | index 5133170..0000000 |
68 | --- a/etc/skel/.config/AutoLinux-DWM |
69 | +++ /dev/null |
70 | @@ -1 +0,0 @@ |
71 | -Subproject commit 5133170fa052d8e406d8dd048f78453505e33192 |
72 | diff --git a/etc/skel/.config/AutoLinux-DWM/AutoLinux b/etc/skel/.config/AutoLinux-DWM/AutoLinux |
73 | new file mode 100755 |
74 | index 0000000..88cf44c |
75 | Binary files /dev/null and b/etc/skel/.config/AutoLinux-DWM/AutoLinux differ |
76 | diff --git a/etc/skel/.config/AutoLinux-DWM/AutoLinux.c b/etc/skel/.config/AutoLinux-DWM/AutoLinux.c |
77 | new file mode 100644 |
78 | index 0000000..9a1ddf2 |
79 | --- /dev/null |
80 | +++ b/etc/skel/.config/AutoLinux-DWM/AutoLinux.c |
81 | @@ -0,0 +1,2961 @@ |
82 | +/* See LICENSE file for copyright and license details. |
83 | + * |
84 | + * dynamic window manager is designed like any other X client as well. It is |
85 | + * driven through handling X events. In contrast to other X clients, a window |
86 | + * manager selects for SubstructureRedirectMask on the root window, to receive |
87 | + * events about window (dis-)appearance. Only one X connection at a time is |
88 | + * allowed to select for this event mask. |
89 | + * |
90 | + * The event handlers of AutoLinux are organized in an array which is accessed |
91 | + * whenever a new event has been fetched. This allows event dispatching |
92 | + * in O(1) time. |
93 | + * |
94 | + * Each child of the root window is called a client, except windows which have |
95 | + * set the override_redirect flag. Clients are organized in a linked client |
96 | + * list on each monitor, the focus history is remembered through a stack list |
97 | + * on each monitor. Each client contains a bit array to indicate the tags of a |
98 | + * client. |
99 | + * |
100 | + * Keys and tagging rules are organized as arrays and defined in config.h. |
101 | + * |
102 | + * To understand everything else, start reading main(). |
103 | + */ |
104 | +#include <errno.h> |
105 | +#include <locale.h> |
106 | +#include <signal.h> |
107 | +#include <stdarg.h> |
108 | +#include <stdio.h> |
109 | +#include <stdlib.h> |
110 | +#include <string.h> |
111 | +#include <unistd.h> |
112 | +#include <sys/types.h> |
113 | +#include <sys/wait.h> |
114 | +#include <X11/cursorfont.h> |
115 | +#include <X11/keysym.h> |
116 | +#include <X11/Xatom.h> |
117 | +#include <X11/Xlib.h> |
118 | +#include <X11/Xproto.h> |
119 | +#include <X11/Xutil.h> |
120 | +#include <X11/Xresource.h> |
121 | +#ifdef XINERAMA |
122 | +#include <X11/extensions/Xinerama.h> |
123 | +#endif /* XINERAMA */ |
124 | +#include <X11/Xft/Xft.h> |
125 | +#include <X11/Xlib-xcb.h> |
126 | +#include <xcb/res.h> |
127 | + |
128 | +#include "drw.h" |
129 | +#include "util.h" |
130 | + |
131 | +/* macros */ |
132 | +#define BARRULES 20 |
133 | +#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) |
134 | +#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) |
135 | +#define GETINC(X) ((X) - 2000) |
136 | +#define INC(X) ((X) + 2000) |
137 | +#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ |
138 | + * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) |
139 | +#define ISINC(X) ((X) > 1000 && (X) < 3000) |
140 | +#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]) || C->issticky) |
141 | +#define PREVSEL 3000 |
142 | +#define LENGTH(X) (sizeof X / sizeof X[0]) |
143 | +#define MOUSEMASK (BUTTONMASK|PointerMotionMask) |
144 | +#define MOD(N,M) ((N)%(M) < 0 ? (N)%(M) + (M) : (N)%(M)) |
145 | +#define WIDTH(X) ((X)->w + 2 * (X)->bw) |
146 | +#define HEIGHT(X) ((X)->h + 2 * (X)->bw) |
147 | +#define NUMTAGS (LENGTH(tags) + LENGTH(scratchpads)) |
148 | +#define TAGMASK ((1 << NUMTAGS) - 1) |
149 | +#define SPTAG(i) ((1 << LENGTH(tags)) << (i)) |
150 | +#define SPTAGMASK (((1 << LENGTH(scratchpads))-1) << LENGTH(tags)) |
151 | +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) |
152 | +#define TRUNC(X,A,B) (MAX((A), MIN((X), (B)))) |
153 | + |
154 | +/* enums */ |
155 | +enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ |
156 | +enum { SchemeNorm, SchemeSel, SchemeTime, SchemeActive, SchemeInactive }; /* color schemes */ |
157 | +enum { NetSupported, NetWMName, NetWMState, NetWMCheck, |
158 | + NetWMFullscreen, NetActiveWindow, NetWMWindowType, |
159 | + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ |
160 | +enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ |
161 | +enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, |
162 | + ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ |
163 | +enum { |
164 | + BAR_ALIGN_LEFT, |
165 | + BAR_ALIGN_CENTER, |
166 | + BAR_ALIGN_RIGHT, |
167 | + BAR_ALIGN_LEFT_LEFT, |
168 | + BAR_ALIGN_LEFT_RIGHT, |
169 | + BAR_ALIGN_LEFT_CENTER, |
170 | + BAR_ALIGN_NONE, |
171 | + BAR_ALIGN_RIGHT_LEFT, |
172 | + BAR_ALIGN_RIGHT_RIGHT, |
173 | + BAR_ALIGN_RIGHT_CENTER, |
174 | + BAR_ALIGN_LAST |
175 | +}; /* bar alignment */ |
176 | + |
177 | +typedef union { |
178 | + int i; |
179 | + unsigned int ui; |
180 | + float f; |
181 | + const void *v; |
182 | +} Arg; |
183 | + |
184 | +typedef struct Monitor Monitor; |
185 | +typedef struct Bar Bar; |
186 | +struct Bar { |
187 | + Window win; |
188 | + Monitor *mon; |
189 | + Bar *next; |
190 | + int idx; |
191 | + int topbar; |
192 | + int bx, by, bw, bh; /* bar geometry */ |
193 | + int w[BARRULES]; // module width |
194 | + int x[BARRULES]; // module position |
195 | +}; |
196 | + |
197 | +typedef struct { |
198 | + int max_width; |
199 | +} BarWidthArg; |
200 | + |
201 | +typedef struct { |
202 | + int x; |
203 | + int w; |
204 | +} BarDrawArg; |
205 | + |
206 | +typedef struct { |
207 | + int rel_x; |
208 | + int rel_y; |
209 | + int rel_w; |
210 | + int rel_h; |
211 | +} BarClickArg; |
212 | + |
213 | +typedef struct { |
214 | + int monitor; |
215 | + int bar; |
216 | + int alignment; // see bar alignment enum |
217 | + int (*widthfunc)(Bar *bar, BarWidthArg *a); |
218 | + int (*drawfunc)(Bar *bar, BarDrawArg *a); |
219 | + int (*clickfunc)(Bar *bar, Arg *arg, BarClickArg *a); |
220 | + char *name; // for debugging |
221 | + int x, w; // position, width for internal use |
222 | +} BarRule; |
223 | + |
224 | +typedef struct { |
225 | + unsigned int click; |
226 | + unsigned int mask; |
227 | + unsigned int button; |
228 | + void (*func)(const Arg *arg); |
229 | + const Arg arg; |
230 | +} Button; |
231 | + |
232 | +typedef struct Client Client; |
233 | +struct Client { |
234 | + char name[256]; |
235 | + float mina, maxa; |
236 | + int x, y, w, h; |
237 | + int oldx, oldy, oldw, oldh; |
238 | + int basew, baseh, incw, inch, maxw, maxh, minw, minh; |
239 | + int bw, oldbw; |
240 | + unsigned int tags; |
241 | + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen, isterminal, noswallow, issticky; |
242 | + pid_t pid; |
243 | + Client *next; |
244 | + Client *snext; |
245 | + Client *swallowing; |
246 | + Monitor *mon; |
247 | + Window win; |
248 | +}; |
249 | + |
250 | +typedef struct { |
251 | + unsigned int mod; |
252 | + KeySym keysym; |
253 | + void (*func)(const Arg *); |
254 | + const Arg arg; |
255 | +} Key; |
256 | + |
257 | +typedef struct { |
258 | + const char *symbol; |
259 | + void (*arrange)(Monitor *); |
260 | +} Layout; |
261 | + |
262 | +struct Monitor { |
263 | + char ltsymbol[16]; |
264 | + float mfact; |
265 | + int nmaster; |
266 | + int num; |
267 | + int mx, my, mw, mh; /* screen size */ |
268 | + int wx, wy, ww, wh; /* window area */ |
269 | + int gappih; /* horizontal gap between windows */ |
270 | + int gappiv; /* vertical gap between windows */ |
271 | + int gappoh; /* horizontal outer gaps */ |
272 | + int gappov; /* vertical outer gaps */ |
273 | + unsigned int seltags; |
274 | + unsigned int sellt; |
275 | + unsigned int tagset[2]; |
276 | + int showbar; |
277 | + Client *clients; |
278 | + Client *sel; |
279 | + Client *stack; |
280 | + Monitor *next; |
281 | + Bar *bar; |
282 | + const Layout *lt[2]; |
283 | +}; |
284 | + |
285 | +typedef struct { |
286 | + const char *class; |
287 | + const char *instance; |
288 | + const char *title; |
289 | + unsigned int tags; |
290 | + int isfloating; |
291 | + int isterminal; |
292 | + int noswallow; |
293 | + int monitor; |
294 | +} Rule; |
295 | + |
296 | +/* Xresources preferences */ |
297 | +enum resource_type { |
298 | + STRING = 0, |
299 | + INTEGER = 1, |
300 | + FLOAT = 2 |
301 | +}; |
302 | + |
303 | +typedef struct { |
304 | + char *name; |
305 | + enum resource_type type; |
306 | + void *dst; |
307 | +} ResourcePref; |
308 | + |
309 | +/* function declarations */ |
310 | +static void applyrules(Client *c); |
311 | +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); |
312 | +static void arrange(Monitor *m); |
313 | +static void arrangemon(Monitor *m); |
314 | +static void attach(Client *c); |
315 | +static void attachbottom(Client *c); |
316 | +static void attachstack(Client *c); |
317 | +static void buttonpress(XEvent *e); |
318 | +static void checkotherwm(void); |
319 | +static void cleanup(void); |
320 | +static void cleanupmon(Monitor *mon); |
321 | +static void clientmessage(XEvent *e); |
322 | +static void configure(Client *c); |
323 | +static void configurenotify(XEvent *e); |
324 | +static void configurerequest(XEvent *e); |
325 | +static void copyvalidchars(char *text, char *rawtext); |
326 | +static Monitor *createmon(void); |
327 | +static void destroynotify(XEvent *e); |
328 | +static void detach(Client *c); |
329 | +static void detachstack(Client *c); |
330 | +static Monitor *dirtomon(int dir); |
331 | +static void drawbar(Monitor *m); |
332 | +static void drawbars(void); |
333 | +static void drawbarwin(Bar *bar); |
334 | +static void enternotify(XEvent *e); |
335 | +static void expose(XEvent *e); |
336 | +static void focus(Client *c); |
337 | +static void focusin(XEvent *e); |
338 | +static void focusmon(const Arg *arg); |
339 | +static void focusstack(const Arg *arg); |
340 | +static Atom getatomprop(Client *c, Atom prop); |
341 | +static int getrootptr(int *x, int *y); |
342 | +static long getstate(Window w); |
343 | +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); |
344 | +static void grabbuttons(Client *c, int focused); |
345 | +static void grabkeys(void); |
346 | +static void incnmaster(const Arg *arg); |
347 | +static void keypress(XEvent *e); |
348 | +static void killclient(const Arg *arg); |
349 | +static void manage(Window w, XWindowAttributes *wa); |
350 | +static void mappingnotify(XEvent *e); |
351 | +static void maprequest(XEvent *e); |
352 | +static void monocle(Monitor *m); |
353 | +static void motionnotify(XEvent *e); |
354 | +static void movemouse(const Arg *arg); |
355 | +static Client *nexttiled(Client *c); |
356 | +static void pop(Client *); |
357 | +static void propertynotify(XEvent *e); |
358 | +static void pushstack(const Arg *arg); |
359 | +static void quit(const Arg *arg); |
360 | +static Monitor *recttomon(int x, int y, int w, int h); |
361 | +static void resize(Client *c, int x, int y, int w, int h, int interact); |
362 | +static void resizeclient(Client *c, int x, int y, int w, int h); |
363 | +static void resizemouse(const Arg *arg); |
364 | +static void restack(Monitor *m); |
365 | +static void run(void); |
366 | +static void runAutostart(void); |
367 | +static void scan(void); |
368 | +static void scratchpad_hide (); |
369 | +static _Bool scratchpad_last_showed_is_killed (void); |
370 | +static void scratchpad_remove (); |
371 | +static void scratchpad_show (); |
372 | +static void scratchpad_show_client (Client * c); |
373 | +static void scratchpad_show_first (void); |
374 | +static int sendevent(Client *c, Atom proto); |
375 | +static void sendmon(Client *c, Monitor *m); |
376 | +static void setclientstate(Client *c, long state); |
377 | +static void setfocus(Client *c); |
378 | +static void setfullscreen(Client *c, int fullscreen); |
379 | +static void setlayout(const Arg *arg); |
380 | +static void setmfact(const Arg *arg); |
381 | +static void setup(void); |
382 | +static void seturgent(Client *c, int urg); |
383 | +static void showhide(Client *c); |
384 | +static void sigchld(int unused); |
385 | +#ifndef __OpenBSD__ |
386 | +static int getdwmblockspid(); |
387 | +static void sigdwmblocks(const Arg *arg); |
388 | +#endif |
389 | +static void sighup(int unused); |
390 | +static void sigterm(int unused); |
391 | +static void spawn(const Arg *arg); |
392 | +static int stackpos(const Arg *arg); |
393 | +static void tag(const Arg *arg); |
394 | +static void tagmon(const Arg *arg); |
395 | +static void togglebar(const Arg *arg); |
396 | +static void togglefloating(const Arg *arg); |
397 | +static void togglescratch(const Arg *arg); |
398 | +static void togglesticky(const Arg *arg); |
399 | +static void togglefullscr(const Arg *arg); |
400 | +static void toggletag(const Arg *arg); |
401 | +static void toggleview(const Arg *arg); |
402 | +static void unfocus(Client *c, int setfocus); |
403 | +static void unmanage(Client *c, int destroyed); |
404 | +static void unmapnotify(XEvent *e); |
405 | +static void updatebarpos(Monitor *m); |
406 | +static void updatebars(void); |
407 | +static void updateclientlist(void); |
408 | +static int updategeom(void); |
409 | +static void updatenumlockmask(void); |
410 | +static void updatesizehints(Client *c); |
411 | +static void updatestatus(void); |
412 | +static void updatetitle(Client *c); |
413 | +static void updatewindowtype(Client *c); |
414 | +static void updatewmhints(Client *c); |
415 | +static void view(const Arg *arg); |
416 | +static Client *wintoclient(Window w); |
417 | +static Monitor *wintomon(Window w); |
418 | +static int xerror(Display *dpy, XErrorEvent *ee); |
419 | +static int xerrordummy(Display *dpy, XErrorEvent *ee); |
420 | +static int xerrorstart(Display *dpy, XErrorEvent *ee); |
421 | +static int leftrotatebits(const int n, const unsigned int d); |
422 | +static int rightrotatebits(const int n, const unsigned int d); |
423 | +static void rightrotview(const Arg *arg); |
424 | +static void leftrotview(const Arg *arg); |
425 | +static void zoom(const Arg *arg); |
426 | +static void load_xresources(void); |
427 | +static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst); |
428 | + |
429 | +static pid_t getparentprocess(pid_t p); |
430 | +static int isdescprocess(pid_t p, pid_t c); |
431 | +static Client *swallowingclient(Window w); |
432 | +static Client *termforwin(const Client *c); |
433 | +static pid_t winpid(Window w); |
434 | + |
435 | +#include "patch/include.h" |
436 | +/* variables */ |
437 | +static const char broken[] = "broken"; |
438 | +static char stext[256]; |
439 | +static char rawstext[256]; |
440 | +static int dwmblockssig; |
441 | +pid_t dwmblockspid = 0; |
442 | +static int screen; |
443 | +static int sw, sh; /* X display screen geometry width, height */ |
444 | +static int bh; /* bar geometry */ |
445 | +static int lrpad; /* sum of left and right padding for text */ |
446 | +static int vp; /* vertical padding for bar */ |
447 | +static int sp; /* side padding for bar */ |
448 | +static int (*xerrorxlib)(Display *, XErrorEvent *); |
449 | +static unsigned int numlockmask = 0; |
450 | +static void (*handler[LASTEvent]) (XEvent *) = { |
451 | + [ButtonPress] = buttonpress, |
452 | + [ClientMessage] = clientmessage, |
453 | + [ConfigureRequest] = configurerequest, |
454 | + [ConfigureNotify] = configurenotify, |
455 | + [DestroyNotify] = destroynotify, |
456 | + [EnterNotify] = enternotify, |
457 | + [Expose] = expose, |
458 | + [FocusIn] = focusin, |
459 | + [KeyPress] = keypress, |
460 | + [MappingNotify] = mappingnotify, |
461 | + [MapRequest] = maprequest, |
462 | + [MotionNotify] = motionnotify, |
463 | + [PropertyNotify] = propertynotify, |
464 | + [UnmapNotify] = unmapnotify |
465 | +}; |
466 | +static Atom wmatom[WMLast], netatom[NetLast]; |
467 | +static int restart = 0; |
468 | +static int running = 1; |
469 | +static Cur *cursor[CurLast]; |
470 | +static Clr **scheme; |
471 | +static Display *dpy; |
472 | +static Drw *drw; |
473 | +static Monitor *mons, *selmon; |
474 | +static Window root, wmcheckwin; |
475 | + |
476 | +/* scratchpad */ |
477 | +# define SCRATCHPAD_MASK (1u << sizeof tags / sizeof * tags) |
478 | +static Client * scratchpad_last_showed = NULL; |
479 | + |
480 | +static xcb_connection_t *xcon; |
481 | + |
482 | +/* configuration, allows nested code to access above variables */ |
483 | +#include "config.h" |
484 | + |
485 | +#include "patch/include.c" |
486 | + |
487 | +/* compile-time check if all tags fit into an unsigned int bit array. */ |
488 | +struct NumTags { char limitexceeded[LENGTH(tags) > 30 ? -1 : 1]; }; |
489 | + |
490 | +/* function implementations */ |
491 | +void |
492 | +applyrules(Client *c) |
493 | +{ |
494 | + const char *class, *instance; |
495 | + unsigned int i; |
496 | + const Rule *r; |
497 | + Monitor *m; |
498 | + XClassHint ch = { NULL, NULL }; |
499 | + |
500 | + /* rule matching */ |
501 | + c->isfloating = 0; |
502 | + c->tags = 0; |
503 | + XGetClassHint(dpy, c->win, &ch); |
504 | + class = ch.res_class ? ch.res_class : broken; |
505 | + instance = ch.res_name ? ch.res_name : broken; |
506 | + |
507 | + for (i = 0; i < LENGTH(rules); i++) { |
508 | + r = &rules[i]; |
509 | + if ((!r->title || strstr(c->name, r->title)) |
510 | + && (!r->class || strstr(class, r->class)) |
511 | + && (!r->instance || strstr(instance, r->instance))) |
512 | + { |
513 | + c->isterminal = r->isterminal; |
514 | + c->isfloating = r->isfloating; |
515 | + c->noswallow = r->noswallow; |
516 | + c->tags |= r->tags; |
517 | + if ((r->tags & SPTAGMASK) && r->isfloating) { |
518 | + c->x = c->mon->wx + (c->mon->ww / 2 - WIDTH(c) / 2); |
519 | + c->y = c->mon->wy + (c->mon->wh / 2 - HEIGHT(c) / 2); |
520 | + } |
521 | + |
522 | + for (m = mons; m && m->num != r->monitor; m = m->next); |
523 | + if (m) |
524 | + c->mon = m; |
525 | + } |
526 | + } |
527 | + if (ch.res_class) |
528 | + XFree(ch.res_class); |
529 | + if (ch.res_name) |
530 | + XFree(ch.res_name); |
531 | + if (c->tags != SCRATCHPAD_MASK) |
532 | + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; |
533 | +} |
534 | + |
535 | +int |
536 | +applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) |
537 | +{ |
538 | + int baseismin; |
539 | + Monitor *m = c->mon; |
540 | + |
541 | + /* set minimum possible */ |
542 | + *w = MAX(1, *w); |
543 | + *h = MAX(1, *h); |
544 | + if (interact) { |
545 | + if (*x > sw) |
546 | + *x = sw - WIDTH(c); |
547 | + if (*y > sh) |
548 | + *y = sh - HEIGHT(c); |
549 | + if (*x + *w + 2 * c->bw < 0) |
550 | + *x = 0; |
551 | + if (*y + *h + 2 * c->bw < 0) |
552 | + *y = 0; |
553 | + } else { |
554 | + if (*x >= m->wx + m->ww) |
555 | + *x = m->wx + m->ww - WIDTH(c); |
556 | + if (*y >= m->wy + m->wh) |
557 | + *y = m->wy + m->wh - HEIGHT(c); |
558 | + if (*x + *w + 2 * c->bw <= m->wx) |
559 | + *x = m->wx; |
560 | + if (*y + *h + 2 * c->bw <= m->wy) |
561 | + *y = m->wy; |
562 | + } |
563 | + if (*h < bh) |
564 | + *h = bh; |
565 | + if (*w < bh) |
566 | + *w = bh; |
567 | + if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { |
568 | + /* see last two sentences in ICCCM 4.1.2.3 */ |
569 | + baseismin = c->basew == c->minw && c->baseh == c->minh; |
570 | + if (!baseismin) { /* temporarily remove base dimensions */ |
571 | + *w -= c->basew; |
572 | + *h -= c->baseh; |
573 | + } |
574 | + /* adjust for aspect limits */ |
575 | + if (c->mina > 0 && c->maxa > 0) { |
576 | + if (c->maxa < (float)*w / *h) |
577 | + *w = *h * c->maxa + 0.5; |
578 | + else if (c->mina < (float)*h / *w) |
579 | + *h = *w * c->mina + 0.5; |
580 | + } |
581 | + if (baseismin) { /* increment calculation requires this */ |
582 | + *w -= c->basew; |
583 | + *h -= c->baseh; |
584 | + } |
585 | + /* adjust for increment value */ |
586 | + if (c->incw) |
587 | + *w -= *w % c->incw; |
588 | + if (c->inch) |
589 | + *h -= *h % c->inch; |
590 | + /* restore base dimensions */ |
591 | + *w = MAX(*w + c->basew, c->minw); |
592 | + *h = MAX(*h + c->baseh, c->minh); |
593 | + if (c->maxw) |
594 | + *w = MIN(*w, c->maxw); |
595 | + if (c->maxh) |
596 | + *h = MIN(*h, c->maxh); |
597 | + } |
598 | + return *x != c->x || *y != c->y || *w != c->w || *h != c->h; |
599 | +} |
600 | + |
601 | +void |
602 | +arrange(Monitor *m) |
603 | +{ |
604 | + if (m) |
605 | + showhide(m->stack); |
606 | + else for (m = mons; m; m = m->next) |
607 | + showhide(m->stack); |
608 | + if (m) { |
609 | + arrangemon(m); |
610 | + restack(m); |
611 | + } else for (m = mons; m; m = m->next) |
612 | + arrangemon(m); |
613 | +} |
614 | + |
615 | +void |
616 | +arrangemon(Monitor *m) |
617 | +{ |
618 | + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); |
619 | + if (m->lt[m->sellt]->arrange) |
620 | + m->lt[m->sellt]->arrange(m); |
621 | +} |
622 | + |
623 | +void |
624 | +attach(Client *c) |
625 | +{ |
626 | + c->next = c->mon->clients; |
627 | + c->mon->clients = c; |
628 | +} |
629 | + |
630 | +void |
631 | +attachbottom(Client *c) |
632 | +{ |
633 | + Client **tc; |
634 | + c->next = NULL; |
635 | + for (tc = &c->mon->clients; *tc; tc = &(*tc)->next); |
636 | + *tc = c; |
637 | +} |
638 | + |
639 | +void |
640 | +attachstack(Client *c) |
641 | +{ |
642 | + c->snext = c->mon->stack; |
643 | + c->mon->stack = c; |
644 | +} |
645 | + |
646 | +void |
647 | +swallow(Client *p, Client *c) |
648 | +{ |
649 | + if (c->noswallow || c->isterminal) |
650 | + return; |
651 | + if (!swallowfloating && c->isfloating) |
652 | + return; |
653 | + |
654 | + detach(c); |
655 | + detachstack(c); |
656 | + |
657 | + setclientstate(c, WithdrawnState); |
658 | + XUnmapWindow(dpy, p->win); |
659 | + |
660 | + p->swallowing = c; |
661 | + c->mon = p->mon; |
662 | + |
663 | + Window w = p->win; |
664 | + p->win = c->win; |
665 | + c->win = w; |
666 | + updatetitle(p); |
667 | + |
668 | + XWindowChanges wc; |
669 | + wc.border_width = p->bw; |
670 | + XConfigureWindow(dpy, p->win, CWBorderWidth, &wc); |
671 | + XMoveResizeWindow(dpy, p->win, p->x, p->y, p->w, p->h); |
672 | + XSetWindowBorder(dpy, p->win, scheme[SchemeNorm][ColBorder].pixel); |
673 | + |
674 | + arrange(p->mon); |
675 | + configure(p); |
676 | + updateclientlist(); |
677 | +} |
678 | + |
679 | +void |
680 | +unswallow(Client *c) |
681 | +{ |
682 | + c->win = c->swallowing->win; |
683 | + |
684 | + free(c->swallowing); |
685 | + c->swallowing = NULL; |
686 | + |
687 | + /* unfullscreen the client */ |
688 | + setfullscreen(c, 0); |
689 | + updatetitle(c); |
690 | + arrange(c->mon); |
691 | + XMapWindow(dpy, c->win); |
692 | + |
693 | + XWindowChanges wc; |
694 | + wc.border_width = c->bw; |
695 | + XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); |
696 | + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); |
697 | + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); |
698 | + |
699 | + setclientstate(c, NormalState); |
700 | + focus(NULL); |
701 | + arrange(c->mon); |
702 | +} |
703 | + |
704 | +void |
705 | +buttonpress(XEvent *e) |
706 | +{ |
707 | + int click, i, r, mi; |
708 | + Arg arg = {0}; |
709 | + Client *c; |
710 | + Monitor *m; |
711 | + Bar *bar; |
712 | + XButtonPressedEvent *ev = &e->xbutton; |
713 | + const BarRule *br; |
714 | + BarClickArg carg = { 0, 0, 0, 0 }; |
715 | + |
716 | + click = ClkRootWin; |
717 | + /* focus monitor if necessary */ |
718 | + if ((m = wintomon(ev->window)) && m != selmon |
719 | + ) { |
720 | + unfocus(selmon->sel, 1); |
721 | + selmon = m; |
722 | + focus(NULL); |
723 | + } |
724 | + |
725 | + for (mi = 0, m = mons; m && m != selmon; m = m->next, mi++); // get the monitor index |
726 | + for (bar = selmon->bar; bar; bar = bar->next) { |
727 | + if (ev->window == bar->win) { |
728 | + for (r = 0; r < LENGTH(barrules); r++) { |
729 | + br = &barrules[r]; |
730 | + if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->clickfunc == NULL) |
731 | + continue; |
732 | + if (br->monitor != 'A' && br->monitor != -1 && br->monitor != mi) |
733 | + continue; |
734 | + if (bar->x[r] <= ev->x && ev->x <= bar->x[r] + bar->w[r]) { |
735 | + carg.rel_x = ev->x - bar->x[r]; |
736 | + carg.rel_y = ev->y; |
737 | + carg.rel_w = bar->w[r]; |
738 | + carg.rel_h = bar->bh; |
739 | + click = br->clickfunc(bar, &arg, &carg); |
740 | + if (click < 0) |
741 | + return; |
742 | + break; |
743 | + } |
744 | + } |
745 | + break; |
746 | + } |
747 | + } |
748 | + |
749 | + if (click == ClkRootWin && (c = wintoclient(ev->window))) { |
750 | + focus(c); |
751 | + restack(selmon); |
752 | + XAllowEvents(dpy, ReplayPointer, CurrentTime); |
753 | + click = ClkClientWin; |
754 | + } |
755 | + |
756 | + for (i = 0; i < LENGTH(buttons); i++) { |
757 | + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button |
758 | + && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) { |
759 | + buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); |
760 | + } |
761 | + } |
762 | +} |
763 | + |
764 | +void |
765 | +checkotherwm(void) |
766 | +{ |
767 | + xerrorxlib = XSetErrorHandler(xerrorstart); |
768 | + /* this causes an error if some other window manager is running */ |
769 | + XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); |
770 | + XSync(dpy, False); |
771 | + XSetErrorHandler(xerror); |
772 | + XSync(dpy, False); |
773 | +} |
774 | + |
775 | +void |
776 | +cleanup(void) |
777 | +{ |
778 | + Arg a = {.ui = ~0}; |
779 | + Layout foo = { "", NULL }; |
780 | + Monitor *m; |
781 | + size_t i; |
782 | + |
783 | + view(&a); |
784 | + selmon->lt[selmon->sellt] = &foo; |
785 | + for (m = mons; m; m = m->next) |
786 | + while (m->stack) |
787 | + unmanage(m->stack, 0); |
788 | + XUngrabKey(dpy, AnyKey, AnyModifier, root); |
789 | + while (mons) |
790 | + cleanupmon(mons); |
791 | + for (i = 0; i < CurLast; i++) |
792 | + drw_cur_free(drw, cursor[i]); |
793 | + for (i = 0; i < LENGTH(colors); i++) |
794 | + free(scheme[i]); |
795 | + XDestroyWindow(dpy, wmcheckwin); |
796 | + drw_free(drw); |
797 | + XSync(dpy, False); |
798 | + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); |
799 | + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); |
800 | +} |
801 | + |
802 | +void |
803 | +cleanupmon(Monitor *mon) |
804 | +{ |
805 | + Monitor *m; |
806 | + Bar *bar; |
807 | + |
808 | + if (mon == mons) |
809 | + mons = mons->next; |
810 | + else { |
811 | + for (m = mons; m && m->next != mon; m = m->next); |
812 | + m->next = mon->next; |
813 | + } |
814 | + for (bar = mon->bar; bar; bar = mon->bar) { |
815 | + XUnmapWindow(dpy, bar->win); |
816 | + XDestroyWindow(dpy, bar->win); |
817 | + mon->bar = bar->next; |
818 | + free(bar); |
819 | + } |
820 | + free(mon); |
821 | +} |
822 | + |
823 | +void |
824 | +clientmessage(XEvent *e) |
825 | +{ |
826 | + XClientMessageEvent *cme = &e->xclient; |
827 | + Client *c = wintoclient(cme->window); |
828 | + |
829 | + if (!c) |
830 | + return; |
831 | + if (cme->message_type == netatom[NetWMState]) { |
832 | + if (cme->data.l[1] == netatom[NetWMFullscreen] |
833 | + || cme->data.l[2] == netatom[NetWMFullscreen]) |
834 | + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ |
835 | + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); |
836 | + } else if (cme->message_type == netatom[NetActiveWindow]) { |
837 | + if (c != selmon->sel && !c->isurgent) |
838 | + seturgent(c, 1); |
839 | + } |
840 | +} |
841 | + |
842 | +void |
843 | +configure(Client *c) |
844 | +{ |
845 | + XConfigureEvent ce; |
846 | + |
847 | + ce.type = ConfigureNotify; |
848 | + ce.display = dpy; |
849 | + ce.event = c->win; |
850 | + ce.window = c->win; |
851 | + ce.x = c->x; |
852 | + ce.y = c->y; |
853 | + ce.width = c->w; |
854 | + ce.height = c->h; |
855 | + ce.border_width = c->bw; |
856 | + ce.above = None; |
857 | + ce.override_redirect = False; |
858 | + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); |
859 | +} |
860 | + |
861 | +void |
862 | +configurenotify(XEvent *e) |
863 | +{ |
864 | + Monitor *m; |
865 | + Bar *bar; |
866 | + Client *c; |
867 | + XConfigureEvent *ev = &e->xconfigure; |
868 | + int dirty; |
869 | + |
870 | + /* TODO: updategeom handling sucks, needs to be simplified */ |
871 | + if (ev->window == root) { |
872 | + dirty = (sw != ev->width || sh != ev->height); |
873 | + sw = ev->width; |
874 | + sh = ev->height; |
875 | + if (updategeom() || dirty) { |
876 | + drw_resize(drw, sw, bh); |
877 | + updatebars(); |
878 | + for (m = mons; m; m = m->next) { |
879 | + for (c = m->clients; c; c = c->next) |
880 | + if (c->isfullscreen) |
881 | + resizeclient(c, m->mx, m->my, m->mw, m->mh); |
882 | + for (bar = m->bar; bar; bar = bar->next) |
883 | + XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh); |
884 | + } |
885 | + focus(NULL); |
886 | + arrange(NULL); |
887 | + } |
888 | + } |
889 | +} |
890 | + |
891 | +void |
892 | +configurerequest(XEvent *e) |
893 | +{ |
894 | + Client *c; |
895 | + Monitor *m; |
896 | + XConfigureRequestEvent *ev = &e->xconfigurerequest; |
897 | + XWindowChanges wc; |
898 | + |
899 | + if ((c = wintoclient(ev->window))) { |
900 | + if (ev->value_mask & CWBorderWidth) |
901 | + c->bw = ev->border_width; |
902 | + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { |
903 | + m = c->mon; |
904 | + if (ev->value_mask & CWX) { |
905 | + c->oldx = c->x; |
906 | + c->x = m->mx + ev->x; |
907 | + } |
908 | + if (ev->value_mask & CWY) { |
909 | + c->oldy = c->y; |
910 | + c->y = m->my + ev->y; |
911 | + } |
912 | + if (ev->value_mask & CWWidth) { |
913 | + c->oldw = c->w; |
914 | + c->w = ev->width; |
915 | + } |
916 | + if (ev->value_mask & CWHeight) { |
917 | + c->oldh = c->h; |
918 | + c->h = ev->height; |
919 | + } |
920 | + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) |
921 | + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ |
922 | + if ((c->y + c->h) > m->my + m->mh && c->isfloating) |
923 | + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ |
924 | + if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) |
925 | + configure(c); |
926 | + if (ISVISIBLE(c)) |
927 | + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); |
928 | + } else |
929 | + configure(c); |
930 | + } else { |
931 | + wc.x = ev->x; |
932 | + wc.y = ev->y; |
933 | + wc.width = ev->width; |
934 | + wc.height = ev->height; |
935 | + wc.border_width = ev->border_width; |
936 | + wc.sibling = ev->above; |
937 | + wc.stack_mode = ev->detail; |
938 | + XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); |
939 | + } |
940 | + XSync(dpy, False); |
941 | +} |
942 | + |
943 | +void |
944 | +copyvalidchars(char *text, char *rawtext) |
945 | +{ |
946 | + int i = -1, j = 0; |
947 | + |
948 | + while(rawtext[++i]) { |
949 | + if ((unsigned char)rawtext[i] >= ' ') { |
950 | + text[j++] = rawtext[i]; |
951 | + } |
952 | + } |
953 | + text[j] = '\0'; |
954 | +} |
955 | + |
956 | +Monitor * |
957 | +createmon(void) |
958 | +{ |
959 | + Monitor *m, *mon; |
960 | + int i, n, mi, max_bars = 2, istopbar = topbar; |
961 | + |
962 | + const BarRule *br; |
963 | + Bar *bar; |
964 | + |
965 | + m = ecalloc(1, sizeof(Monitor)); |
966 | + m->tagset[0] = m->tagset[1] = 1; |
967 | + m->mfact = mfact; |
968 | + m->nmaster = nmaster; |
969 | + m->showbar = showbar; |
970 | + m->gappih = gappih; |
971 | + m->gappiv = gappiv; |
972 | + m->gappoh = gappoh; |
973 | + m->gappov = gappov; |
974 | + |
975 | + for (mi = 0, mon = mons; mon; mon = mon->next, mi++); // monitor index |
976 | + m->lt[0] = &layouts[0]; |
977 | + m->lt[1] = &layouts[1 % LENGTH(layouts)]; |
978 | + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); |
979 | + |
980 | + /* Derive the number of bars for this monitor based on bar rules */ |
981 | + for (n = -1, i = 0; i < LENGTH(barrules); i++) { |
982 | + br = &barrules[i]; |
983 | + if (br->monitor == 'A' || br->monitor == -1 || br->monitor == mi) |
984 | + n = MAX(br->bar, n); |
985 | + } |
986 | + |
987 | + for (i = 0; i <= n && i < max_bars; i++) { |
988 | + bar = ecalloc(1, sizeof(Bar)); |
989 | + bar->mon = m; |
990 | + bar->idx = i; |
991 | + bar->next = m->bar; |
992 | + bar->topbar = istopbar; |
993 | + m->bar = bar; |
994 | + istopbar = !istopbar; |
995 | + } |
996 | + |
997 | + return m; |
998 | +} |
999 | + |