diff options
Diffstat (limited to 'dwm.c')
-rw-r--r-- | dwm.c | 154 |
1 files changed, 146 insertions, 8 deletions
@@ -52,8 +52,8 @@ #define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) #define LENGTH(X) (sizeof X / sizeof X[0]) #define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#define WIDTH(X) ((X)->w + 2 * (X)->bw + gappx) +#define HEIGHT(X) ((X)->h + 2 * (X)->bw + gappx) #define TAGMASK ((1 << LENGTH(tags)) - 1) #define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) @@ -119,6 +119,7 @@ struct Monitor { int by; /* bar geometry */ 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]; @@ -184,8 +185,10 @@ static void maprequest(XEvent *e); static void monocle(Monitor *m); static void motionnotify(XEvent *e); static void movemouse(const Arg *arg); +static unsigned int nexttag(void); static Client *nexttiled(Client *c); static void pop(Client *c); +static unsigned int prevtag(void); static void propertynotify(XEvent *e); static void quit(const Arg *arg); static Monitor *recttomon(int x, int y, int w, int h); @@ -200,6 +203,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); @@ -208,9 +212,12 @@ static void showhide(Client *c); static void spawn(const Arg *arg); static void tag(const Arg *arg); static void tagmon(const Arg *arg); +static void tagtonext(const Arg *arg); +static void tagtoprev(const Arg *arg); static void tile(Monitor *m); 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); @@ -227,6 +234,8 @@ static void updatetitle(Client *c); static void updatewindowtype(Client *c); static void updatewmhints(Client *c); static void view(const Arg *arg); +static void viewnext(const Arg *arg); +static void viewprev(const Arg *arg); static Client *wintoclient(Window w); static Monitor *wintomon(Window w); static int xerror(Display *dpy, XErrorEvent *ee); @@ -641,6 +650,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); @@ -1202,6 +1212,29 @@ movemouse(const Arg *arg) } } +unsigned int +nexttag(void) +{ + unsigned int seltag = selmon->tagset[selmon->seltags]; + unsigned int usedtags = 0; + Client *c = selmon->clients; + + if (!c) + return seltag; + + /* skip vacant tags */ + do { + usedtags |= c->tags; + c = c->next; + } while (c); + + do { + seltag = seltag == (1 << (LENGTH(tags) - 1)) ? 1 : seltag << 1; + } while (!(seltag & usedtags)); + + return seltag; +} + Client * nexttiled(Client *c) { @@ -1218,6 +1251,28 @@ pop(Client *c) arrange(c->mon); } +unsigned int +prevtag(void) +{ + unsigned int seltag = selmon->tagset[selmon->seltags]; + unsigned int usedtags = 0; + Client *c = selmon->clients; + if (!c) + return seltag; + + /* skip vacant tags */ + do { + usedtags |= c->tags; + c = c->next; + } while (c); + + do { + seltag = seltag == 1 ? (1 << (LENGTH(tags) - 1)) : seltag >> 1; + } while (!(seltag & usedtags)); + + return seltag; +} + void propertynotify(XEvent *e) { @@ -1286,12 +1341,36 @@ void resizeclient(Client *c, int x, int y, int w, int h) { XWindowChanges wc; + unsigned int n; + unsigned int gapoffset; + unsigned int gapincr; + Client *nbc; - c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; c->y = wc.y = y; - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; wc.border_width = c->bw; + + /* Get number of clients for the client's monitor */ + for (n = 0, nbc = nexttiled(c->mon->clients); nbc; nbc = nexttiled(nbc->next), n++); + + /* Do nothing if layout is floating */ + if (c->isfloating || c->mon->lt[c->mon->sellt]->arrange == NULL) { + gapincr = gapoffset = 0; + } else { + /* Remove border and gap if layout is monocle or only one client */ + if (c->mon->lt[c->mon->sellt]->arrange == monocle || n == 1) { + gapoffset = 0; + gapincr = -2 * borderpx; + wc.border_width = 0; + } else { + gapoffset = gappx; + gapincr = 2 * gappx; + } + } + + c->oldx = c->x; c->x = wc.x = x + gapoffset; + c->oldy = c->y; c->y = wc.y = y + gapoffset; + c->oldw = c->w; c->w = wc.width = w - gapincr; + c->oldh = c->h; c->h = wc.height = h - gapincr; + XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); configure(c); XSync(dpy, False); @@ -1508,6 +1587,16 @@ 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) { if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) @@ -1685,6 +1774,36 @@ tagmon(const Arg *arg) } void +tagtonext(const Arg *arg) +{ + unsigned int tmp; + + if (selmon->sel == NULL) + return; + + if ((tmp = nexttag()) == selmon->tagset[selmon->seltags]) + return; + + tag(&(const Arg){.ui = tmp }); + view(&(const Arg){.ui = tmp }); +} + +void +tagtoprev(const Arg *arg) +{ + unsigned int tmp; + + if (selmon->sel == NULL) + return; + + if ((tmp = prevtag()) == selmon->tagset[selmon->seltags]) + return; + + tag(&(const Arg){.ui = tmp }); + view(&(const Arg){.ui = tmp }); +} + +void tile(Monitor *m) { unsigned int i, n, h, mw, my, ty; @@ -1701,7 +1820,7 @@ tile(Monitor *m) 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), 0); + resize(c, m->wx, m->wy + my, mw - (2*c->bw) + (n > 1 ? gappx : 0), h - (2*c->bw), 0); if (my + HEIGHT(c) < m->wh) my += HEIGHT(c); } else { @@ -1736,6 +1855,13 @@ togglefloating(const Arg *arg) } void +togglefullscr(const Arg *arg) +{ + if(selmon->sel) + setfullscreen(selmon->sel, !selmon->sel->isfullscreen); +} + +void toggletag(const Arg *arg) { unsigned int newtags; @@ -1915,7 +2041,7 @@ updategeom(void) m->clients = c->next; detachstack(c); c->mon = mons; - attach(c); + attachbottom(c); attachstack(c); } if (m == selmon) @@ -2062,6 +2188,18 @@ view(const Arg *arg) arrange(selmon); } +void +viewnext(const Arg *arg) +{ + view(&(const Arg){.ui = nexttag()}); +} + +void +viewprev(const Arg *arg) +{ + view(&(const Arg){.ui = prevtag()}); +} + Client * wintoclient(Window w) { |