aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/autostart/autostart.c18
-rw-r--r--modules/autostart/autostart.h1
-rw-r--r--modules/betterresize/betterresize.c124
-rw-r--r--modules/directionalfocus/directionalfocus.c113
-rw-r--r--modules/directionalfocus/directionalfocus.h1
-rw-r--r--modules/directionalmove/directionalmove.c84
-rw-r--r--modules/directionalmove/directionalmove.h1
-rw-r--r--modules/etf/etf.c91
-rw-r--r--modules/etf/etf.h1
-rw-r--r--modules/ewmh_tags/ewmh_tags.c42
-rw-r--r--modules/ewmh_tags/ewmh_tags.h8
-rw-r--r--modules/externalbars/externalbars.c195
-rw-r--r--modules/externalbars/externalbars.h18
-rw-r--r--modules/fullscreen/fullscreen.c6
-rw-r--r--modules/fullscreen/fullscreen.h1
-rw-r--r--modules/gaps/gaps.c9
-rw-r--r--modules/gaps/gaps.h1
-rw-r--r--modules/infinitetags/infinitetags.c218
-rw-r--r--modules/infinitetags/infinitetags.h7
-rw-r--r--modules/moveresizekbd/moveresizekbd.c160
-rw-r--r--modules/moveresizekbd/moveresizekbd.h1
-rw-r--r--modules/vxwm_includes.c57
-rw-r--r--modules/vxwm_includes.h53
-rw-r--r--modules/warptoclient/warptoclient.c15
-rw-r--r--modules/warptoclient/warptoclient.h1
-rw-r--r--modules/windowmap/windowmap.c42
-rw-r--r--modules/windowmap/windowmap.h3
-rw-r--r--modules/xrdb/xrdb.c42
-rw-r--r--modules/xrdb/xrdb.h20
29 files changed, 1333 insertions, 0 deletions
diff --git a/modules/autostart/autostart.c b/modules/autostart/autostart.c
new file mode 100644
index 0000000..d947972
--- /dev/null
+++ b/modules/autostart/autostart.c
@@ -0,0 +1,18 @@
+void
+runautostart(void)
+{
+ const char *const *cmd = autostart;
+
+ if (fork() == 0) {
+ setsid();
+
+ while (*cmd != NULL) {
+ if (fork() == 0) {
+ execl("/bin/sh", "sh", "-c", *cmd, NULL);
+ exit(1);
+ }
+ cmd++;
+ }
+ exit(0);
+ }
+}
diff --git a/modules/autostart/autostart.h b/modules/autostart/autostart.h
new file mode 100644
index 0000000..10a6f88
--- /dev/null
+++ b/modules/autostart/autostart.h
@@ -0,0 +1 @@
+static void runautostart(void);
diff --git a/modules/betterresize/betterresize.c b/modules/betterresize/betterresize.c
new file mode 100644
index 0000000..d35f0c0
--- /dev/null
+++ b/modules/betterresize/betterresize.c
@@ -0,0 +1,124 @@
+void
+resizemouse(const Arg *arg)
+{
+ Client *c;
+ Monitor *m;
+ XEvent ev;
+#if LOCK_MOVE_RESIZE_REFRESH_RATE
+ Time lasttime = 0;
+#endif
+ if (!(c = selmon->sel) || c->isfullscreen)
+ return;
+
+ restack(selmon);
+
+ int orig_x = c->x;
+ int orig_y = c->y;
+ int orig_w = c->w;
+ int orig_h = c->h;
+
+ int rx, ry;
+ Window junkwin;
+ int junk_signed;
+ unsigned int junk;
+ if (!XQueryPointer(dpy, c->win, &junkwin, &junkwin, &junk_signed, &junk_signed, &rx, &ry, &junk))
+ return;
+ int left = rx < orig_w / 3;
+ int right = rx > orig_w * 2 / 3;
+ int top = ry < orig_h / 3;
+ int bottom = ry > orig_h * 2 / 3;
+#if BR_CHANGE_CURSOR
+ Cursor cur;
+ if (top && left) cur = cursor[CurNW]->cursor;
+ else if (top && right) cur = cursor[CurNE]->cursor;
+ else if (bottom && left) cur = cursor[CurSW]->cursor;
+ else if (bottom && right) cur = cursor[CurSE]->cursor;
+ else if (top) cur = cursor[CurN]->cursor;
+ else if (bottom) cur = cursor[CurS]->cursor;
+ else if (left) cur = cursor[CurW]->cursor;
+ else if (right) cur = cursor[CurE]->cursor;
+ else cur = cursor[CurResize]->cursor; // fallback
+#else
+ Cursor cur = cursor[CurResize]->cursor;
+#endif
+ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+ None, cur, CurrentTime) != GrabSuccess)
+ return;
+ do {
+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+
+ if (ev.type == MotionNotify) {
+#if LOCK_MOVE_RESIZE_REFRESH_RATE
+ if (ev.xmotion.time - lasttime <= (1000 / refreshrate))
+ continue;
+ lasttime = ev.xmotion.time;
+#endif
+ int dx = ev.xmotion.x_root - (orig_x + rx);
+ int dy = ev.xmotion.y_root - (orig_y + ry);
+
+ int nx = orig_x;
+ int ny = orig_y;
+ int nw = orig_w;
+ int nh = orig_h;
+
+ if (left) nw = orig_w - dx;
+ else if (right) nw = orig_w + dx;
+
+ if (top) nh = orig_h - dy;
+ else if (bottom) nh = orig_h + dy;
+
+ int min_w = MAX(1, c->minw);
+ int min_h = MAX(1, c->minh);
+
+ if (nw < min_w) nw = min_w;
+ if (nh < min_h) nh = min_h;
+
+ if (left) nx = orig_x + (orig_w - nw);
+ if (top) ny = orig_y + (orig_h - nh);
+
+ int dx_final = nw - orig_w;
+ int dy_final = nh - orig_h;
+#if !RESIZINIG_WINDOWS_IN_ALL_LAYOUTS_FLOATS_THEM
+ if (!c->isfloating && selmon->lt[selmon->sellt]->arrange &&
+ (abs(dx_final) > snap || abs(dy_final) > snap)) {
+#else
+ if (!c->isfloating && (abs(dx_final) > snap || abs(dy_final) > snap)) {
+#endif
+ if (nx >= selmon->wx && nx + nw <= selmon->wx + selmon->ww &&
+ ny >= selmon->wy && ny + nh <= selmon->wy + selmon->wh) {
+
+ togglefloating(NULL);
+
+ orig_x = c->x;
+ orig_y = c->y;
+ orig_w = c->w;
+ orig_h = c->h;
+ }
+ }
+#if USE_RESIZECLIENT_FUNC
+ resizeclient(c, nx, ny, nw, nh);
+#else
+ resize(c, nx, ny, nw, nh, 1);
+#endif
+ drawbar(selmon); //fix for issue 1
+ }
+ } while (ev.type != ButtonRelease);
+
+ XUngrabPointer(dpy, CurrentTime);
+ while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+
+ if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
+ sendmon(c, m);
+ selmon = m;
+ focus(NULL);
+ }
+#if ENHANCED_TOGGLE_FLOATING && RESTORE_SIZE_AND_POS_ETF
+ c->wasmanuallyedited = 1;
+ if (c->isfloating) {
+ c->sfx = c->x;
+ c->sfy = c->y;
+ c->sfw = c->w;
+ c->sfh = c->h;
+ }
+#endif
+}
diff --git a/modules/directionalfocus/directionalfocus.c b/modules/directionalfocus/directionalfocus.c
new file mode 100644
index 0000000..5d1ebcb
--- /dev/null
+++ b/modules/directionalfocus/directionalfocus.c
@@ -0,0 +1,113 @@
+void
+focusdir(const Arg *arg)
+{
+ Client *s = selmon->sel, *f = NULL, *c, *next;
+
+ if (!s)
+ return;
+
+ unsigned int score = -1;
+ unsigned int client_score;
+ int isfloating = s->isfloating;
+
+ next = s->next;
+ if (!next)
+ next = s->mon->clients;
+ for (c = next; c != s; c = next) {
+
+ next = c->next;
+ if (!next)
+ next = s->mon->clients;
+
+ if (!ISVISIBLE(c) || c->isfloating != isfloating)
+ continue;
+
+#if INFINITE_TAGS
+ if (selmon->lt[selmon->sellt]->arrange == NULL) {
+
+ int s_cx = s->x + s->w / 2;
+ int s_cy = s->y + s->h / 2;
+ int c_cx = c->x + c->w / 2;
+ int c_cy = c->y + c->h / 2;
+
+ int dx = c_cx - s_cx; /* positive = c is to the right */
+ int dy = c_cy - s_cy; /* positive = c is below */
+
+ int axial, lateral;
+
+ switch (arg->i) {
+ case 0: /* left */
+ if (dx >= 0) continue;
+ axial = -dx;
+ lateral = abs(dy);
+ break;
+ case 1: /* right */
+ if (dx <= 0) continue;
+ axial = dx;
+ lateral = abs(dy);
+ break;
+ case 2: /* up */
+ if (dy >= 0) continue;
+ axial = -dy;
+ lateral = abs(dx);
+ break;
+ default:
+ case 3: /* down */
+ if (dy <= 0) continue;
+ axial = dy;
+ lateral = abs(dx);
+ break;
+ }
+
+ client_score = axial + (unsigned int)((long)lateral * lateral) / (axial + 1);
+ } else
+#endif
+ {
+ int dist;
+ int dirweight = 20;
+ switch (arg->i) {
+ case 0:
+ dist = s->x - c->x - c->w;
+ client_score =
+ dirweight * abs(dist) +
+ abs(s->y - c->y);
+ break;
+ case 1:
+ dist = c->x - s->x - s->w;
+ client_score =
+ dirweight * abs(dist) +
+ abs(c->y - s->y);
+ break;
+ case 2:
+ dist = s->y - c->y - c->h;
+ client_score =
+ dirweight * abs(dist) +
+ abs(s->x - c->x);
+ break;
+ default:
+ case 3:
+ dist = c->y - s->y - s->h;
+ client_score =
+ dirweight * abs(dist) +
+ abs(c->x - s->x);
+ break;
+ }
+ }
+
+ if (client_score < score) {
+ score = client_score;
+ f = c;
+ }
+ }
+
+ if (f && f != s) {
+ focus(f);
+#if INFINITE_TAGS
+ centerwindow(NULL);
+#endif
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_FOCUSSTACK
+ warptoclient(f);
+#endif
+ restack(f->mon);
+ }
+}
diff --git a/modules/directionalfocus/directionalfocus.h b/modules/directionalfocus/directionalfocus.h
new file mode 100644
index 0000000..773341a
--- /dev/null
+++ b/modules/directionalfocus/directionalfocus.h
@@ -0,0 +1 @@
+static void focusdir(const Arg *arg);
diff --git a/modules/directionalmove/directionalmove.c b/modules/directionalmove/directionalmove.c
new file mode 100644
index 0000000..d83c792
--- /dev/null
+++ b/modules/directionalmove/directionalmove.c
@@ -0,0 +1,84 @@
+void
+movedir(const Arg *arg)
+{
+ if (selmon->lt[selmon->sellt]->arrange != tile) return;
+ Client *s = selmon->sel, *f = NULL, *c, *next;
+ if (!s)
+ return;
+ unsigned int score = -1;
+ unsigned int client_score;
+ int dist;
+ int dirweight = 20;
+ int isfloating = s->isfloating;
+ next = s->next;
+ if (!next)
+ next = s->mon->clients;
+ for (c = next; c != s; c = next) {
+ next = c->next;
+ if (!next)
+ next = s->mon->clients;
+ if (!ISVISIBLE(c) || c->isfloating != isfloating)
+ continue;
+ switch (arg->i) {
+ case 0: // left
+ dist = s->x - c->x - c->w;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
+ abs(s->y - c->y);
+ break;
+ case 1: // right
+ dist = c->x - s->x - s->w;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) +
+ abs(c->y - s->y);
+ break;
+ case 2: // up
+ dist = s->y - c->y - c->h;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
+ abs(s->x - c->x);
+ break;
+ default:
+ case 3: // down
+ dist = c->y - s->y - s->h;
+ client_score =
+ dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) +
+ abs(c->x - s->x);
+ break;
+ }
+ if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) {
+ score = client_score;
+ f = c;
+ }
+ }
+ if (!f || f == s)
+ return;
+
+ Client *ps = NULL, *pf = NULL, *p;
+ for (p = s->mon->clients; p; p = p->next) {
+ if (p->next == s) ps = p;
+ if (p->next == f) pf = p;
+ }
+
+ if (s->next == f) {
+ if (ps) ps->next = f; else s->mon->clients = f;
+ s->next = f->next;
+ f->next = s;
+ } else if (f->next == s) {
+ if (pf) pf->next = s; else s->mon->clients = s;
+ f->next = s->next;
+ s->next = f;
+ } else {
+ if (ps) ps->next = f; else s->mon->clients = f;
+ if (pf) pf->next = s; else s->mon->clients = s;
+ Client *tmp = s->next;
+ s->next = f->next;
+ f->next = tmp;
+ }
+
+ focus(s);
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_FOCUSSTACK
+ warptoclient(f);
+#endif
+ arrange(s->mon);
+}
diff --git a/modules/directionalmove/directionalmove.h b/modules/directionalmove/directionalmove.h
new file mode 100644
index 0000000..69e9f0f
--- /dev/null
+++ b/modules/directionalmove/directionalmove.h
@@ -0,0 +1 @@
+static void movedir(const Arg *arg);
diff --git a/modules/etf/etf.c b/modules/etf/etf.c
new file mode 100644
index 0000000..dfb69fe
--- /dev/null
+++ b/modules/etf/etf.c
@@ -0,0 +1,91 @@
+#if !RESTORE_SIZE_AND_POS_ETF
+void
+enhancedtogglefloating(const Arg *arg)
+{
+ if (!selmon->sel || selmon->sel->isfullscreen)
+ return;
+ Client *c = selmon->sel;
+ const Layout *prevlayout = selmon->lt[selmon->sellt];
+ c->isfloating = !c->isfloating;
+ if (c->isfloating) {
+ int w = c->sfw > 0 ? c->sfw : c->w;
+ int h = c->sfh > 0 ? c->sfh : c->h;
+ resize(c,
+ c->mon->wx + (c->mon->ww - w) / 2,
+ c->mon->wy + (c->mon->wh - h) / 2,
+ w, h, 0);
+ } else {
+ int tiled_sellt = -1;
+ for (int i = 0; i < LENGTH(layouts); i++) {
+ if (selmon->lt[i]->arrange != NULL) {
+ tiled_sellt = i;
+ break;
+ }
+ }
+ if (tiled_sellt != -1) {
+ selmon->sellt = tiled_sellt;
+ arrange(selmon);
+ }
+ for (int i = 0; i < LENGTH(layouts); i++) {
+ if (selmon->lt[i] == prevlayout) {
+ selmon->sellt = i;
+ break;
+ }
+ }
+ }
+ arrange(selmon);
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_ENHANCED_TOGGLE_FLOATING
+ warptoclient(selmon->sel);
+#endif
+}
+#else
+void
+enhancedtogglefloating(const Arg *arg)
+{
+ if (!selmon->sel || selmon->sel->isfullscreen)
+ return;
+ Client *c = selmon->sel;
+ const Layout *prevlayout = selmon->lt[selmon->sellt];
+ c->isfloating = !c->isfloating;
+ if (c->isfloating) {
+ int w = c->sfw > 0 ? c->sfw : c->w;
+ int h = c->sfh > 0 ? c->sfh : c->h;
+ if (!c->wasmanuallyedited) {
+ resize(c,
+ c->mon->wx + (c->mon->ww - w) / 2,
+ c->mon->wy + (c->mon->wh - h) / 2,
+ w, h, 0);
+ } else {
+ resize(c, c->sfx, c->sfy, w, h, 0);
+ }
+ c->sfx = c->x; c->sfy = c->y;
+ c->sfw = c->w; c->sfh = c->h;
+ } else {
+ c->sfx = c->x;
+ c->sfy = c->y;
+ c->sfw = c->w;
+ c->sfh = c->h;
+ int tiled_sellt = -1;
+ for (int i = 0; i < LENGTH(layouts); i++) {
+ if (selmon->lt[i]->arrange != NULL) {
+ tiled_sellt = i;
+ break;
+ }
+ }
+ if (tiled_sellt != -1) {
+ selmon->sellt = tiled_sellt;
+ arrange(selmon);
+ }
+ for (int i = 0; i < LENGTH(layouts); i++) {
+ if (selmon->lt[i] == prevlayout) {
+ selmon->sellt = i;
+ break;
+ }
+ }
+ }
+ arrange(selmon);
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_AFFECTED_BY_ENHANCED_TOGGLE_FLOATING
+ warptoclient(selmon->sel);
+#endif
+}
+#endif
diff --git a/modules/etf/etf.h b/modules/etf/etf.h
new file mode 100644
index 0000000..9b2b127
--- /dev/null
+++ b/modules/etf/etf.h
@@ -0,0 +1 @@
+static void enhancedtogglefloating(const Arg *arg);
diff --git a/modules/ewmh_tags/ewmh_tags.c b/modules/ewmh_tags/ewmh_tags.c
new file mode 100644
index 0000000..12e8e26
--- /dev/null
+++ b/modules/ewmh_tags/ewmh_tags.c
@@ -0,0 +1,42 @@
+void
+setcurrentdesktop(void){
+ long data[] = { 0 };
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
+
+void setdesktopnames(void){
+ XTextProperty text;
+ Xutf8TextListToTextProperty(dpy, (char **)tags, TAGSLENGTH, XUTF8StringStyle, &text);
+ XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
+}
+
+void
+setnumdesktops(void){
+ long data[] = { TAGSLENGTH };
+ XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
+
+void
+setviewport(void){
+ long data[] = { 0, 0 };
+ XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
+}
+
+void
+updatecurrentdesktop(void){
+ long rawdata[] = { selmon->tagset[selmon->seltags] };
+ int i=0;
+ while(*rawdata >> (i+1)){
+ i++;
+ }
+ long data[] = { i };
+ XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
+}
+
+void
+updatewmdesktop(Client *c)
+{
+ unsigned long desktop = c->tags ? ffs(c->tags) - 1 : 0;
+ XChangeProperty(dpy, c->win, netatom[NetDesktopNum], XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char *)&desktop, 1);
+}
diff --git a/modules/ewmh_tags/ewmh_tags.h b/modules/ewmh_tags/ewmh_tags.h
new file mode 100644
index 0000000..74137c8
--- /dev/null
+++ b/modules/ewmh_tags/ewmh_tags.h
@@ -0,0 +1,8 @@
+#define TAGSLENGTH (LENGTH(tags))
+
+static void setcurrentdesktop(void);
+static void setdesktopnames(void);
+static void setnumdesktops(void);
+static void setviewport(void);
+static void updatecurrentdesktop(void);
+static void updatewmdesktop(Client *c); \ No newline at end of file
diff --git a/modules/externalbars/externalbars.c b/modules/externalbars/externalbars.c
new file mode 100644
index 0000000..b84fe06
--- /dev/null
+++ b/modules/externalbars/externalbars.c
@@ -0,0 +1,195 @@
+static ExternalBarStrut *ebarstruts = NULL;
+static Atom eb_atom_strut = None;
+static Atom eb_atom_strut_partial = None;
+static int eb_scanning = 0;
+
+void
+externalbars_init_atoms(void)
+{
+ if (eb_atom_strut == None)
+ eb_atom_strut = XInternAtom(dpy, "_NET_WM_STRUT", False);
+ if (eb_atom_strut_partial == None)
+ eb_atom_strut_partial = XInternAtom(dpy, "_NET_WM_STRUT_PARTIAL", False);
+}
+
+int
+externalbars_read(Window w, ExternalBarStrut *out)
+{
+ Atom real;
+ int fmt;
+ unsigned long n, extra;
+ unsigned char *p = NULL;
+
+ externalbars_init_atoms();
+ memset(out, 0, sizeof *out);
+ out->win = w;
+
+ /* Prefer _NET_WM_STRUT_PARTIAL (12 longs) */
+ if (XGetWindowProperty(dpy, w, eb_atom_strut_partial, 0L, 12L, False,
+ XA_CARDINAL, &real, &fmt, &n, &extra, &p) == Success && p) {
+ if (n >= 4) {
+ long *s = (long *)p;
+ out->left = (int)s[0]; out->right = (int)s[1];
+ out->top = (int)s[2]; out->bottom = (int)s[3];
+ if (n >= 12) {
+ out->left_start_y = (int)s[4]; out->left_end_y = (int)s[5];
+ out->right_start_y = (int)s[6]; out->right_end_y = (int)s[7];
+ out->top_start_x = (int)s[8]; out->top_end_x = (int)s[9];
+ out->bottom_start_x = (int)s[10]; out->bottom_end_x = (int)s[11];
+ } else {
+ out->left_start_y = 0; out->left_end_y = sh;
+ out->right_start_y = 0; out->right_end_y = sh;
+ out->top_start_x = 0; out->top_end_x = sw;
+ out->bottom_start_x = 0; out->bottom_end_x = sw;
+ }
+ XFree(p);
+ if (out->left == 0 && out->right == 0 &&
+ out->top == 0 && out->bottom == 0)
+ return 0;
+ return 1;
+ }
+ XFree(p);
+ p = NULL;
+ }
+
+ /* Fallback: plain _NET_WM_STRUT (4 longs) */
+ if (XGetWindowProperty(dpy, w, eb_atom_strut, 0L, 4L, False,
+ XA_CARDINAL, &real, &fmt, &n, &extra, &p) == Success && p) {
+ if (n >= 4) {
+ long *s = (long *)p;
+ out->left = (int)s[0]; out->right = (int)s[1];
+ out->top = (int)s[2]; out->bottom = (int)s[3];
+ out->left_start_y = 0; out->left_end_y = sh;
+ out->right_start_y = 0; out->right_end_y = sh;
+ out->top_start_x = 0; out->top_end_x = sw;
+ out->bottom_start_x = 0; out->bottom_end_x = sw;
+ XFree(p);
+ if (out->left == 0 && out->right == 0 &&
+ out->top == 0 && out->bottom == 0)
+ return 0;
+ return 1;
+ }
+ XFree(p);
+ }
+ return 0;
+}
+
+int
+externalbars_hasstrut(Window w)
+{
+ ExternalBarStrut tmp;
+ return externalbars_read(w, &tmp);
+}
+
+void
+externalbars_begin_scan(void)
+{
+ eb_scanning = 1;
+}
+
+void
+externalbars_end_scan(void)
+{
+ eb_scanning = 0;
+ externalbars_reapply_all();
+}
+
+void
+externalbars_register(Window w)
+{
+ ExternalBarStrut tmp, *sw;
+
+ if (!externalbars_read(w, &tmp))
+ return;
+
+ for (sw = ebarstruts; sw; sw = sw->next) {
+ if (sw->win == w) {
+ ExternalBarStrut *nxt = sw->next;
+ *sw = tmp;
+ sw->next = nxt;
+ if (!eb_scanning)
+ externalbars_reapply_all();
+ return;
+ }
+ }
+
+ sw = ecalloc(1, sizeof(ExternalBarStrut));
+ *sw = tmp;
+ sw->next = ebarstruts;
+ ebarstruts = sw;
+ if (!eb_scanning)
+ externalbars_reapply_all();
+}
+
+void
+externalbars_unregister(Window w)
+{
+ ExternalBarStrut **prev = &ebarstruts, *sw;
+
+ while ((sw = *prev)) {
+ if (sw->win == w) {
+ *prev = sw->next;
+ free(sw);
+ if (!eb_scanning)
+ externalbars_reapply_all();
+ return;
+ }
+ prev = &sw->next;
+ }
+}
+
+void
+externalbars_apply(Monitor *m)
+{
+ ExternalBarStrut *s;
+ int top = 0, bottom = 0, left = 0, right = 0;
+
+ for (s = ebarstruts; s; s = s->next) {
+ if (s->top > 0) {
+ if (s->top_start_x < m->mx + m->mw && s->top_end_x > m->mx) {
+ int local = s->top - m->my;
+ if (local > 0)
+ top = MAX(top, MIN(local, m->mh));
+ }
+ }
+ if (s->bottom > 0) {
+ if (s->bottom_start_x < m->mx + m->mw && s->bottom_end_x > m->mx) {
+ int local = s->bottom - (sh - (m->my + m->mh));
+ if (local > 0)
+ bottom = MAX(bottom, MIN(local, m->mh));
+ }
+ }
+ if (s->left > 0) {
+ if (s->left_start_y < m->my + m->mh && s->left_end_y > m->my) {
+ int local = s->left - m->mx;
+ if (local > 0)
+ left = MAX(left, MIN(local, m->mw));
+ }
+ }
+ if (s->right > 0) {
+ if (s->right_start_y < m->my + m->mh && s->right_end_y > m->my) {
+ int local = s->right - (sw - (m->mx + m->mw));
+ if (local > 0)
+ right = MAX(right, MIN(local, m->mw));
+ }
+ }
+ }
+
+ m->strut_top = top;
+ m->strut_bottom = bottom;
+ m->strut_left = left;
+ m->strut_right = right;
+}
+
+void
+externalbars_reapply_all(void)
+{
+ Monitor *m;
+
+ for (m = mons; m; m = m->next) {
+ externalbars_apply(m);
+ updatebarpos(m);
+ }
+ if (selmon)
+ arrange(NULL);
+}
diff --git a/modules/externalbars/externalbars.h b/modules/externalbars/externalbars.h
new file mode 100644
index 0000000..3e80185
--- /dev/null
+++ b/modules/externalbars/externalbars.h
@@ -0,0 +1,18 @@
+typedef struct ExternalBarStrut ExternalBarStrut;
+struct ExternalBarStrut {
+ Window win;
+ int left, right, top, bottom;
+ int left_start_y, left_end_y;
+ int right_start_y, right_end_y;
+ int top_start_x, top_end_x;
+ int bottom_start_x, bottom_end_x;
+ ExternalBarStrut *next;
+};
+
+static void externalbars_begin_scan(void);
+static void externalbars_end_scan(void);
+static int externalbars_hasstrut(Window w);
+static void externalbars_register(Window w);
+static void externalbars_unregister(Window w);
+static void externalbars_apply(Monitor *m);
+static void externalbars_reapply_all(void);
diff --git a/modules/fullscreen/fullscreen.c b/modules/fullscreen/fullscreen.c
new file mode 100644
index 0000000..3b36575
--- /dev/null
+++ b/modules/fullscreen/fullscreen.c
@@ -0,0 +1,6 @@
+void
+togglefullscr(const Arg *arg)
+{
+ if(selmon->sel)
+ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
+}
diff --git a/modules/fullscreen/fullscreen.h b/modules/fullscreen/fullscreen.h
new file mode 100644
index 0000000..37e5b2d
--- /dev/null
+++ b/modules/fullscreen/fullscreen.h
@@ -0,0 +1 @@
+static void togglefullscr(const Arg *arg);
diff --git a/modules/gaps/gaps.c b/modules/gaps/gaps.c
new file mode 100644
index 0000000..2e501dd
--- /dev/null
+++ b/modules/gaps/gaps.c
@@ -0,0 +1,9 @@
+void
+setgaps(const Arg *arg)
+{
+ if ((arg->i == 0) || (selmon->gappx + arg->i < 0))
+ selmon->gappx = 0;
+ else
+ selmon->gappx += arg->i;
+ arrange(selmon);
+}
diff --git a/modules/gaps/gaps.h b/modules/gaps/gaps.h
new file mode 100644
index 0000000..2bf4000
--- /dev/null
+++ b/modules/gaps/gaps.h
@@ -0,0 +1 @@
+static void setgaps(const Arg *arg);
diff --git a/modules/infinitetags/infinitetags.c b/modules/infinitetags/infinitetags.c
new file mode 100644
index 0000000..2b08f94
--- /dev/null
+++ b/modules/infinitetags/infinitetags.c
@@ -0,0 +1,218 @@
+int
+getcurrenttag(Monitor *m) {
+ unsigned int i;
+ for (i = 0; i < LENGTH(tags) && !(m->tagset[m->seltags] & (1 << i)); i++);
+ return i < LENGTH(tags) ? i : 0;
+}
+
+void
+homecanvas(const Arg *arg) {
+ Client *c;
+ int tagidx = getcurrenttag(selmon);
+ int cx = selmon->canvas[tagidx].cx;
+ int cy = selmon->canvas[tagidx].cy;
+
+ for (c = selmon->clients; c; c = c->next) {
+ if (c->tags & (1 << tagidx)) {
+ c->x -= cx;
+ c->y -= cy;
+ XMoveWindow(dpy, c->win, c->x, c->y);
+ }
+ }
+
+ selmon->canvas[tagidx].cx = 0;
+ selmon->canvas[tagidx].cy = 0;
+ drawbar(selmon);
+ XFlush(dpy);
+}
+
+void
+movecanvas(const Arg *arg)
+{
+ if (selmon->lt[selmon->sellt]->arrange != NULL)
+ return;
+ if (selmon->sel && selmon->sel->isfullscreen)
+ return;
+
+ int tagidx = getcurrenttag(selmon);
+ int dx = 0, dy = 0;
+
+#ifndef MOVE_CANVAS_STEP
+#define MOVE_CANVAS_STEP 120
+#endif
+
+ switch(arg->i) {
+ case 0: dx = -MOVE_CANVAS_STEP; break;
+ case 1: dx = MOVE_CANVAS_STEP; break;
+ case 2: dy = -MOVE_CANVAS_STEP; break;
+ case 3: dy = MOVE_CANVAS_STEP; break;
+ }
+
+ selmon->canvas[tagidx].cx -= dx;
+ selmon->canvas[tagidx].cy -= dy;
+
+ Client *c;
+ for (c = selmon->clients; c; c = c->next) {
+ if (ISVISIBLE(c)) {
+ c->x -= dx;
+ c->y -= dy;
+ XMoveWindow(dpy, c->win, c->x, c->y);
+ }
+ }
+
+ drawbar(selmon);
+}
+
+void
+movecanvasmouse(const Arg *arg) {
+ if (selmon->lt[selmon->sellt]->arrange != NULL)
+ return;
+ if (selmon->sel && selmon->sel->isfullscreen)
+ return;
+ int start_x, start_y;
+ Window dummy;
+ int di;
+ unsigned int dui;
+ int tagidx = getcurrenttag(selmon);
+ float multiplier = arg ? arg->f : 1.0f;
+ float accum_x = 0.0f, accum_y = 0.0f;
+
+#if LOCK_MOVE_RESIZE_REFRESH_RATE
+ Time lasttime = 0;
+#endif
+
+ if (!XQueryPointer(dpy, root, &dummy, &dummy, &start_x, &start_y, &di, &di, &dui))
+ return;
+
+ if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+ None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
+ return;
+
+ XEvent ev;
+ do {
+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+
+ switch (ev.type) {
+ case MotionNotify:
+ {
+#if LOCK_MOVE_RESIZE_REFRESH_RATE
+ if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate))
+ continue;
+ lasttime = ev.xmotion.time;
+#endif
+ int nx = ev.xmotion.x - start_x;
+ int ny = ev.xmotion.y - start_y;
+
+ /* accumulate subpixel remainder to not lose fractional pixels:
+ multiplier=0.5, nx=1: accum=0.5, dx=0 --- skip
+ nx=1: accum=1.0, dx=1 --- move
+ */
+ accum_x += nx * multiplier;
+ accum_y += ny * multiplier;
+
+ int dx = (int)accum_x;
+ int dy = (int)accum_y;
+
+ accum_x -= dx;
+ accum_y -= dy;
+
+ for (Client *c = selmon->clients; c; c = c->next) {
+ if (c->tags & (1 << tagidx)) {
+ c->x += dx;
+ c->y += dy;
+ XMoveWindow(dpy, c->win, c->x, c->y);
+ }
+ }
+
+ selmon->canvas[tagidx].cx += dx;
+ selmon->canvas[tagidx].cy += dy;
+ drawbar(selmon);
+ start_x = ev.xmotion.x;
+ start_y = ev.xmotion.y;
+ } break;
+ }
+ } while (ev.type != ButtonRelease);
+
+ XUngrabPointer(dpy, CurrentTime);
+}
+
+void
+save_canvas_positions(Monitor *m) {
+ Client *c;
+ int tagidx = getcurrenttag(m);
+
+ m->canvas[tagidx].saved_cx = m->canvas[tagidx].cx;
+ m->canvas[tagidx].saved_cy = m->canvas[tagidx].cy;
+
+ for (c = m->clients; c; c = c->next) {
+ if (ISVISIBLE(c)) {
+ c->saved_cx = c->x + m->canvas[tagidx].cx;
+ c->saved_cy = c->y + m->canvas[tagidx].cy;
+ c->saved_cw = c->w;
+ c->saved_ch = c->h;
+ c->was_on_canvas = 1;
+ }
+ }
+}
+
+void
+restore_canvas_positions(Monitor *m) {
+ Client *c;
+ int tagidx = getcurrenttag(m);
+
+ m->canvas[tagidx].cx = m->canvas[tagidx].saved_cx;
+ m->canvas[tagidx].cy = m->canvas[tagidx].saved_cy;
+
+ for (c = m->clients; c; c = c->next) {
+ if (ISVISIBLE(c) && c->was_on_canvas) {
+ if (c->isfullscreen)
+ continue;
+ c->isfloating = 1;
+
+ int target_x = c->saved_cx - m->canvas[tagidx].cx;
+ int target_y = c->saved_cy - m->canvas[tagidx].cy;
+
+ c->x = target_x;
+ c->y = target_y;
+ c->w = c->saved_cw;
+ c->h = c->saved_ch;
+
+ XMoveResizeWindow(dpy, c->win, target_x, target_y, c->w, c->h);
+
+ configure(c);
+ }
+ }
+ XSync(dpy, False);
+}
+
+void
+centerwindow(const Arg *arg)
+{
+ Client *c = (arg && arg->v) ? (Client *)arg->v : selmon->sel;
+
+ if (!c || !c->mon || c->mon->lt[c->mon->sellt]->arrange != NULL)
+ return;
+
+ Monitor *m = c->mon;
+ int tagidx = getcurrenttag(m);
+
+ int dx = (m->wx + m->ww - WIDTH(c)) / 2 - c->x;
+ int dy = m->wy + (m->wh / 2) - (c->y + HEIGHT(c) / 2);
+
+ if (dx == 0 && dy == 0)
+ return;
+
+ Client *tmp;
+ for (tmp = m->clients; tmp; tmp = tmp->next) {
+ if (ISVISIBLE(tmp)) {
+ tmp->x += dx;
+ tmp->y += dy;
+ XMoveWindow(dpy, tmp->win, tmp->x, tmp->y);
+ }
+ }
+
+ m->canvas[tagidx].cx += dx;
+ m->canvas[tagidx].cy += dy;
+
+ drawbar(m);
+}
diff --git a/modules/infinitetags/infinitetags.h b/modules/infinitetags/infinitetags.h
new file mode 100644
index 0000000..e3cc64e
--- /dev/null
+++ b/modules/infinitetags/infinitetags.h
@@ -0,0 +1,7 @@
+static void movecanvas(const Arg *arg);
+static void movecanvasmouse(const Arg *arg);
+static void homecanvas(const Arg *arg);
+static int getcurrenttag(Monitor *m);
+static void save_canvas_positions(Monitor *m);
+static void restore_canvas_positions(Monitor *m);
+static void centerwindow(const Arg *arg);
diff --git a/modules/moveresizekbd/moveresizekbd.c b/modules/moveresizekbd/moveresizekbd.c
new file mode 100644
index 0000000..5105de4
--- /dev/null
+++ b/modules/moveresizekbd/moveresizekbd.c
@@ -0,0 +1,160 @@
+#if !INFINITE_TAGS
+void
+moveresize(const Arg *arg)
+{
+ if (selmon->sel && selmon->sel->isfullscreen)
+ return;
+ XEvent ev;
+ Monitor *m = selmon;
+
+ if(!(m->sel && arg && arg->v && m->sel->isfloating)) {
+
+#if DIRECTIONAL_MOVE
+ if (((int *)arg->v)[0] != 0 || ((int *)arg->v)[1] != 0) {
+ if (((int *)arg->v)[1] > 0) movedir(&(Arg){.i = 3}); // Down
+ if (((int *)arg->v)[1] < 0) movedir(&(Arg){.i = 2}); // Up
+ if (((int *)arg->v)[0] > 0) movedir(&(Arg){.i = 1}); // Right
+ if (((int *)arg->v)[0] < 0) movedir(&(Arg){.i = 0}); // Left
+ }
+#endif
+ return;
+ }
+
+ XRaiseWindow(dpy, m->sel->win);
+
+ resize(m->sel, m->sel->x + ((int *)arg->v)[0],
+ m->sel->y + ((int *)arg->v)[1],
+ m->sel->w + ((int *)arg->v)[2],
+ m->sel->h + ((int *)arg->v)[3],
+ True);
+
+#if ENHANCED_TOGGLE_FLOATING && RESTORE_SIZE_AND_POS_ETF
+ if (m->sel->isfloating) {
+ m->sel->wasmanuallyedited = 1;
+ m->sel->sfx = m->sel->x;
+ m->sel->sfy = m->sel->y;
+ m->sel->sfw = m->sel->w;
+ m->sel->sfh = m->sel->h;
+ }
+#endif
+
+ focus(m->sel);
+
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_MOVED_BY_KEYBOARD
+ warptoclient(m->sel);
+#endif
+
+ while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+}
+
+#else
+
+
+void
+moveresize(const Arg *arg)
+{
+ if (selmon->sel && selmon->sel->isfullscreen)
+ return;
+ int dx = ((int *)arg->v)[0];
+ int dy = ((int *)arg->v)[1];
+ int dw = ((int *)arg->v)[2];
+ int dh = ((int *)arg->v)[3];
+
+ XEvent ev;
+ Monitor *m = selmon;
+
+ if (!m->sel || !arg || !arg->v)
+ return;
+
+ if (!m->sel->isfloating) {
+#if DIRECTIONAL_MOVE
+ if (selmon->lt[selmon->sellt]->arrange != NULL && (dx || dy)) {
+ if (dy > 0) movedir(&(Arg){.i = 3}); // Down
+ if (dy < 0) movedir(&(Arg){.i = 2}); // Up
+ if (dx > 0) movedir(&(Arg){.i = 1}); // Right
+ if (dx < 0) movedir(&(Arg){.i = 0}); // Left
+ }
+#endif
+ return;
+ }
+
+
+ Client *c = m->sel;
+
+ XRaiseWindow(dpy, c->win);
+
+ if (selmon->lt[selmon->sellt]->arrange != NULL) {
+ resize(c,
+ c->x + dx,
+ c->y + dy,
+ c->w + dw,
+ c->h + dh,
+ True);
+ }
+ else {
+ int nx = c->x + dx;
+ int ny = c->y + dy;
+ int nw = c->w + dw;
+ int nh = c->h + dh;
+ int canvas_dx = 0, canvas_dy = 0;
+ int tagidx = getcurrenttag(m);
+
+ if (dx || dy) {
+ if (nx < m->wx) {
+ canvas_dx = nx - m->wx;
+ nx = m->wx;
+ } else if (nx + nw + 2 * c->bw > m->wx + m->ww) {
+ canvas_dx = (nx + nw + 2 * c->bw) - (m->wx + m->ww);
+ nx = m->wx + m->ww - nw - 2 * c->bw;
+ }
+
+ if (ny < m->wy) {
+ canvas_dy = ny - m->wy;
+ ny = m->wy;
+ } else if (ny + nh + 2 * c->bw > m->wy + m->wh) {
+ canvas_dy = (ny + nh + 2 * c->bw) - (m->wy + m->wh);
+ ny = m->wy + m->wh - nh - 2 * c->bw;
+ }
+
+ if (canvas_dx || canvas_dy) {
+ m->canvas[tagidx].cx -= canvas_dx;
+ m->canvas[tagidx].cy -= canvas_dy;
+
+ Client *tmp;
+ for (tmp = m->clients; tmp; tmp = tmp->next) {
+ if (ISVISIBLE(tmp) && tmp != c) {
+ tmp->x -= canvas_dx;
+ tmp->y -= canvas_dy;
+ XMoveWindow(dpy, tmp->win, tmp->x, tmp->y);
+ }
+ }
+ }
+ }
+
+ resize(c, nx, ny, nw, nh, True);
+ }
+
+#if ENHANCED_TOGGLE_FLOATING && RESTORE_SIZE_AND_POS_ETF
+ if (c->isfloating) {
+ c->wasmanuallyedited = 1;
+ c->sfx = c->x;
+ c->sfy = c->y;
+ c->sfw = c->w;
+ c->sfh = c->h;
+ }
+#endif
+
+ focus(c);
+
+#if WARP_TO_CLIENT && WARP_TO_CENTER_OF_WINDOW_MOVED_BY_KEYBOARD
+ warptoclient(c);
+#endif
+
+ while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
+
+#if IT_SHOW_COORDINATES_IN_BAR
+ drawbar(m);
+#endif
+
+}
+#endif
diff --git a/modules/moveresizekbd/moveresizekbd.h b/modules/moveresizekbd/moveresizekbd.h
new file mode 100644
index 0000000..de565eb
--- /dev/null
+++ b/modules/moveresizekbd/moveresizekbd.h
@@ -0,0 +1 @@
+static void moveresize(const Arg *arg);
diff --git a/modules/vxwm_includes.c b/modules/vxwm_includes.c
new file mode 100644
index 0000000..6bd0fea
--- /dev/null
+++ b/modules/vxwm_includes.c
@@ -0,0 +1,57 @@
+#pragma once
+
+#if GAPS
+#include "gaps/gaps.c"
+#endif
+
+#if XRDB
+#include "xrdb/xrdb.c"
+#endif
+
+#if FULLSCREEN
+#include "fullscreen/fullscreen.c"
+#endif
+
+#if EWMH_TAGS
+#include "ewmh_tags/ewmh_tags.c"
+#endif
+
+#if WARP_TO_CLIENT
+#include "warptoclient/warptoclient.c"
+#endif
+
+#if ENHANCED_TOGGLE_FLOATING
+#include "etf/etf.c"
+#endif
+
+#if BETTER_RESIZE
+#include "betterresize/betterresize.c"
+#endif
+
+#if WINDOWMAP
+#include "windowmap/windowmap.c"
+#endif
+
+#if INFINITE_TAGS
+#include "infinitetags/infinitetags.c"
+#endif
+
+#if MOVE_RESIZE_WITH_KEYBOARD
+#include "moveresizekbd/moveresizekbd.c"
+#endif
+
+#if DIRECTIONAL_FOCUS
+#include "directionalfocus/directionalfocus.c"
+#endif
+
+#if DIRECTIONAL_MOVE
+#include "directionalmove/directionalmove.c"
+#endif
+
+#if AUTOSTART
+#include "autostart/autostart.c"
+#endif
+
+#if EXTERNAL_BARS
+#include "externalbars/externalbars.c"
+#endif
diff --git a/modules/vxwm_includes.h b/modules/vxwm_includes.h
new file mode 100644
index 0000000..b4c09a9
--- /dev/null
+++ b/modules/vxwm_includes.h
@@ -0,0 +1,53 @@
+#pragma once
+
+#if GAPS
+#include "gaps/gaps.h"
+#endif
+
+#if XRDB
+#include "xrdb/xrdb.h"
+#endif
+
+#if FULLSCREEN
+#include "fullscreen/fullscreen.h"
+#endif
+
+#if EWMH_TAGS
+#include "ewmh_tags/ewmh_tags.h"
+#endif
+
+#if WARP_TO_CLIENT
+#include "warptoclient/warptoclient.h"
+#endif
+
+#if ENHANCED_TOGGLE_FLOATING
+#include "etf/etf.h"
+#endif
+
+#if WINDOWMAP
+#include "windowmap/windowmap.h"
+#endif
+
+#if INFINITE_TAGS
+#include "infinitetags/infinitetags.h"
+#endif
+
+#if MOVE_RESIZE_WITH_KEYBOARD
+#include "moveresizekbd/moveresizekbd.h"
+#endif
+
+#if DIRECTIONAL_FOCUS
+#include "directionalfocus/directionalfocus.h"
+#endif
+
+#if DIRECTIONAL_MOVE
+#include "directionalmove/directionalmove.h"
+#endif
+
+#if AUTOSTART
+#include "autostart/autostart.h"
+#endif
+
+#if EXTERNAL_BARS
+#include "externalbars/externalbars.h"
+#endif
diff --git a/modules/warptoclient/warptoclient.c b/modules/warptoclient/warptoclient.c
new file mode 100644
index 0000000..fbedeaa
--- /dev/null
+++ b/modules/warptoclient/warptoclient.c
@@ -0,0 +1,15 @@
+void
+warptoclient(Client *c)
+{
+ int x, y;
+
+ if (!c) {
+ XWarpPointer(dpy, None, root, 0, 0, 0, 0, selmon->wx + selmon->ww/2, selmon->wy + selmon->wh/2);
+ return;
+ }
+
+ x = c->x + WIDTH(c) / 2;
+ y = c->y + HEIGHT(c) / 2;
+
+ XWarpPointer(dpy, None, root, 0, 0, 0, 0, x, y);
+}
diff --git a/modules/warptoclient/warptoclient.h b/modules/warptoclient/warptoclient.h
new file mode 100644
index 0000000..0017968
--- /dev/null
+++ b/modules/warptoclient/warptoclient.h
@@ -0,0 +1 @@
+static void warptoclient(Client *c);
diff --git a/modules/windowmap/windowmap.c b/modules/windowmap/windowmap.c
new file mode 100644
index 0000000..ef76153
--- /dev/null
+++ b/modules/windowmap/windowmap.c
@@ -0,0 +1,42 @@
+void
+window_set_state(Display *dpy, Window win, long state)
+{
+ long data[] = { state, None };
+
+ XChangeProperty(dpy, win, wmatom[WMState], wmatom[WMState], 32,
+ PropModeReplace, (unsigned char*)data, 2);
+}
+
+void
+window_map(Display *dpy, Client *c, int deiconify)
+{
+ Window win = c->win;
+
+ if (deiconify)
+ window_set_state(dpy, win, NormalState);
+
+ XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
+ XMapWindow(dpy, win);
+ focus(NULL);
+}
+
+void
+window_unmap(Display *dpy, Window win, Window root, int iconify)
+{
+ static XWindowAttributes ca, ra;
+
+ XGetWindowAttributes(dpy, root, &ra);
+ XGetWindowAttributes(dpy, win, &ca);
+
+ /* Prevent UnmapNotify events */
+ XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
+ XSelectInput(dpy, win, ca.your_event_mask & ~StructureNotifyMask);
+
+ XUnmapWindow(dpy, win);
+ focus(NULL);
+ if (iconify)
+ window_set_state(dpy, win, IconicState);
+
+ XSelectInput(dpy, root, ra.your_event_mask);
+ XSelectInput(dpy, win, ca.your_event_mask);
+}
diff --git a/modules/windowmap/windowmap.h b/modules/windowmap/windowmap.h
new file mode 100644
index 0000000..993b83a
--- /dev/null
+++ b/modules/windowmap/windowmap.h
@@ -0,0 +1,3 @@
+static void window_set_state(Display *dpy, Window win, long state);
+static void window_map(Display *dpy, Client *c, int deiconify);
+static void window_unmap(Display *dpy, Window win, Window root, int iconify);
diff --git a/modules/xrdb/xrdb.c b/modules/xrdb/xrdb.c
new file mode 100644
index 0000000..556c6b8
--- /dev/null
+++ b/modules/xrdb/xrdb.c
@@ -0,0 +1,42 @@
+void
+loadxrdb()
+{
+ Display *display;
+ char * resm;
+ XrmDatabase xrdb;
+ char *type;
+ XrmValue value;
+
+ display = XOpenDisplay(NULL);
+
+ if (display != NULL) {
+ resm = XResourceManagerString(display);
+
+ if (resm != NULL) {
+ xrdb = XrmGetStringDatabase(resm);
+
+ if (xrdb != NULL) {
+ XRDB_LOAD_COLOR("dwm.color0", normbordercolor);
+ XRDB_LOAD_COLOR("dwm.color8", selbordercolor);
+ XRDB_LOAD_COLOR("dwm.color0", normbgcolor);
+ XRDB_LOAD_COLOR("dwm.color6", normfgcolor);
+ XRDB_LOAD_COLOR("dwm.color0", selfgcolor);
+ XRDB_LOAD_COLOR("dwm.color14", selbgcolor);
+ }
+ }
+ }
+
+ XCloseDisplay(display);
+}
+
+void
+xrdb(const Arg *arg)
+{
+ loadxrdb();
+ int i;
+ for (i = 0; i < LENGTH(colors); i++)
+ scheme[i] = drw_scm_create(drw, colors[i], 3);
+ focus(NULL);
+ arrange(NULL);
+}
+
diff --git a/modules/xrdb/xrdb.h b/modules/xrdb/xrdb.h
new file mode 100644
index 0000000..aa7006f
--- /dev/null
+++ b/modules/xrdb/xrdb.h
@@ -0,0 +1,20 @@
+#include <X11/Xresource.h>
+
+#define XRDB_LOAD_COLOR(R,V) if (XrmGetResource(xrdb, R, NULL, &type, &value) == True) { \
+ if (value.addr != NULL && strnlen(value.addr, 8) == 7 && value.addr[0] == '#') { \
+ int i = 1; \
+ for (; i <= 6; i++) { \
+ if (value.addr[i] < 48) break; \
+ if (value.addr[i] > 57 && value.addr[i] < 65) break; \
+ if (value.addr[i] > 70 && value.addr[i] < 97) break; \
+ if (value.addr[i] > 102) break; \
+ } \
+ if (i == 7) { \
+ strncpy(V, value.addr, 7); \
+ V[7] = '\0'; \
+ } \
+ } \
+ }
+
+static void loadxrdb(void);
+static void xrdb(const Arg *arg);