aboutsummaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorphilw <dscr@duck.com>2025-04-24 11:05:27 +0200
committerphilw <dscr@duck.com>2025-04-24 11:05:27 +0200
commit3067e463f953463d4c604d0c5259475595d89a00 (patch)
tree45b451826566e707cc19b17fa872e9ecade7a025 /src/core
parent8146021a2ea4130cfb0d2bf846b451ec538b1bb6 (diff)
downloaddwm-3067e463f953463d4c604d0c5259475595d89a00.tar.gz
dwm-3067e463f953463d4c604d0c5259475595d89a00.zip
feat: Refactor dwm.c for modularity, add dwm.h header file, switch compiler to tcc
Refactored dwm.c to improve code organization and maintainability Added dwm.h header file for better modularity and to define common declarations Changed the compiler to TCC for faster compilation during development. Signed-off-by: philw <dscr@duck.com>
Diffstat (limited to 'src/core')
-rw-r--r--src/core/dwm.c572
-rw-r--r--src/core/dwm.h268
2 files changed, 412 insertions, 428 deletions
diff --git a/src/core/dwm.c b/src/core/dwm.c
index 6082987..d3782cb 100644
--- a/src/core/dwm.c
+++ b/src/core/dwm.c
@@ -51,6 +51,8 @@
51#include "../util/util.h" 51#include "../util/util.h"
52#include <X11/XF86keysym.h> 52#include <X11/XF86keysym.h>
53 53
54#include "dwm.h"
55
54/* macros */ 56/* macros */
55#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) 57#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
56#define CLEANMASK(mask) \ 58#define CLEANMASK(mask) \
@@ -81,292 +83,6 @@
81#define VERSION_MINOR 0 83#define VERSION_MINOR 0
82#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR 84#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
83 85
84/* enums */
85enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
86enum { SchemeNorm, SchemeSel }; /* color schemes */
87enum {
88 NetSupported,
89 NetWMName,
90 NetWMState,
91 NetWMCheck,
92 NetSystemTray,
93 NetSystemTrayOP,
94 NetSystemTrayOrientation,
95 NetSystemTrayOrientationHorz,
96 NetWMFullscreen,
97 NetActiveWindow,
98 NetWMWindowType,
99 NetWMWindowTypeDialog,
100 NetClientList,
101 NetLast
102}; /* EWMH atoms */
103enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
104enum {
105 WMProtocols,
106 WMDelete,
107 WMState,
108 WMTakeFocus,
109 WMLast
110}; /* default atoms */
111enum {
112 ClkTagBar,
113 ClkLtSymbol,
114 ClkStatusText,
115 ClkWinTitle,
116 ClkClientWin,
117 ClkRootWin,
118 ClkLast
119}; /* clicks */
120
121typedef union {
122 int i;
123 unsigned int ui;
124 float f;
125 const void *v;
126} Arg;
127
128typedef struct {
129 unsigned int click;
130 unsigned int mask;
131 unsigned int button;
132 void (*func)(const Arg *arg);
133 const Arg arg;
134} Button;
135
136typedef struct Monitor Monitor;
137typedef struct Client Client;
138struct Client {
139 char name[256];
140 float mina, maxa;
141 int x, y, w, h;
142 int oldx, oldy, oldw, oldh;
143 int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
144 int bw, oldbw;
145 unsigned int tags;
146 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen,
147 isterminal, noswallow;
148 pid_t pid;
149 Client *next;
150 Client *snext;
151 Client *swallowing;
152 Monitor *mon;
153 Window win;
154};
155
156typedef struct {
157 unsigned int mod;
158 KeySym keysym;
159 void (*func)(const Arg *);
160 const Arg arg;
161} Key;
162
163typedef struct {
164 const char *symbol;
165 void (*arrange)(Monitor *);
166} Layout;
167
168struct Monitor {
169 char ltsymbol[16];
170 float mfact;
171 int nmaster;
172 int num;
173 int by; /* bar geometry */
174 int mx, my, mw, mh; /* screen size */
175 int wx, wy, ww, wh; /* window area */
176 int gappih; /* horizontal gap between windows */
177 int gappiv; /* vertical gap between windows */
178 int gappoh; /* horizontal outer gaps */
179 int gappov; /* vertical outer gaps */
180 unsigned int seltags;
181 unsigned int sellt;
182 unsigned int tagset[2];
183 int showbar;
184 int topbar;
185 Client *clients;
186 Client *sel;
187 Client *stack;
188 Monitor *next;
189 Window barwin;
190 const Layout *lt[2];
191};
192
193typedef struct {
194 const char *class;
195 const char *instance;
196 const char *title;
197 unsigned int tags;
198 int isfloating;
199 int isterminal;
200 int noswallow;
201 int monitor;
202} Rule;
203
204typedef struct Systray Systray;
205struct Systray {
206 Window win;
207 Client *icons;
208};
209
210/* function declarations */
211static void applyrules(Client *c);
212static int applysizehints(Client *c, int *x, int *y, int *w, int *h,
213 int interact);
214static void arrange(Monitor *m);
215static void arrangemon(Monitor *m);
216static void attach(Client *c);
217static void attachstack(Client *c);
218static void buttonpress(XEvent *e);
219static void checkotherwm(void);
220static void cleanup(void);
221static void cleanupmon(Monitor *mon);
222static void clientmessage(XEvent *e);
223static void configure(Client *c);
224static void configurenotify(XEvent *e);
225static void configurerequest(XEvent *e);
226static Monitor *createmon(void);
227static void destroynotify(XEvent *e);
228static void detach(Client *c);
229static void detachstack(Client *c);
230static Monitor *dirtomon(int dir);
231static void drawbar(Monitor *m);
232static void drawbars(void);
233static void enternotify(XEvent *e);
234static void expose(XEvent *e);
235static void focus(Client *c);
236static void focusin(XEvent *e);
237static void focusmon(const Arg *arg);
238static void focusstack(const Arg *arg);
239static Atom getatomprop(Client *c, Atom prop);
240static int getrootptr(int *x, int *y);
241static long getstate(Window w);
242static unsigned int getsystraywidth();
243static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
244static void grabbuttons(Client *c, int focused);
245static void grabkeys(void);
246static void incnmaster(const Arg *arg);
247static void keypress(XEvent *e);
248static void killclient(const Arg *arg);
249static void manage(Window w, XWindowAttributes *wa);
250static void mappingnotify(XEvent *e);
251static void maprequest(XEvent *e);
252static void monocle(Monitor *m);
253static void motionnotify(XEvent *e);
254static void movemouse(const Arg *arg);
255static Client *nexttiled(Client *c);
256static void pop(Client *c);
257static void propertynotify(XEvent *e);
258static void quit(const Arg *arg);
259static Monitor *recttomon(int x, int y, int w, int h);
260static void removesystrayicon(Client *i);
261static void resize(Client *c, int x, int y, int w, int h, int interact);
262static void resizebarwin(Monitor *m);
263static void resizeclient(Client *c, int x, int y, int w, int h);
264static void resizemouse(const Arg *arg);
265static void resizerequest(XEvent *e);
266static void restack(Monitor *m);
267static void run(void);
268static void scan(void);
269static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2,
270 long d3, long d4);
271static void sendmon(Client *c, Monitor *m);
272static void setclientstate(Client *c, long state);
273static void setfocus(Client *c);
274static void setfullscreen(Client *c, int fullscreen);
275static void setgaps(int oh, int ov, int ih, int iv);
276static void incrgaps(const Arg *arg);
277static void incrigaps(const Arg *arg);
278static void incrogaps(const Arg *arg);
279static void incrohgaps(const Arg *arg);
280static void incrovgaps(const Arg *arg);
281static void incrihgaps(const Arg *arg);
282static void incrivgaps(const Arg *arg);
283static void togglegaps(const Arg *arg);
284static void defaultgaps(const Arg *arg);
285static void setlayout(const Arg *arg);
286static void setmfact(const Arg *arg);
287static void setup(void);
288static void seturgent(Client *c, int urg);
289static void showhide(Client *c);
290static void spawn(const Arg *arg);
291static Monitor *systraytomon(Monitor *m);
292static void tag(const Arg *arg);
293static void tagmon(const Arg *arg);
294static void tile(Monitor *m);
295static void togglebar(const Arg *arg);
296static void togglefloating(const Arg *arg);
297static void togglefullscr(const Arg *arg);
298static void toggletag(const Arg *arg);
299static void toggleview(const Arg *arg);
300static void unfocus(Client *c, int setfocus);
301static void unmanage(Client *c, int destroyed);
302static void unmapnotify(XEvent *e);
303static void updatebarpos(Monitor *m);
304static void updatebars(void);
305static void updateclientlist(void);
306static int updategeom(void);
307static void updatenumlockmask(void);
308static void updatesystray(void);
309static void updatesystrayicongeom(Client *i, int w, int h);
310static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
311static void updatesizehints(Client *c);
312static void updatestatus(void);
313static void updatetitle(Client *c);
314static void updatewindowtype(Client *c);
315static void updatewmhints(Client *c);
316static void view(const Arg *arg);
317static Client *wintoclient(Window w);
318static Monitor *wintomon(Window w);
319static Client *wintosystrayicon(Window w);
320static int xerror(Display *dpy, XErrorEvent *ee);
321static int xerrordummy(Display *dpy, XErrorEvent *ee);
322static int xerrorstart(Display *dpy, XErrorEvent *ee);
323static void zoom(const Arg *arg);
324
325static pid_t getparentprocess(pid_t p);
326static int isdescprocess(pid_t p, pid_t c);
327static Client *swallowingclient(Window w);
328static Client *termforwin(const Client *c);
329static pid_t winpid(Window w);
330
331/* variables */
332static Systray *systray = NULL;
333static const char broken[] = "broken";
334static char stext[256];
335static int screen;
336static int sw, sh; /* X display screen geometry width, height */
337static int bh; /* bar height */
338static int enablegaps = 1; /* enables gaps, used by togglegaps */
339static int lrpad; /* sum of left and right padding for text */
340static int (*xerrorxlib)(Display *, XErrorEvent *);
341static unsigned int numlockmask = 0;
342static void (*handler[LASTEvent])(XEvent *) = {
343 [ButtonPress] = buttonpress,
344 [ClientMessage] = clientmessage,
345 [ConfigureRequest] = configurerequest,
346 [ConfigureNotify] = configurenotify,
347 [DestroyNotify] = destroynotify,
348 [EnterNotify] = enternotify,
349 [Expose] = expose,
350 [FocusIn] = focusin,
351 [KeyPress] = keypress,
352 [MappingNotify] = mappingnotify,
353 [MapRequest] = maprequest,
354 [MotionNotify] = motionnotify,
355 [PropertyNotify] = propertynotify,
356 [ResizeRequest] = resizerequest,
357 [UnmapNotify] = unmapnotify};
358
359static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
360static int running = 1;
361static Cur *cursor[CurLast];
362static Clr **scheme;
363static Display *dpy;
364static Drw *drw;
365static Monitor *mons, *selmon;
366static Window root, wmcheckwin;
367
368static xcb_connection_t *xcon;
369
370/* configuration, allows nested code to access above variables */ 86/* configuration, allows nested code to access above variables */
371#include "../config/config.h" 87#include "../config/config.h"
372 88
@@ -882,20 +598,20 @@ void detachstack(Client *c) {
882 } 598 }
883} 599}
884 600
885Monitor *dirtomon(int dir) { 601// Monitor *dirtomon(int dir) {
886 Monitor *m = NULL; 602// Monitor *m = NULL;
887 603//
888 if (dir > 0) { 604// if (dir > 0) {
889 if (!(m = selmon->next)) 605// if (!(m = selmon->next))
890 m = mons; 606// m = mons;
891 } else if (selmon == mons) 607// } else if (selmon == mons)
892 for (m = mons; m->next; m = m->next) 608// for (m = mons; m->next; m = m->next)
893 ; 609// ;
894 else 610// else
895 for (m = mons; m->next != selmon; m = m->next) 611// for (m = mons; m->next != selmon; m = m->next)
896 ; 612// ;
897 return m; 613// return m;
898} 614// }
899 615
900void drawbar(Monitor *m) { 616void drawbar(Monitor *m) {
901 int x, w, tw = 0, stw = 0; 617 int x, w, tw = 0, stw = 0;
@@ -1024,43 +740,43 @@ void focusin(XEvent *e) {
1024 setfocus(selmon->sel); 740 setfocus(selmon->sel);
1025} 741}
1026 742
1027void focusmon(const Arg *arg) { 743// void focusmon(const Arg *arg) {
1028 Monitor *m; 744// Monitor *m;
1029 745//
1030 if (!mons->next) 746// if (!mons->next)
1031 return; 747// return;
1032 if ((m = dirtomon(arg->i)) == selmon) 748// if ((m = dirtomon(arg->i)) == selmon)
1033 return; 749// return;
1034 unfocus(selmon->sel, 0); 750// unfocus(selmon->sel, 0);
1035 selmon = m; 751// selmon = m;
1036 focus(NULL); 752// focus(NULL);
1037} 753// }
1038 754
1039void focusstack(const Arg *arg) { 755// void focusstack(const Arg *arg) {
1040 Client *c = NULL, *i; 756// Client *c = NULL, *i;
1041 757//
1042 if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) 758// if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen))
1043 return; 759// return;
1044 if (arg->i > 0) { 760// if (arg->i > 0) {
1045 for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next) 761// for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next)
1046 ; 762// ;
1047 if (!c) 763// if (!c)
1048 for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next) 764// for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next)
1049 ; 765// ;
1050 } else { 766// } else {
1051 for (i = selmon->clients; i != selmon->sel; i = i->next) 767// for (i = selmon->clients; i != selmon->sel; i = i->next)
1052 if (ISVISIBLE(i)) 768// if (ISVISIBLE(i))
1053 c = i; 769// c = i;
1054 if (!c) 770// if (!c)
1055 for (; i; i = i->next) 771// for (; i; i = i->next)
1056 if (ISVISIBLE(i)) 772// if (ISVISIBLE(i))
1057 c = i; 773// c = i;
1058 } 774// }
1059 if (c) { 775// if (c) {
1060 focus(c); 776// focus(c);
1061 restack(selmon); 777// restack(selmon);
1062 } 778// }
1063} 779// }
1064 780
1065Atom getatomprop(Client *c, Atom prop) { 781Atom getatomprop(Client *c, Atom prop) {
1066 int di; 782 int di;
@@ -1185,10 +901,10 @@ void grabkeys(void) {
1185 } 901 }
1186} 902}
1187 903
1188void incnmaster(const Arg *arg) { 904// void incnmaster(const Arg *arg) {
1189 selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); 905// selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
1190 arrange(selmon); 906// arrange(selmon);
1191} 907// }
1192 908
1193#ifdef XINERAMA 909#ifdef XINERAMA
1194static int isuniquegeom(XineramaScreenInfo *unique, size_t n, 910static int isuniquegeom(XineramaScreenInfo *unique, size_t n,
@@ -1321,18 +1037,18 @@ void maprequest(XEvent *e) {
1321 manage(ev->window, &wa); 1037 manage(ev->window, &wa);
1322} 1038}
1323 1039
1324void monocle(Monitor *m) { 1040// void monocle(Monitor *m) {
1325 unsigned int n = 0; 1041// unsigned int n = 0;
1326 Client *c; 1042// Client *c;
1327 1043//
1328 for (c = m->clients; c; c = c->next) 1044// for (c = m->clients; c; c = c->next)
1329 if (ISVISIBLE(c)) 1045// if (ISVISIBLE(c))
1330 n++; 1046// n++;
1331 if (n > 0) /* override layout symbol */ 1047// if (n > 0) /* override layout symbol */
1332 snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); 1048// snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
1333 for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) 1049// for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
1334 resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); 1050// resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
1335} 1051// }
1336 1052
1337void motionnotify(XEvent *e) { 1053void motionnotify(XEvent *e) {
1338 static Monitor *mon = NULL; 1054 static Monitor *mon = NULL;
@@ -1742,64 +1458,64 @@ void setfullscreen(Client *c, int fullscreen) {
1742 } 1458 }
1743} 1459}
1744 1460
1745void setgaps(int oh, int ov, int ih, int iv) { 1461// void setgaps(int oh, int ov, int ih, int iv) {
1746 if (oh < 0) 1462// if (oh < 0)
1747 oh = 0; 1463// oh = 0;
1748 if (ov < 0) 1464// if (ov < 0)
1749 ov = 0; 1465// ov = 0;
1750 if (ih < 0) 1466// if (ih < 0)
1751 ih = 0; 1467// ih = 0;
1752 if (iv < 0) 1468// if (iv < 0)
1753 iv = 0; 1469// iv = 0;
1754 1470//
1755 selmon->gappoh = oh; 1471// selmon->gappoh = oh;
1756 selmon->gappov = ov; 1472// selmon->gappov = ov;
1757 selmon->gappih = ih; 1473// selmon->gappih = ih;
1758 selmon->gappiv = iv; 1474// selmon->gappiv = iv;
1759 arrange(selmon); 1475// arrange(selmon);
1760} 1476// }
1761 1477
1762void togglegaps(const Arg *arg) { 1478// void togglegaps(const Arg *arg) {
1763 enablegaps = !enablegaps; 1479// enablegaps = !enablegaps;
1764 arrange(selmon); 1480// arrange(selmon);
1765} 1481// }
1766 1482
1767void defaultgaps(const Arg *arg) { setgaps(gappoh, gappov, gappih, gappiv); } 1483// void defaultgaps(const Arg *arg) { setgaps(gappoh, gappov, gappih, gappiv); }
1768 1484//
1769void incrgaps(const Arg *arg) { 1485// void incrgaps(const Arg *arg) {
1770 setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, 1486// setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i,
1771 selmon->gappih + arg->i, selmon->gappiv + arg->i); 1487// selmon->gappih + arg->i, selmon->gappiv + arg->i);
1772} 1488// }
1773 1489//
1774void incrigaps(const Arg *arg) { 1490// void incrigaps(const Arg *arg) {
1775 setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, 1491// setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
1776 selmon->gappiv + arg->i); 1492// selmon->gappiv + arg->i);
1777} 1493// }
1778 1494//
1779void incrogaps(const Arg *arg) { 1495// void incrogaps(const Arg *arg) {
1780 setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih, 1496// setgaps(selmon->gappoh + arg->i, selmon->gappov + arg->i, selmon->gappih,
1781 selmon->gappiv); 1497// selmon->gappiv);
1782} 1498// }
1783 1499
1784void incrohgaps(const Arg *arg) { 1500// void incrohgaps(const Arg *arg) {
1785 setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih, 1501// setgaps(selmon->gappoh + arg->i, selmon->gappov, selmon->gappih,
1786 selmon->gappiv); 1502// selmon->gappiv);
1787} 1503// }
1788 1504//
1789void incrovgaps(const Arg *arg) { 1505// void incrovgaps(const Arg *arg) {
1790 setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih, 1506// setgaps(selmon->gappoh, selmon->gappov + arg->i, selmon->gappih,
1791 selmon->gappiv); 1507// selmon->gappiv);
1792} 1508// }
1793 1509//
1794void incrihgaps(const Arg *arg) { 1510// void incrihgaps(const Arg *arg) {
1795 setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i, 1511// setgaps(selmon->gappoh, selmon->gappov, selmon->gappih + arg->i,
1796 selmon->gappiv); 1512// selmon->gappiv);
1797} 1513// }
1798 1514//
1799void incrivgaps(const Arg *arg) { 1515// void incrivgaps(const Arg *arg) {
1800 setgaps(selmon->gappoh, selmon->gappov, selmon->gappih, 1516// setgaps(selmon->gappoh, selmon->gappov, selmon->gappih,
1801 selmon->gappiv + arg->i); 1517// selmon->gappiv + arg->i);
1802} 1518// }
1803 1519
1804void setlayout(const Arg *arg) { 1520void setlayout(const Arg *arg) {
1805 if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 1521 if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
@@ -1814,18 +1530,18 @@ void setlayout(const Arg *arg) {
1814 drawbar(selmon); 1530 drawbar(selmon);
1815} 1531}
1816 1532
1817/* arg > 1.0 will set mfact absolutely */ 1533// /* arg > 1.0 will set mfact absolutely */
1818void setmfact(const Arg *arg) { 1534// void setmfact(const Arg *arg) {
1819 float f; 1535// float f;
1820 1536//
1821 if (!arg || !selmon->lt[selmon->sellt]->arrange) 1537// if (!arg || !selmon->lt[selmon->sellt]->arrange)
1822 return; 1538// return;
1823 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 1539// f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
1824 if (f < 0.05 || f > 0.95) 1540// if (f < 0.05 || f > 0.95)
1825 return; 1541// return;
1826 selmon->mfact = f; 1542// selmon->mfact = f;
1827 arrange(selmon); 1543// arrange(selmon);
1828} 1544// }
1829 1545
1830void setup(void) { 1546void setup(void) {
1831 int i; 1547 int i;
@@ -1972,11 +1688,11 @@ void tag(const Arg *arg) {
1972 } 1688 }
1973} 1689}
1974 1690
1975void tagmon(const Arg *arg) { 1691// void tagmon(const Arg *arg) {
1976 if (!selmon->sel || !mons->next) 1692// if (!selmon->sel || !mons->next)
1977 return; 1693// return;
1978 sendmon(selmon->sel, dirtomon(arg->i)); 1694// sendmon(selmon->sel, dirtomon(arg->i));
1979} 1695// }
1980 1696
1981void tile(Monitor *m) { 1697void tile(Monitor *m) {
1982 unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty; 1698 unsigned int i, n, h, r, oe = enablegaps, ie = enablegaps, mw, my, ty;
diff --git a/src/core/dwm.h b/src/core/dwm.h
new file mode 100644
index 0000000..68eaf93
--- /dev/null
+++ b/src/core/dwm.h
@@ -0,0 +1,268 @@
1/* enums */
2enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
3enum { SchemeNorm, SchemeSel }; /* color schemes */
4enum {
5 NetSupported,
6 NetWMName,
7 NetWMState,
8 NetWMCheck,
9 NetSystemTray,
10 NetSystemTrayOP,
11 NetSystemTrayOrientation,
12 NetSystemTrayOrientationHorz,
13 NetWMFullscreen,
14 NetActiveWindow,
15 NetWMWindowType,
16 NetWMWindowTypeDialog,
17 NetClientList,
18 NetLast
19}; /* EWMH atoms */
20enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
21enum {
22 WMProtocols,
23 WMDelete,
24 WMState,
25 WMTakeFocus,
26 WMLast
27}; /* default atoms */
28enum {
29 ClkTagBar,
30 ClkLtSymbol,
31 ClkStatusText,
32 ClkWinTitle,
33 ClkClientWin,
34 ClkRootWin,
35 ClkLast
36}; /* clicks */
37
38typedef union {
39 int i;
40 unsigned int ui;
41 float f;
42 const void *v;
43} Arg;
44
45typedef struct {
46 unsigned int click;
47 unsigned int mask;
48 unsigned int button;
49 void (*func)(const Arg *arg);
50 const Arg arg;
51} Button;
52
53typedef struct Monitor Monitor;
54typedef struct Client Client;
55struct Client {
56 char name[256];
57 float mina, maxa;
58 int x, y, w, h;
59 int oldx, oldy, oldw, oldh;
60 int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
61 int bw, oldbw;
62 unsigned int tags;
63 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen,
64 isterminal, noswallow;
65 pid_t pid;
66 Client *next;
67 Client *snext;
68 Client *swallowing;
69 Monitor *mon;
70 Window win;
71};
72
73typedef struct {
74 unsigned int mod;
75 KeySym keysym;
76 void (*func)(const Arg *);
77 const Arg arg;
78} Key;
79
80typedef struct {
81 const char *symbol;
82 void (*arrange)(Monitor *);
83} Layout;
84
85struct Monitor {
86 char ltsymbol[16];
87 float mfact;
88 int nmaster;
89 int num;
90 int by; /* bar geometry */
91 int mx, my, mw, mh; /* screen size */
92 int wx, wy, ww, wh; /* window area */
93 int gappih; /* horizontal gap between windows */
94 int gappiv; /* vertical gap between windows */
95 int gappoh; /* horizontal outer gaps */
96 int gappov; /* vertical outer gaps */
97 unsigned int seltags;
98 unsigned int sellt;
99 unsigned int tagset[2];
100 int showbar;
101 int topbar;
102 Client *clients;
103 Client *sel;
104 Client *stack;
105 Monitor *next;
106 Window barwin;
107 const Layout *lt[2];
108};
109
110typedef struct {
111 const char *class;
112 const char *instance;
113 const char *title;
114 unsigned int tags;
115 int isfloating;
116 int isterminal;
117 int noswallow;
118 int monitor;
119} Rule;
120
121typedef struct Systray Systray;
122struct Systray {
123 Window win;
124 Client *icons;
125};
126
127/* function declarations */
128static void applyrules(Client *c);
129static int applysizehints(Client *c, int *x, int *y, int *w, int *h,
130 int interact);
131static void arrange(Monitor *m);
132static void arrangemon(Monitor *m);
133static void attach(Client *c);
134static void attachstack(Client *c);
135static void buttonpress(XEvent *e);
136static void checkotherwm(void);
137static void cleanup(void);
138static void cleanupmon(Monitor *mon);
139static void clientmessage(XEvent *e);
140static void configure(Client *c);
141static void configurenotify(XEvent *e);
142static void configurerequest(XEvent *e);
143static Monitor *createmon(void);
144static void destroynotify(XEvent *e);
145static void detach(Client *c);
146static void detachstack(Client *c);
147static void drawbar(Monitor *m);
148static void drawbars(void);
149static void enternotify(XEvent *e);
150static void expose(XEvent *e);
151static void focus(Client *c);
152static void focusin(XEvent *e);
153static Atom getatomprop(Client *c, Atom prop);
154static int getrootptr(int *x, int *y);
155static long getstate(Window w);
156static unsigned int getsystraywidth();
157static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
158static void grabbuttons(Client *c, int focused);
159static void grabkeys(void);
160static void keypress(XEvent *e);
161static void killclient(const Arg *arg);
162static void manage(Window w, XWindowAttributes *wa);
163static void mappingnotify(XEvent *e);
164static void maprequest(XEvent *e);
165static void motionnotify(XEvent *e);
166static void movemouse(const Arg *arg);
167static Client *nexttiled(Client *c);
168static void pop(Client *c);
169static void propertynotify(XEvent *e);
170static void quit(const Arg *arg);
171static Monitor *recttomon(int x, int y, int w, int h);
172static void removesystrayicon(Client *i);
173static void resize(Client *c, int x, int y, int w, int h, int interact);
174static void resizebarwin(Monitor *m);
175static void resizeclient(Client *c, int x, int y, int w, int h);
176static void resizemouse(const Arg *arg);
177static void resizerequest(XEvent *e);
178static void restack(Monitor *m);
179static void run(void);
180static void scan(void);
181static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2,
182 long d3, long d4);
183static void sendmon(Client *c, Monitor *m);
184static void setclientstate(Client *c, long state);
185static void setfocus(Client *c);
186static void setfullscreen(Client *c, int fullscreen);
187static void setlayout(const Arg *arg);
188static void setup(void);
189static void seturgent(Client *c, int urg);
190static void showhide(Client *c);
191static void spawn(const Arg *arg);
192static Monitor *systraytomon(Monitor *m);
193static void tag(const Arg *arg);
194static void tile(Monitor *m);
195static void togglebar(const Arg *arg);
196static void togglefloating(const Arg *arg);
197static void togglefullscr(const Arg *arg);
198static void toggletag(const Arg *arg);
199static void toggleview(const Arg *arg);
200static void unfocus(Client *c, int setfocus);
201static void unmanage(Client *c, int destroyed);
202static void unmapnotify(XEvent *e);
203static void updatebarpos(Monitor *m);
204static void updatebars(void);
205static void updateclientlist(void);
206static int updategeom(void);
207static void updatenumlockmask(void);
208static void updatesystray(void);
209static void updatesystrayicongeom(Client *i, int w, int h);
210static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
211static void updatesizehints(Client *c);
212static void updatestatus(void);
213static void updatetitle(Client *c);
214static void updatewindowtype(Client *c);
215static void updatewmhints(Client *c);
216static void view(const Arg *arg);
217static Client *wintoclient(Window w);
218static Monitor *wintomon(Window w);
219static Client *wintosystrayicon(Window w);
220static int xerror(Display *dpy, XErrorEvent *ee);
221static int xerrordummy(Display *dpy, XErrorEvent *ee);
222static int xerrorstart(Display *dpy, XErrorEvent *ee);
223static void zoom(const Arg *arg);
224
225static pid_t getparentprocess(pid_t p);
226static int isdescprocess(pid_t p, pid_t c);
227static Client *swallowingclient(Window w);
228static Client *termforwin(const Client *c);
229static pid_t winpid(Window w);
230
231/* variables */
232static Systray *systray = NULL;
233static const char broken[] = "broken";
234static char stext[256];
235static int screen;
236static int sw, sh; /* X display screen geometry width, height */
237static int bh; /* bar height */
238static int enablegaps = 1; /* enables gaps, used by togglegaps */
239static int lrpad; /* sum of left and right padding for text */
240static int (*xerrorxlib)(Display *, XErrorEvent *);
241static unsigned int numlockmask = 0;
242static void (*handler[LASTEvent])(XEvent *) = {
243 [ButtonPress] = buttonpress,
244 [ClientMessage] = clientmessage,
245 [ConfigureRequest] = configurerequest,
246 [ConfigureNotify] = configurenotify,
247 [DestroyNotify] = destroynotify,
248 [EnterNotify] = enternotify,
249 [Expose] = expose,
250 [FocusIn] = focusin,
251 [KeyPress] = keypress,
252 [MappingNotify] = mappingnotify,
253 [MapRequest] = maprequest,
254 [MotionNotify] = motionnotify,
255 [PropertyNotify] = propertynotify,
256 [ResizeRequest] = resizerequest,
257 [UnmapNotify] = unmapnotify};
258
259static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast];
260static int running = 1;
261static Cur *cursor[CurLast];
262static Clr **scheme;
263static Display *dpy;
264static Drw *drw;
265static Monitor *mons, *selmon;
266static Window root, wmcheckwin;
267
268static xcb_connection_t *xcon;