Created
November 11, 2011 11:24
-
-
Save ropery/1357788 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -r 183cedbebe52 config.def.h | |
--- a/config.def.h Fri Nov 04 20:02:35 2011 +0100 | |
+++ b/config.def.h Fri Nov 11 18:13:10 2011 +0800 | |
@@ -32,6 +32,9 @@ | |
{ "[]=", tile }, /* first entry is default */ | |
{ "><>", NULL }, /* no layout function means floating behavior */ | |
{ "[M]", monocle }, | |
+ { "TTT", bstack }, | |
+ { "|||", col }, | |
+ { "[]@", spiral }, | |
}; | |
/* key definitions */ | |
@@ -66,6 +69,9 @@ | |
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, | |
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, | |
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, | |
+ { MODKEY, XK_s, setlayout, {.v = &layouts[3]} }, | |
+ { MODKEY, XK_c, setlayout, {.v = &layouts[4]} }, | |
+ { MODKEY, XK_e, setlayout, {.v = &layouts[5]} }, | |
{ MODKEY, XK_space, setlayout, {0} }, | |
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, | |
{ MODKEY, XK_0, view, {.ui = ~0 } }, | |
diff -r 183cedbebe52 dwm.c | |
--- a/dwm.c Fri Nov 04 20:02:35 2011 +0100 | |
+++ b/dwm.c Fri Nov 11 18:13:10 2011 +0800 | |
@@ -55,6 +55,7 @@ | |
#define TEXTW(X) (textnw(X, strlen(X)) + dc.font.height) | |
/* enums */ | |
+enum { CutLeft, CutTop, CutRight, CutBottom }; | |
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ | |
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ | |
enum { NetSupported, NetWMName, NetWMState, | |
@@ -123,26 +124,9 @@ | |
void (*arrange)(Monitor *); | |
} Layout; | |
-struct Monitor { | |
- char ltsymbol[16]; | |
- float mfact; | |
- int nmaster; | |
- int num; | |
- int by; /* bar geometry */ | |
- int mx, my, mw, mh; /* screen size */ | |
- int wx, wy, ww, wh; /* window area */ | |
- unsigned int seltags; | |
- unsigned int sellt; | |
- unsigned int tagset[2]; | |
- Bool showbar; | |
- Bool topbar; | |
- Client *clients; | |
- Client *sel; | |
- Client *stack; | |
- Monitor *next; | |
- Window barwin; | |
- const Layout *lt[2]; | |
-}; | |
+typedef struct { | |
+ int x, y, w, h; | |
+} Rect; | |
typedef struct { | |
const char *class; | |
@@ -154,22 +138,29 @@ | |
} Rule; | |
/* function declarations */ | |
+static void applymslts(Monitor *m, int cut, | |
+ void (*mltf)(Client **, Rect *, unsigned int), /* master layout function */ | |
+ void (*sltf)(Client **, Rect *, unsigned int)); /* slave layout function */ | |
static void applyrules(Client *c); | |
static Bool applysizehints(Client *c, int *x, int *y, int *w, int *h, Bool interact); | |
static void arrange(Monitor *m); | |
static void arrangemon(Monitor *m); | |
static void attach(Client *c); | |
+static void attachslave(Client *c); | |
static void attachstack(Client *c); | |
+static void bstack(Monitor *); | |
static void buttonpress(XEvent *e); | |
static void checkotherwm(void); | |
static void cleanup(void); | |
static void cleanupmon(Monitor *mon); | |
static void clearurgent(Client *c); | |
static void clientmessage(XEvent *e); | |
+static void col(Monitor *); | |
static void configure(Client *c); | |
static void configurenotify(XEvent *e); | |
static void configurerequest(XEvent *e); | |
static Monitor *createmon(void); | |
+static void cutrect(int cut, float fact, Rect *r, Rect *t); | |
static void destroynotify(XEvent *e); | |
static void detach(Client *c); | |
static void detachstack(Client *c); | |
@@ -195,6 +186,9 @@ | |
static void initfont(const char *fontstr); | |
static void keypress(XEvent *e); | |
static void killclient(const Arg *arg); | |
+static void lt_stackh(Client **c, Rect *r, unsigned int n); | |
+static void lt_stackv(Client **c, Rect *r, unsigned int n); | |
+static void lt_spiral(Client **c, Rect *r, unsigned int n); | |
static void manage(Window w, XWindowAttributes *wa); | |
static void mappingnotify(XEvent *e); | |
static void maprequest(XEvent *e); | |
@@ -208,6 +202,7 @@ | |
static void resize(Client *c, int x, int y, int w, int h, Bool interact); | |
static void resizeclient(Client *c, int x, int y, int w, int h); | |
static void resizemouse(const Arg *arg); | |
+static void resizetocut(Client *c, int cut, float fact, Rect *r); | |
static void restack(Monitor *m); | |
static void run(void); | |
static void scan(void); | |
@@ -221,6 +216,7 @@ | |
static void showhide(Client *c); | |
static void sigchld(int unused); | |
static void spawn(const Arg *arg); | |
+static void spiral(Monitor *); | |
static void tag(const Arg *arg); | |
static void tagmon(const Arg *arg); | |
static int textnw(const char *text, unsigned int len); | |
@@ -283,11 +279,70 @@ | |
/* configuration, allows nested code to access above variables */ | |
#include "config.h" | |
+struct Monitor { | |
+ char ltsymbol[16]; | |
+ float mfact[LENGTH(layouts)]; | |
+ int nmaster[LENGTH(layouts)]; | |
+ int num; | |
+ int by; /* bar geometry */ | |
+ int mx, my, mw, mh; /* screen size */ | |
+ int wx, wy, ww, wh; /* window area */ | |
+ unsigned int seltags; | |
+ unsigned int sellt; | |
+ unsigned int tagset[2]; | |
+ Bool showbar; | |
+ Bool topbar; | |
+ Client *clients; | |
+ Client *sel; | |
+ Client *stack; | |
+ Monitor *next; | |
+ Window barwin; | |
+ const Layout *lt[2]; | |
+}; | |
+ | |
/* compile-time check if all tags fit into an unsigned int bit array. */ | |
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | |
/* function implementations */ | |
void | |
+applymslts(Monitor *m, int cut, | |
+ void (*mltf)(Client **, Rect *, unsigned int), | |
+ void (*sltf)(Client **, Rect *, unsigned int)) { | |
+ unsigned int i, n; | |
+ Client *c; | |
+ | |
+ for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); | |
+ if(n == 0) | |
+ return; | |
+ | |
+ int nm; | |
+ float f; | |
+ | |
+ i = m->lt[m->sellt] - layouts; | |
+ if(0 <= i && i < LENGTH(layouts)) { | |
+ f = m->mfact[i]; | |
+ nm = m->nmaster[i]; | |
+ } | |
+ else { | |
+ f = mfact; | |
+ nm = nmaster; | |
+ } | |
+ | |
+ Rect rm, r = { m->wx, m->wy, m->ww, m->wh }; | |
+ | |
+ c = m->clients; | |
+ if(nm == 0 || mltf == NULL) | |
+ (*sltf)(&c, &r, n); | |
+ else if(n > nm) { | |
+ cutrect(cut, f, &r, &rm); | |
+ (*mltf)(&c, &rm, nm); | |
+ (*sltf)(&c, &r, n - nm); | |
+ } | |
+ else | |
+ (*mltf)(&c, &r, n); | |
+} | |
+ | |
+void | |
applyrules(Client *c) { | |
const char *class, *instance; | |
unsigned int i; | |
@@ -419,6 +474,32 @@ | |
c->mon->stack = c; | |
} | |
+/* attach as the first slave, if all master seats are taken */ | |
+void | |
+attachslave(Client *c) { | |
+ Client *tc; | |
+ int i, n; | |
+ | |
+ if(!(tc = nexttiled(c->mon->clients)) || !c->mon->sel || c->isfloating) { | |
+ attach(c); | |
+ return; | |
+ } | |
+ i = c->mon->lt[c->mon->sellt] - layouts; | |
+ n = 0 <= i && i < LENGTH(layouts) ? c->mon->nmaster[i] : nmaster; | |
+ for(i = 1; tc && i < n; tc = nexttiled(tc->next), i++); | |
+ if(n == 0 || !tc) { | |
+ attach(c); | |
+ return; | |
+ } | |
+ c->next = tc->next; | |
+ tc->next = c; | |
+} | |
+ | |
+void | |
+bstack(Monitor *m) { | |
+ applymslts(m, CutTop, lt_stackh, lt_stackh); | |
+} | |
+ | |
void | |
buttonpress(XEvent *e) { | |
unsigned int i, x, click; | |
@@ -567,6 +648,11 @@ | |
} | |
void | |
+col(Monitor *m) { | |
+ applymslts(m, CutLeft, lt_stackh, lt_stackv); | |
+} | |
+ | |
+void | |
configure(Client *c) { | |
XConfigureEvent ce; | |
@@ -663,12 +749,15 @@ | |
Monitor * | |
createmon(void) { | |
Monitor *m; | |
+ unsigned int i; | |
if(!(m = (Monitor *)calloc(1, sizeof(Monitor)))) | |
die("fatal: could not malloc() %u bytes\n", sizeof(Monitor)); | |
m->tagset[0] = m->tagset[1] = 1; | |
- m->mfact = mfact; | |
- m->nmaster = nmaster; | |
+ for(i = 0; i < LENGTH(layouts); i++) { | |
+ m->mfact[i] = mfact; | |
+ m->nmaster[i] = nmaster; | |
+ } | |
m->showbar = showbar; | |
m->topbar = topbar; | |
m->lt[0] = &layouts[0]; | |
@@ -678,6 +767,33 @@ | |
} | |
void | |
+cutrect(int cut, float fact, Rect *r, Rect *t) { | |
+ fact = fact > 1 ? 1 : (fact < 0 ? 0 : fact); | |
+ t->x = r->x; | |
+ t->y = r->y; | |
+ t->w = r->w; | |
+ t->h = r->h; | |
+ switch(cut) { | |
+ case CutLeft: | |
+ r->x += t->w * fact; | |
+ r->w += t->x - r->x; | |
+ t->w -= r->w; | |
+ break; | |
+ case CutTop: | |
+ r->y += t->h * fact; | |
+ r->h += t->y - r->y; | |
+ t->h -= r->h; | |
+ break; | |
+ case CutRight: | |
+ cutrect(CutLeft, 1 - fact, t, r); | |
+ break; | |
+ case CutBottom: | |
+ cutrect(CutTop, 1 - fact, t, r); | |
+ break; | |
+ } | |
+} | |
+ | |
+void | |
destroynotify(XEvent *e) { | |
Client *c; | |
XDestroyWindowEvent *ev = &e->xdestroywindow; | |
@@ -1030,8 +1146,18 @@ | |
void | |
incnmaster(const Arg *arg) { | |
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); | |
- arrange(selmon); | |
+ if(!arg || !selmon->lt[selmon->sellt]->arrange) | |
+ return; | |
+ int n; | |
+ unsigned int i; | |
+ i = selmon->lt[selmon->sellt] - layouts; | |
+ if(0 <= i && i < LENGTH(layouts)) { | |
+ n = MAX(selmon->nmaster[i] + arg->i, 0); | |
+ if(n != selmon->nmaster[i]) { | |
+ selmon->nmaster[i] = n; | |
+ arrange(selmon); | |
+ } | |
+ } | |
} | |
void | |
@@ -1110,6 +1236,35 @@ | |
} | |
void | |
+lt_stackh(Client **c, Rect *r, unsigned int n) { | |
+ unsigned int i; | |
+ | |
+ for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { | |
+ resizetocut(*c, CutLeft, 1.0 / (n - i), r); | |
+ } | |
+} | |
+ | |
+void | |
+lt_stackv(Client **c, Rect *r, unsigned int n) { | |
+ unsigned int i; | |
+ | |
+ for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { | |
+ resizetocut(*c, CutTop, 1.0 / (n - i), r); | |
+ } | |
+} | |
+ | |
+void | |
+lt_spiral(Client **c, Rect *r, unsigned int n) { | |
+ const float f = 0.5; | |
+ int cut = CutTop, i; | |
+ | |
+ for(i = 0, *c = nexttiled(*c); *c && i < n; *c = nexttiled((*c)->next), i++) { | |
+ resizetocut(*c, cut, n - i == 1 ? 1 : f, r); | |
+ cut = cut == CutTop ? CutRight : cut == CutRight ? CutBottom : cut == CutBottom ? CutLeft : CutTop; | |
+ } | |
+} | |
+ | |
+void | |
manage(Window w, XWindowAttributes *wa) { | |
Client *c, *t = NULL; | |
Window trans = None; | |
@@ -1163,7 +1318,7 @@ | |
c->isfloating = c->oldstate = trans != None || c->isfixed; | |
if(c->isfloating) | |
XRaiseWindow(dpy, c->win); | |
- attach(c); | |
+ attachslave(c); | |
attachstack(c); | |
XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ | |
setclientstate(c, NormalState); | |
@@ -1402,6 +1557,39 @@ | |
} | |
void | |
+resizetocut(Client *c, int cut, float fact, Rect *r) { | |
+ int x = r->x, y = r->y, w = r->w, h = r->h; | |
+ | |
+ fact = fact > 1 ? 1 : (fact < 0 ? 0 : fact); | |
+ switch(cut) { | |
+ case CutLeft: | |
+ resize(c, r->x, r->y, r->w * fact - 2 * c->bw, r->h - 2 * c->bw, False); | |
+ w = WIDTH(c); | |
+ r->x += w; | |
+ r->w -= w; | |
+ break; | |
+ case CutTop: | |
+ resize(c, r->x, r->y, r->w - 2 * c->bw, r->h * fact - 2 * c->bw, False); | |
+ h = HEIGHT(c); | |
+ r->y += h; | |
+ r->h -= h; | |
+ break; | |
+ case CutRight: | |
+ w *= fact; | |
+ x += r->w - w; | |
+ r->w -= w; | |
+ resize(c, x, y, w - 2 * c->bw, h - 2 * c->bw, False); | |
+ break; | |
+ case CutBottom: | |
+ h *= fact; | |
+ y += r->h - h; | |
+ r->h -= h; | |
+ resize(c, x, y, w - 2 * c->bw, h - 2 * c->bw, False); | |
+ break; | |
+ } | |
+} | |
+ | |
+void | |
restack(Monitor *m) { | |
Client *c; | |
XEvent ev; | |
@@ -1531,15 +1719,18 @@ | |
/* arg > 1.0 will set mfact absolutly */ | |
void | |
setmfact(const Arg *arg) { | |
- float f; | |
- | |
if(!arg || !selmon->lt[selmon->sellt]->arrange) | |
return; | |
- f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; | |
- if(f < 0.1 || f > 0.9) | |
- return; | |
- selmon->mfact = f; | |
- arrange(selmon); | |
+ float f; | |
+ unsigned int i; | |
+ i = selmon->lt[selmon->sellt] - layouts; | |
+ if(0 <= i && i < LENGTH(layouts)) { | |
+ f = arg->f < 1.0 ? arg->f + selmon->mfact[i] : arg->f - 1.0; | |
+ if(f != selmon->mfact[i] && f >= 0.1 && f <= 0.9) { | |
+ selmon->mfact[i] = f; | |
+ arrange(selmon); | |
+ } | |
+ } | |
} | |
void | |
@@ -1638,6 +1829,11 @@ | |
} | |
void | |
+spiral(Monitor *m) { | |
+ applymslts(m, CutRight, lt_spiral, lt_stackv); | |
+} | |
+ | |
+void | |
tag(const Arg *arg) { | |
if(selmon->sel && arg->ui & TAGMASK) { | |
selmon->sel->tags = arg->ui & TAGMASK; | |
@@ -1666,28 +1862,7 @@ | |
void | |
tile(Monitor *m) { | |
- unsigned int i, n, h, mw, my, ty; | |
- Client *c; | |
- | |
- for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); | |
- if(n == 0) | |
- return; | |
- | |
- 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++) | |
- 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), False); | |
- my += HEIGHT(c); | |
- } | |
- 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), False); | |
- ty += HEIGHT(c); | |
- } | |
+ applymslts(m, CutLeft, lt_stackv, lt_stackv); | |
} | |
void |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment