commit be256b3d89258718ba4b680f536ee7ee613cf14d
parent 8af5dd28ac62b5f824e7ce8667daccda3b622a23
Author: hhvn <hayden@haydenvh.com>
Date: Thu, 26 Nov 2020 20:25:35 +0000
makefile dwm-6.2.diff[NEW]: provide history
Diffstat:
D | Makefile | | | 51 | --------------------------------------------------- |
A | dwm-6.2.diff | | | 1111 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | makefile | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 1165 insertions(+), 51 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,51 +0,0 @@
-# dwm - dynamic window manager
-# See LICENSE file for copyright and license details.
-
-include config.mk
-
-SRC = drw.c dwm.c util.c
-OBJ = ${SRC:.c=.o}
-
-all: options dwm
-
-options:
- @echo dwm build options:
- @echo "CFLAGS = ${CFLAGS}"
- @echo "LDFLAGS = ${LDFLAGS}"
- @echo "CC = ${CC}"
-
-.c.o:
- ${CC} -c ${CFLAGS} $<
-
-${OBJ}: config.h config.mk
-
-config.h:
- cp config.def.h $@
-
-dwm: ${OBJ}
- ${CC} -o $@ ${OBJ} ${LDFLAGS}
-
-clean:
- rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
-
-dist: clean
- mkdir -p dwm-${VERSION}
- cp -R LICENSE Makefile README config.def.h config.mk\
- dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
- tar -cf dwm-${VERSION}.tar dwm-${VERSION}
- gzip dwm-${VERSION}.tar
- rm -rf dwm-${VERSION}
-
-install: all
- mkdir -p ${DESTDIR}${PREFIX}/bin
- cp -f dwm ${DESTDIR}${PREFIX}/bin
- chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
- mkdir -p ${DESTDIR}${MANPREFIX}/man1
- sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-uninstall:
- rm -f ${DESTDIR}${PREFIX}/bin/dwm\
- ${DESTDIR}${MANPREFIX}/man1/dwm.1
-
-.PHONY: all options clean dist install uninstall
diff --git a/dwm-6.2.diff b/dwm-6.2.diff
@@ -0,0 +1,1111 @@
+diff --git a/LICENSE b/LICENSE
+index d221f09..a5a021d 100644
+--- a/LICENSE
++++ b/LICENSE
+@@ -17,6 +17,7 @@ MIT/X Consortium License
+ © 2015-2016 Quentin Rameau <quinq@fifth.space>
+ © 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
+ © 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
++(C) 2019-Present - Forked by Hayden Hamilton <hayden@haydenvh.com>
+
+ Permission is hereby granted, free of charge, to any person obtaining a
+ copy of this software and associated documentation files (the "Software"),
+diff --git a/config.h b/config.h
+new file mode 100644
+index 0000000..6ac0d79
+--- /dev/null
++++ b/config.h
+@@ -0,0 +1,97 @@
++/* See LICENSE file for copyright and license details. */
++
++/* appearance */
++static const unsigned int borderpx = 2; /* border pixel of windows */
++static const unsigned int gappx = 10;
++static const unsigned int snap = 1; /* snap pixel */
++static const int showbar = 1; /* 0 means no bar */
++static const int topbar = 1; /* 0 means bottom bar */
++static const char *fonts[] = { "monospace:size=8" };
++static const char *colors[][3] = {
++ /* fg bg border */
++ [SchemeNorm] = { "#bbbbbb", "#0a0a10", "#0a0a10" },
++ [SchemeSel] = { "#eeeeee", "#30404e", "#892b2b" },
++ [SchemeStat] = { "#eeeeee", "#0a2126", "#0a2126" },
++ [SchemeNormWin] = { "#bbbbbb", "#24284c", "#0a0a10" },
++ [SchemeUrgent] = { "#892b2b", "#0a0a10", "#0a0a10" },
++};
++
++/* tagging */
++static const char *tags[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX" };
++
++static const Rule rules[] = {
++ { "Gimp", NULL, NULL, 1 << 7, 0, 0 },
++ { "mpv", NULL, NULL, 1 << 1, 0, 0 },
++ { "mpvrcp", NULL, NULL, 1 << 0, 1, 0 },
++};
++
++/* layout(s) */
++static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
++static const int nmaster = 1; /* number of clients in master area */
++static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
++
++static const Layout layouts[] = {
++ /* symbol arrange function */
++ { "|=", tile }, /* first entry is default */
++ { ".:", NULL }, /* no layout function means floating behavior */
++ { "M", monocle },
++ { "@", spiral },
++ { "#=", dwindle },
++ { "=#=", centeredmaster },
++ { "=:=", centeredfloatingmaster },
++};
++
++/* key definitions */
++#define MODKEY Mod4Mask
++#define AltMask Mod1Mask
++#define TAGKEYS(KEY,TAG) \
++ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \
++ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
++ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
++ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
++#define LAYOUT(KEY, LAYOUT) \
++ { MODKEY|AltMask, KEY, setlayout, {.v = &layouts[LAYOUT]} },
++
++/* helper for spawning shell commands in the pre dwm-5.0 fashion */
++#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
++
++static Key keys[] = {
++ /* modifier key function argument */
++ { MODKEY|ShiftMask, XK_Return, zoom, {0} },
++ { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
++ { MODKEY, XK_Tab, view, {0} },
++ { MODKEY, XK_f, togglefullscr, {0} },
++ { MODKEY, XK_h, setmfact, {.f = -0.05} },
++ { MODKEY, XK_i, incnmaster, {.i = +1 } },
++ { MODKEY, XK_j, focusstack, {.i = +1 } },
++ { MODKEY, XK_k, focusstack, {.i = -1 } },
++ { MODKEY, XK_l, setmfact, {.f = +0.05 } },
++ { MODKEY, XK_p, incnmaster, {.i = -1 } },
++ { MODKEY, XK_q, killclient, {0} },
++ { MODKEY|ShiftMask, XK_q, quit, {0} },
++ { MODKEY, XK_0, view, {.ui = ~0 } },
++ { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
++ { MODKEY, XK_comma, focusmon, {.i = -1 } },
++ { MODKEY, XK_period, focusmon, {.i = +1 } },
++ { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } },
++ { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } },
++ /* Layout */
++ LAYOUT( XK_1, 0)
++ LAYOUT( XK_2, 1)
++ LAYOUT( XK_3, 3)
++ LAYOUT( XK_4, 4)
++ LAYOUT( XK_5, 5)
++ LAYOUT( XK_6, 6)
++ LAYOUT( XK_7, 7)
++ LAYOUT( XK_0, 2)
++ /* Tags */
++ TAGKEYS( XK_1, 0)
++ TAGKEYS( XK_2, 1)
++ TAGKEYS( XK_3, 2)
++ TAGKEYS( XK_4, 3)
++ TAGKEYS( XK_5, 4)
++ TAGKEYS( XK_6, 5)
++ TAGKEYS( XK_7, 6)
++ TAGKEYS( XK_8, 7)
++ TAGKEYS( XK_9, 8)
++};
+diff --git a/dwm.c b/dwm.c
+index 4465af1..09f86e7 100644
+--- a/dwm.c
++++ b/dwm.c
+@@ -30,12 +30,14 @@
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
++#include <sys/stat.h>
+ #include <X11/cursorfont.h>
+ #include <X11/keysym.h>
+ #include <X11/Xatom.h>
+ #include <X11/Xlib.h>
+ #include <X11/Xproto.h>
+ #include <X11/Xutil.h>
++#include <X11/Xft/Xft.h>
+ #ifdef XINERAMA
+ #include <X11/extensions/Xinerama.h>
+ #endif /* XINERAMA */
+@@ -49,8 +51,15 @@
+ #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
+ #define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
+ * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
+-#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
++#define ISVISIBLEONTAG(C, T) ((C->tags & T))
++#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags])
+ #define LENGTH(X) (sizeof X / sizeof X[0])
++#ifndef MAX
++#define MAX(A, B) ((A) > (B) ? (A) : (B))
++#endif
++#ifndef MIN
++#define MIN(A, B) ((A) < (B) ? (A) : (B))
++#endif
+ #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
+ #define WIDTH(X) ((X)->w + 2 * (X)->bw)
+ #define HEIGHT(X) ((X)->h + 2 * (X)->bw)
+@@ -59,13 +68,11 @@
+
+ /* enums */
+ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
+-enum { SchemeNorm, SchemeSel }; /* color schemes */
++enum { SchemeNorm, SchemeSel, SchemeStat, SchemeNormWin, SchemeUrgent }; /* color schemes */
+ enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
+ NetWMFullscreen, NetActiveWindow, NetWMWindowType,
+ NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
+ enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */
+-enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
+- ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
+
+ typedef union {
+ int i;
+@@ -77,7 +84,6 @@ typedef union {
+ typedef struct {
+ unsigned int click;
+ unsigned int mask;
+- unsigned int button;
+ void (*func)(const Arg *arg);
+ const Arg arg;
+ } Button;
+@@ -117,8 +123,11 @@ struct Monitor {
+ int nmaster;
+ int num;
+ int by; /* bar geometry */
++ int btw; /* width of tasks portion of bar */
++ int bt; /* number of tasks */
+ int mx, my, mw, mh; /* screen size */
+ int wx, wy, ww, wh; /* window area */
++ int gappx; /* gaps between windows */
+ unsigned int seltags;
+ unsigned int sellt;
+ unsigned int tagset[2];
+@@ -147,8 +156,8 @@ static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interac
+ static void arrange(Monitor *m);
+ static void arrangemon(Monitor *m);
+ static void attach(Client *c);
++static void attachaside(Client *c);
+ static void attachstack(Client *c);
+-static void buttonpress(XEvent *e);
+ static void checkotherwm(void);
+ static void cleanup(void);
+ static void cleanupmon(Monitor *mon);
+@@ -163,6 +172,7 @@ static void detachstack(Client *c);
+ static Monitor *dirtomon(int dir);
+ static void drawbar(Monitor *m);
+ static void drawbars(void);
++static int drawstatusbar(Monitor *m, int bh, char* text);
+ static void enternotify(XEvent *e);
+ static void expose(XEvent *e);
+ static void focus(Client *c);
+@@ -172,7 +182,6 @@ static void focusstack(const Arg *arg);
+ static int getrootptr(int *x, int *y);
+ static long getstate(Window w);
+ static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
+-static void grabbuttons(Client *c, int focused);
+ static void grabkeys(void);
+ static void incnmaster(const Arg *arg);
+ static void keypress(XEvent *e);
+@@ -182,7 +191,7 @@ static void mappingnotify(XEvent *e);
+ static void maprequest(XEvent *e);
+ static void monocle(Monitor *m);
+ static void motionnotify(XEvent *e);
+-static void movemouse(const Arg *arg);
++static Client *nexttagged(Client *c);
+ static Client *nexttiled(Client *c);
+ static void pop(Client *);
+ static void propertynotify(XEvent *e);
+@@ -190,7 +199,6 @@ static void quit(const Arg *arg);
+ static Monitor *recttomon(int x, int y, int w, int h);
+ static void resize(Client *c, int x, int y, int w, int h, int interact);
+ static void resizeclient(Client *c, int x, int y, int w, int h);
+-static void resizemouse(const Arg *arg);
+ static void restack(Monitor *m);
+ static void run(void);
+ static void scan(void);
+@@ -199,6 +207,7 @@ static void sendmon(Client *c, Monitor *m);
+ static void setclientstate(Client *c, long state);
+ static void setfocus(Client *c);
+ static void setfullscreen(Client *c, int fullscreen);
++//static void setgaps(const Arg *arg);
+ static void setlayout(const Arg *arg);
+ static void setmfact(const Arg *arg);
+ static void setup(void);
+@@ -209,8 +218,9 @@ static void spawn(const Arg *arg);
+ static void tag(const Arg *arg);
+ static void tagmon(const Arg *arg);
+ static void tile(Monitor *);
+-static void togglebar(const Arg *arg);
++//static void togglebar(const Arg *arg);
+ static void togglefloating(const Arg *arg);
++static void togglefullscr(const Arg *arg);
+ static void toggletag(const Arg *arg);
+ static void toggleview(const Arg *arg);
+ static void unfocus(Client *c, int setfocus);
+@@ -233,18 +243,24 @@ static int xerror(Display *dpy, XErrorEvent *ee);
+ static int xerrordummy(Display *dpy, XErrorEvent *ee);
+ static int xerrorstart(Display *dpy, XErrorEvent *ee);
+ static void zoom(const Arg *arg);
++static void centeredmaster(Monitor *m);
++static void centeredfloatingmaster(Monitor *m);
++static void spiral(Monitor *mon);
++static void dwindle(Monitor *mon);
++static void fibonacci(Monitor *mon, int s);
+
+ /* variables */
+ static const char broken[] = "broken";
+-static char stext[256];
++static char stext[1024];
+ static int screen;
+ static int sw, sh; /* X display screen geometry width, height */
+ static int bh, blw = 0; /* bar geometry */
+ static int lrpad; /* sum of left and right padding for text */
++static int sidepad;
++static int vertpad;
+ static int (*xerrorxlib)(Display *, XErrorEvent *);
+ static unsigned int numlockmask = 0;
+ static void (*handler[LASTEvent]) (XEvent *) = {
+- [ButtonPress] = buttonpress,
+ [ClientMessage] = clientmessage,
+ [ConfigureRequest] = configurerequest,
+ [ConfigureNotify] = configurenotify,
+@@ -407,52 +423,21 @@ attach(Client *c)
+ }
+
+ void
+-attachstack(Client *c)
+-{
+- c->snext = c->mon->stack;
+- c->mon->stack = c;
++attachaside(Client *c) {
++ Client *at = nexttagged(c);
++ if(!at) {
++ attach(c);
++ return;
++ }
++ c->next = at->next;
++ at->next = c;
+ }
+
+ void
+-buttonpress(XEvent *e)
++attachstack(Client *c)
+ {
+- unsigned int i, x, click;
+- Arg arg = {0};
+- Client *c;
+- Monitor *m;
+- XButtonPressedEvent *ev = &e->xbutton;
+-
+- click = ClkRootWin;
+- /* focus monitor if necessary */
+- if ((m = wintomon(ev->window)) && m != selmon) {
+- unfocus(selmon->sel, 1);
+- selmon = m;
+- focus(NULL);
+- }
+- if (ev->window == selmon->barwin) {
+- i = x = 0;
+- do
+- x += TEXTW(tags[i]);
+- while (ev->x >= x && ++i < LENGTH(tags));
+- if (i < LENGTH(tags)) {
+- click = ClkTagBar;
+- arg.ui = 1 << i;
+- } else if (ev->x < x + blw)
+- click = ClkLtSymbol;
+- else if (ev->x > selmon->ww - TEXTW(stext))
+- click = ClkStatusText;
+- else
+- click = ClkWinTitle;
+- } else if ((c = wintoclient(ev->window))) {
+- focus(c);
+- restack(selmon);
+- XAllowEvents(dpy, ReplayPointer, CurrentTime);
+- click = ClkClientWin;
+- }
+- for (i = 0; i < LENGTH(buttons); i++)
+- if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
+- && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
+- buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg);
++ c->snext = c->mon->stack;
++ c->mon->stack = c;
+ }
+
+ void
+@@ -484,7 +469,7 @@ cleanup(void)
+ cleanupmon(mons);
+ for (i = 0; i < CurLast; i++)
+ drw_cur_free(drw, cursor[i]);
+- for (i = 0; i < LENGTH(colors); i++)
++ for (i = 0; i < LENGTH(colors) + 1; i++)
+ free(scheme[i]);
+ XDestroyWindow(dpy, wmcheckwin);
+ drw_free(drw);
+@@ -567,7 +552,7 @@ configurenotify(XEvent *e)
+ for (c = m->clients; c; c = c->next)
+ if (c->isfullscreen)
+ resizeclient(c, m->mx, m->my, m->mw, m->mh);
+- XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh);
++ XMoveResizeWindow(dpy, m->barwin, m->wx + sidepad, m->by + vertpad, m->ww - 2*sidepad, bh);
+ }
+ focus(NULL);
+ arrange(NULL);
+@@ -638,6 +623,7 @@ createmon(void)
+ m->nmaster = nmaster;
+ m->showbar = showbar;
+ m->topbar = topbar;
++ m->gappx = gappx;
+ m->lt[0] = &layouts[0];
+ m->lt[1] = &layouts[1 % LENGTH(layouts)];
+ strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
+@@ -692,23 +678,129 @@ dirtomon(int dir)
+ return m;
+ }
+
++int
++drawstatusbar(Monitor *m, int bh, char* stext) {
++ int ret, i, w, x, len;
++ short isCode = 0;
++ char *text;
++ char *p;
++
++ len = strlen(stext) + 1 ;
++ if (!(text = (char*) malloc(sizeof(char)*len)))
++ die("malloc");
++ p = text;
++ memcpy(text, stext, len);
++
++ /* compute width of the status text */
++ w = 0;
++ i = -1;
++ while (text[++i]) {
++ if (text[i] == '^') {
++ if (!isCode) {
++ isCode = 1;
++ text[i] = '\0';
++ w += TEXTW(text) - lrpad;
++ text[i] = '^';
++ if (text[++i] == 'f')
++ w += atoi(text + ++i);
++ } else {
++ isCode = 0;
++ text = text + i + 1;
++ i = -1;
++ }
++ }
++ }
++ if (!isCode)
++ w += TEXTW(text) - lrpad;
++ else
++ isCode = 0;
++ text = p;
++
++ w += 2; /* 1px padding on both sides */
++ ret = x = m->ww - w;
++
++ drw_setscheme(drw, scheme[LENGTH(colors)]);
++ drw->scheme[ColFg] = scheme[SchemeStat][ColFg];
++ drw_rect(drw, x, 0, w, bh, 1, 1);
++ x++;
++
++ /* process status text */
++ i = -1;
++ while (text[++i]) {
++ if (text[i] == '^' && !isCode) {
++ isCode = 1;
++
++ text[i] = '\0';
++ w = TEXTW(text) - lrpad;
++ drw_text(drw, x, 0, w, bh, 0, text, 0);
++
++ x += w;
++
++ /* process code */
++ while (text[++i] != '^') {
++ if (text[i] == 'c') {
++ char buf[8];
++ memcpy(buf, (char*)text+i+1, 7);
++ buf[7] = '\0';
++ drw_clr_create(drw, &drw->scheme[ColFg], buf);
++ i += 7;
++ } else if (text[i] == 'b') {
++ char buf[8];
++ memcpy(buf, (char*)text+i+1, 7);
++ buf[7] = '\0';
++ drw_clr_create(drw, &drw->scheme[ColBg], buf);
++ i += 7;
++ } else if (text[i] == 'd') {
++ drw->scheme[ColFg] = scheme[SchemeStat][ColFg];
++ drw->scheme[ColBg] = scheme[SchemeStat][ColBg];
++ } else if (text[i] == 'r') {
++ int rx = atoi(text + ++i);
++ while (text[++i] != ',');
++ int ry = atoi(text + ++i);
++ while (text[++i] != ',');
++ int rw = atoi(text + ++i);
++ while (text[++i] != ',');
++ int rh = atoi(text + ++i);
++
++ drw_rect(drw, rx + x, ry, rw, rh, 1, 0);
++ } else if (text[i] == 'f') {
++ x += atoi(text + ++i);
++ }
++ }
++
++ text = text + i + 1;
++ i=-1;
++ isCode = 0;
++ }
++ }
++
++ drw->scheme[ColBg] = scheme[SchemeStat][ColBg];
++ if (!isCode) {
++ w = TEXTW(text) - lrpad;
++ drw_text(drw, x, 0, w, bh, 0, text, 0);
++ }
++
++ free(p);
++
++ return ret;
++}
++
+ void
+ drawbar(Monitor *m)
+ {
+- int x, w, sw = 0;
++ int x, w, sw = 0, n = 0, scm;
+ int boxs = drw->fonts->h / 9;
+ int boxw = drw->fonts->h / 6 + 2;
+ unsigned int i, occ = 0, urg = 0;
+ Client *c;
+
+ /* draw status first so it can be overdrawn by tags later */
+- if (m == selmon) { /* status is only drawn on selected monitor */
+- drw_setscheme(drw, scheme[SchemeNorm]);
+- sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */
+- drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0);
+- }
++ drw_setscheme(drw, scheme[SchemeSel]);
++ sw = m->ww - drawstatusbar(m, bh, stext);
+
+ for (c = m->clients; c; c = c->next) {
++ if (ISVISIBLE(c))
++ n++;
+ occ |= c->tags;
+ if (c->isurgent)
+ urg |= c->tags;
+@@ -716,10 +808,13 @@ drawbar(Monitor *m)
+ x = 0;
+ for (i = 0; i < LENGTH(tags); i++) {
+ w = TEXTW(tags[i]);
+- drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
++ if (urg & 1 << i)
++ drw_setscheme(drw, scheme[SchemeUrgent]);
++ else
++ drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]);
+ drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i);
+ if (occ & 1 << i)
+- drw_rect(drw, x + boxs, boxs, boxw, boxw,
++ drw_rect(drw, x + 2*boxs, 9*boxs, boxw, boxw,
+ m == selmon && selmon->sel && selmon->sel->tags & 1 << i,
+ urg & 1 << i);
+ x += w;
+@@ -729,16 +824,42 @@ drawbar(Monitor *m)
+ x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0);
+
+ if ((w = m->ww - sw - x) > bh) {
+- if (m->sel) {
+- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+- drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
+- if (m->sel->isfloating)
+- drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
++ if (n > 0) {
++ int remainder = w % n;
++ int tabw = (1.0 / (double)n) * w + 1;
++ for (c = m->clients; c; c = c->next) {
++ if (!ISVISIBLE(c))
++ continue;
++ if (m->sel == c && m == selmon)
++ scm = SchemeSel;
++ else
++ scm = SchemeNormWin;
++ drw_setscheme(drw, scheme[scm]);
++
++ if (remainder >= 0) {
++ if (remainder == 0) {
++ tabw--;
++ }
++ remainder--;
++ }
++ drw_text(drw, x, 0, tabw - borderpx, bh, lrpad / 2, c->name, 0);
++ /* draw seperator */
++ drw_setscheme(drw, scheme[SchemeNorm]);
++ drw_rect(drw, x + tabw - borderpx, 0, borderpx, bh, 1, 1);
++
++ x += tabw;
++ }
+ } else {
+- drw_setscheme(drw, scheme[SchemeNorm]);
++ if (m == selmon)
++ drw_setscheme(drw, scheme[SchemeNormWin]);
++ else
++ drw_setscheme(drw, scheme[SchemeNorm]);
+ drw_rect(drw, x, 0, w, bh, 1, 1);
+ }
+ }
++
++ m->bt = n;
++ m->btw = w;
+ drw_map(drw, m->barwin, 0, 0, m->ww, bh);
+ }
+
+@@ -794,7 +915,6 @@ focus(Client *c)
+ seturgent(c, 0);
+ detachstack(c);
+ attachstack(c);
+- grabbuttons(c, 1);
+ XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel);
+ setfocus(c);
+ } else {
+@@ -924,27 +1044,6 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size)
+ return 1;
+ }
+
+-void
+-grabbuttons(Client *c, int focused)
+-{
+- updatenumlockmask();
+- {
+- unsigned int i, j;
+- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+- if (!focused)
+- XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
+- BUTTONMASK, GrabModeSync, GrabModeSync, None, None);
+- for (i = 0; i < LENGTH(buttons); i++)
+- if (buttons[i].click == ClkClientWin)
+- for (j = 0; j < LENGTH(modifiers); j++)
+- XGrabButton(dpy, buttons[i].button,
+- buttons[i].mask | modifiers[j],
+- c->win, False, BUTTONMASK,
+- GrabModeAsync, GrabModeSync, None, None);
+- }
+-}
+-
+ void
+ grabkeys(void)
+ {
+@@ -1057,12 +1156,11 @@ manage(Window w, XWindowAttributes *wa)
+ updatesizehints(c);
+ updatewmhints(c);
+ XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
+- grabbuttons(c, 0);
+ if (!c->isfloating)
+ c->isfloating = c->oldstate = trans != None || c->isfixed;
+ if (c->isfloating)
+ XRaiseWindow(dpy, c->win);
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
+ (unsigned char *) &(c->win), 1);
+@@ -1110,9 +1208,9 @@ monocle(Monitor *m)
+ if (ISVISIBLE(c))
+ n++;
+ if (n > 0) /* override layout symbol */
+- snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n);
++ snprintf(m->ltsymbol, sizeof m->ltsymbol, "M%d", n);
+ for (c = nexttiled(m->clients); c; c = nexttiled(c->next))
+- resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0);
++ resize(c, m->wx + m->gappx, m->wy + m->gappx, (m->ww - 2 * c->bw) - 2*m->gappx, (m->wh - 2 * c->bw) - 2*m->gappx, 0);
+ }
+
+ void
+@@ -1132,64 +1230,14 @@ motionnotify(XEvent *e)
+ mon = m;
+ }
+
+-void
+-movemouse(const Arg *arg)
+-{
+- int x, y, ocx, ocy, nx, ny;
+- Client *c;
+- Monitor *m;
+- XEvent ev;
+- Time lasttime = 0;
+-
+- if (!(c = selmon->sel))
+- return;
+- if (c->isfullscreen) /* no support moving fullscreen windows by mouse */
+- return;
+- restack(selmon);
+- ocx = c->x;
+- ocy = c->y;
+- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+- None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess)
+- return;
+- if (!getrootptr(&x, &y))
+- return;
+- do {
+- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+- switch(ev.type) {
+- case ConfigureRequest:
+- case Expose:
+- case MapRequest:
+- handler[ev.type](&ev);
+- break;
+- case MotionNotify:
+- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+- continue;
+- lasttime = ev.xmotion.time;
+-
+- nx = ocx + (ev.xmotion.x - x);
+- ny = ocy + (ev.xmotion.y - y);
+- if (abs(selmon->wx - nx) < snap)
+- nx = selmon->wx;
+- else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap)
+- nx = selmon->wx + selmon->ww - WIDTH(c);
+- if (abs(selmon->wy - ny) < snap)
+- ny = selmon->wy;
+- else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap)
+- ny = selmon->wy + selmon->wh - HEIGHT(c);
+- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
+- && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
+- togglefloating(NULL);
+- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+- resize(c, nx, ny, c->w, c->h, 1);
+- break;
+- }
+- } while (ev.type != ButtonRelease);
+- XUngrabPointer(dpy, CurrentTime);
+- if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) {
+- sendmon(c, m);
+- selmon = m;
+- focus(NULL);
+- }
++Client *
++nexttagged(Client *c) {
++ Client *walked = c->mon->clients;
++ for(;
++ walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags));
++ walked = walked->next
++ );
++ return walked;
+ }
+
+ Client *
+@@ -1287,71 +1335,12 @@ resizeclient(Client *c, int x, int y, int w, int h)
+ XSync(dpy, False);
+ }
+
+-void
+-resizemouse(const Arg *arg)
+-{
+- int ocx, ocy, nw, nh;
+- Client *c;
+- Monitor *m;
+- XEvent ev;
+- Time lasttime = 0;
+-
+- if (!(c = selmon->sel))
+- return;
+- if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
+- return;
+- restack(selmon);
+- ocx = c->x;
+- ocy = c->y;
+- if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
+- None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess)
+- return;
+- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+- do {
+- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
+- switch(ev.type) {
+- case ConfigureRequest:
+- case Expose:
+- case MapRequest:
+- handler[ev.type](&ev);
+- break;
+- case MotionNotify:
+- if ((ev.xmotion.time - lasttime) <= (1000 / 60))
+- continue;
+- lasttime = ev.xmotion.time;
+-
+- nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1);
+- nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1);
+- if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww
+- && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh)
+- {
+- if (!c->isfloating && selmon->lt[selmon->sellt]->arrange
+- && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
+- togglefloating(NULL);
+- }
+- if (!selmon->lt[selmon->sellt]->arrange || c->isfloating)
+- resize(c, c->x, c->y, nw, nh, 1);
+- break;
+- }
+- } while (ev.type != ButtonRelease);
+- XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
+- 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);
+- }
+-}
+-
+ void
+ restack(Monitor *m)
+ {
+ Client *c;
+ XEvent ev;
+- XWindowChanges wc;
+-
+- drawbar(m);
++ XWindowChanges wc; drawbar(m);
+ if (!m->sel)
+ return;
+ if (m->sel->isfloating || !m->lt[m->sellt]->arrange)
+@@ -1417,7 +1406,7 @@ sendmon(Client *c, Monitor *m)
+ detachstack(c);
+ c->mon = m;
+ c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ focus(NULL);
+ arrange(NULL);
+@@ -1497,6 +1486,18 @@ setfullscreen(Client *c, int fullscreen)
+ }
+ }
+
++/*
++void
++setgaps(const Arg *arg)
++{
++ if ((arg->i == 0) || (selmon->gappx + arg->i < 0))
++ selmon->gappx = 0;
++ else
++ selmon->gappx += arg->i;
++ arrange(selmon);
++}
++*/
++
+ void
+ setlayout(const Arg *arg)
+ {
+@@ -1563,16 +1564,20 @@ setup(void)
+ netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
+ netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
+ /* init cursors */
+- cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
++ cursor[CurNormal] = drw_cur_create(drw, XC_sailboat);
+ cursor[CurResize] = drw_cur_create(drw, XC_sizing);
+ cursor[CurMove] = drw_cur_create(drw, XC_fleur);
+ /* init appearance */
+- scheme = ecalloc(LENGTH(colors), sizeof(Clr *));
++ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *));
++ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3);
+ for (i = 0; i < LENGTH(colors); i++)
+ scheme[i] = drw_scm_create(drw, colors[i], 3);
+ /* init bars */
++ vertpad = gappx;
++ sidepad = gappx;
+ updatebars();
+ updatestatus();
++ updatebarpos(selmon);
+ /* supporting window for NetWMCheck */
+ wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0);
+ XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32,
+@@ -1639,8 +1644,6 @@ sigchld(int unused)
+ void
+ spawn(const Arg *arg)
+ {
+- if (arg->v == dmenucmd)
+- dmenumon[0] = '0' + selmon->num;
+ if (fork() == 0) {
+ if (dpy)
+ close(ConnectionNumber(dpy));
+@@ -1683,28 +1686,19 @@ tile(Monitor *m)
+ if (n > m->nmaster)
+ mw = m->nmaster ? m->ww * m->mfact : 0;
+ else
+- mw = m->ww;
+- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ mw = m->ww - m->gappx;
++ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
+ if (i < m->nmaster) {
+- h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
+- my += HEIGHT(c);
++ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx;
++ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw) - m->gappx, h - (2*c->bw), 0);
++ my += HEIGHT(c) + m->gappx;
+ } else {
+- h = (m->wh - ty) / (n - i);
+- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
+- ty += HEIGHT(c);
++ h = (m->wh - ty) / (n - i) - m->gappx;
++ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - mw - (2*c->bw) - (2*m->gappx), h - (2*c->bw), 0);
++ ty += HEIGHT(c) + m->gappx;
+ }
+ }
+
+-void
+-togglebar(const Arg *arg)
+-{
+- selmon->showbar = !selmon->showbar;
+- updatebarpos(selmon);
+- XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
+- arrange(selmon);
+-}
+-
+ void
+ togglefloating(const Arg *arg)
+ {
+@@ -1719,6 +1713,13 @@ togglefloating(const Arg *arg)
+ arrange(selmon);
+ }
+
++void
++togglefullscr(const Arg *arg)
++{
++ if(selmon->sel)
++ setfullscreen(selmon->sel, !selmon->sel->isfullscreen);
++}
++
+ void
+ toggletag(const Arg *arg)
+ {
+@@ -1751,7 +1752,6 @@ unfocus(Client *c, int setfocus)
+ {
+ if (!c)
+ return;
+- grabbuttons(c, 0);
+ XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
+ if (setfocus) {
+ XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
+@@ -1811,7 +1811,7 @@ updatebars(void)
+ for (m = mons; m; m = m->next) {
+ if (m->barwin)
+ continue;
+- m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen),
++ m->barwin = XCreateWindow(dpy, root, m->wx + sidepad, m->by + vertpad, m->ww - 2*sidepad, bh, 0, DefaultDepth(dpy, screen),
+ CopyFromParent, DefaultVisual(dpy, screen),
+ CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
+ XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor);
+@@ -1826,11 +1826,11 @@ updatebarpos(Monitor *m)
+ m->wy = m->my;
+ m->wh = m->mh;
+ if (m->showbar) {
+- m->wh -= bh;
+- m->by = m->topbar ? m->wy : m->wy + m->wh;
+- m->wy = m->topbar ? m->wy + bh : m->wy;
++ m->wh = m->wh - vertpad - bh;
++ m->by = m->topbar ? m->wy : m->wy + m->wh + vertpad;
++ m->wy = m->topbar ? m->wy + bh + vertpad : m->wy;
+ } else
+- m->by = -bh;
++ m->by = -bh - vertpad;
+ }
+
+ void
+@@ -1897,7 +1897,7 @@ updategeom(void)
+ m->clients = c->next;
+ detachstack(c);
+ c->mon = mons;
+- attach(c);
++ attachaside(c);
+ attachstack(c);
+ }
+ if (m == selmon)
+@@ -1989,7 +1989,7 @@ updatestatus(void)
+ {
+ if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext)))
+ strcpy(stext, "dwm-"VERSION);
+- drawbar(selmon);
++ drawbars();
+ }
+
+ void
+@@ -2147,3 +2147,174 @@ main(int argc, char *argv[])
+ XCloseDisplay(dpy);
+ return EXIT_SUCCESS;
+ }
++
++static void
++fibonacci(Monitor *mon, int s) {
++ unsigned int i, n, nx, ny, nw, nh;
++ Client *c;
++
++ for(n = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next), n++);
++ if(n == 0)
++ return;
++
++ nx = mon->wx;
++ ny = 0;
++ nw = mon->ww;
++ nh = mon->wh - gappx;
++
++ for(i = 0, c = nexttiled(mon->clients); c; c = nexttiled(c->next)) {
++ if((i % 2 && nh / 2 > 2 * c->bw)
++ || (!(i % 2) && nw / 2 > 2 * c->bw)) {
++ if(i < n - 1) {
++ if(i % 2)
++ nh /= 2;
++ else
++ nw /= 2;
++ if((i % 4) == 2 && !s)
++ nx += nw;
++ else if((i % 4) == 3 && !s)
++ ny += nh;
++ }
++ if((i % 4) == 0) {
++ if(s)
++ ny += nh;
++ else
++ ny -= nh;
++ }
++ else if((i % 4) == 1)
++ nx += nw;
++ else if((i % 4) == 2)
++ ny += nh;
++ else if((i % 4) == 3) {
++ if(s)
++ nx += nw;
++ else
++ nx -= nw;
++ }
++ if(i == 0)
++ {
++ if(n != 1)
++ nw = mon->ww * mon->mfact;
++ ny = mon->wy;
++ }
++ else if(i == 1)
++ nw = mon->ww - nw - gappx;
++ i++;
++ }
++ resize(c, nx + mon->gappx, ny + mon->gappx, nw - (2 * c->bw) - mon->gappx, nh - 2*c->bw - mon->gappx, False);
++ }
++}
++
++static void
++dwindle(Monitor *mon) {
++ fibonacci(mon, 1);
++}
++
++static void
++spiral(Monitor *mon) {
++ fibonacci(mon, 0);
++}
++
++void
++centeredmaster(Monitor *m)
++{
++ unsigned int i, n, h, mw, mx, my, oty, ety, tw;
++ Client *c;
++
++ /* count number of clients in the selected monitor */
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ if (n == 0)
++ return;
++
++ /* initialize areas */
++ mw = m->ww;
++ mx = 0;
++ my = 0;
++ tw = mw;
++
++ if (n > m->nmaster) {
++ /* go mfact box in the center if more than nmaster clients */
++ mw = m->nmaster ? m->ww * m->mfact : 0;
++ tw = m->ww - mw;
++
++ if (n - m->nmaster > 1) {
++ /* only one client */
++ mx = (m->ww - mw) / 2;
++ tw = (m->ww - mw) / 2;
++ }
++ }
++
++ oty = 0;
++ ety = 0;
++ for (i = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < m->nmaster) {
++ /* nmaster clients are stacked vertically, in the center
++ * of the screen */
++ h = (m->wh - my) / (MIN(n, m->nmaster) - i);
++ resize(c, m->wx + mx + gappx, m->wy + my + gappx, (mw - (2*c->bw)) - 2*gappx,
++ (h - (2*c->bw)) - 2*gappx, 0);
++ my += HEIGHT(c);
++ } else {
++ /* stack clients are stacked vertically */
++ if ((i - m->nmaster) % 2 ) {
++ h = (m->wh - ety) / ( (1 + n - i) / 2);
++ resize(c, m->wx + gappx, m->wy + ety + gappx, tw - (2*c->bw) - gappx,
++ (h - (2*c->bw)) - 2*gappx, 0);
++ ety += HEIGHT(c);
++ } else {
++ h = (m->wh - oty) / ((1 + n - i) / 2);
++ resize(c, m->wx + mx + mw, m->wy + oty + gappx,
++ tw - (2*c->bw) - gappx, (h - (2*c->bw)) - 2*gappx, 0);
++ oty += HEIGHT(c);
++ }
++ }
++}
++
++void
++centeredfloatingmaster(Monitor *m)
++{
++ unsigned int i, n, w, mh, mw, mx, mxo, my, myo, tx;
++ Client *c;
++
++ /* count number of clients in the selected monitor */
++ for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
++ if (n == 0)
++ return;
++
++ /* initialize nmaster area */
++ if (n > m->nmaster) {
++ /* go mfact box in the center if more than nmaster clients */
++ if (m->ww > m->wh) {
++ mw = m->nmaster ? m->ww * m->mfact : 0;
++ mh = m->nmaster ? m->wh * 0.9 : 0;
++ } else {
++ mh = m->nmaster ? m->wh * m->mfact : 0;
++ mw = m->nmaster ? m->ww * 0.9 : 0;
++ }
++ mx = mxo = (m->ww - mw) / 2;
++ my = myo = (m->wh - mh) / 2;
++ } else {
++ /* go fullscreen if all clients are in the master area */
++ mh = m->wh - 2*gappx;
++ mw = m->ww - 2*gappx;
++ mx = mxo = 0 + gappx;
++ my = myo = 0 + gappx;
++ }
++
++ for(i = tx = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
++ if (i < m->nmaster) {
++ /* nmaster clients are stacked horizontally, in the center
++ * of the screen */
++ w = (mw + mxo - mx) / (MIN(n, m->nmaster) - i);
++ resize(c, m->wx + mx, m->wy + my, w - (2*c->bw),
++ mh - (2*c->bw), 0);
++ mx += WIDTH(c) + gappx;
++ } else {
++ /* stack clients are stacked horizontally */
++ w = (m->ww - tx) / (n - i);
++ resize(c, m->wx + tx + gappx, m->wy + gappx, w - (2*c->bw) - 2*gappx,
++ m->wh - (2*c->bw) - 2*gappx, 0);
++ tx += WIDTH(c) + gappx;
++ }
++ /* XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char *)&netatom[NetWMFullscreen], 1); */
++}
diff --git a/makefile b/makefile
@@ -0,0 +1,54 @@
+# dwm - dynamic window manager
+# See LICENSE file for copyright and license details.
+
+include config.mk
+
+SRC = drw.c dwm.c util.c
+OBJ = ${SRC:.c=.o}
+
+all: options dwm
+
+options:
+ @echo dwm build options:
+ @echo "CFLAGS = ${CFLAGS}"
+ @echo "LDFLAGS = ${LDFLAGS}"
+ @echo "CC = ${CC}"
+
+.c.o:
+ ${CC} -c ${CFLAGS} $<
+
+${OBJ}: config.h config.mk
+
+config.h:
+ cp config.def.h $@
+
+dwm: ${OBJ}
+ ${CC} -o $@ ${OBJ} ${LDFLAGS}
+
+clean:
+ rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
+
+dist: clean
+ mkdir -p dwm-${VERSION}
+ cp -R LICENSE Makefile README config.def.h config.mk\
+ dwm.1 drw.h util.h ${SRC} dwm.png transient.c dwm-${VERSION}
+ tar -cf dwm-${VERSION}.tar dwm-${VERSION}
+ gzip dwm-${VERSION}.tar
+ rm -rf dwm-${VERSION}
+
+install: all
+ mkdir -p ${DESTDIR}${PREFIX}/bin
+ cp -f dwm ${DESTDIR}${PREFIX}/bin
+ chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
+ mkdir -p ${DESTDIR}${MANPREFIX}/man1
+ sed "s/VERSION/${VERSION}/g" < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
+
+diff:
+ git diff cb3f58a -- `ls | sed '/dwm-6.2.diff/d'` > dwm-6.2.diff
+
+uninstall:
+ rm -f ${DESTDIR}${PREFIX}/bin/dwm\
+ ${DESTDIR}${MANPREFIX}/man1/dwm.1
+
+.PHONY: all options clean dist install uninstall