int rx, ry, rw, rh; /* revert geometry */
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int minax, maxax, minay, maxay;
- long flags;
+ long flags;
unsigned int border, oldborder;
Bool isbanned, isfixed, ismax, isfloating, wasfloating;
Bool *tags;
regex_t *tagregex;
} Regs;
-/* forward declarations */
+/* function declarations */
void applyrules(Client *c);
void arrange(void);
void attach(Client *c);
void updatesizehints(Client *c);
void updatetitle(Client *c);
void view(const char *arg);
+void viewprevtag(const char *arg); /* views previous selected tags */
int xerror(Display *dpy, XErrorEvent *ee);
int xerrordummy(Display *dsply, XErrorEvent *ee);
int xerrorstart(Display *dsply, XErrorEvent *ee);
double mwfact;
int screen, sx, sy, sw, sh, wax, way, waw, wah;
int (*xerrorxlib)(Display *, XErrorEvent *);
-unsigned int bh, bpos, ntags;
+unsigned int bh, bpos;
unsigned int blw = 0;
unsigned int ltidx = 0; /* default */
unsigned int nlayouts = 0;
Atom wmatom[WMLast], netatom[NetLast];
Bool otherwm, readin;
Bool running = True;
-Bool *seltags;
Bool selscreen = True;
Client *clients = NULL;
Client *sel = NULL;
/* configuration, allows nested code to access above variables */
#include "config.h"
-/* functions*/
+/* function implementations */
void
applyrules(Client *c) {
static char buf[512];
for(i = 0; i < nrules; i++)
if(regs[i].propregex && !regexec(regs[i].propregex, buf, 1, &tmp, 0)) {
c->isfloating = rules[i].isfloating;
- for(j = 0; regs[i].tagregex && j < ntags; j++) {
+ for(j = 0; regs[i].tagregex && j < NTAGS; j++) {
if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
matched = True;
c->tags[j] = True;
if(ch.res_name)
XFree(ch.res_name);
if(!matched)
- for(i = 0; i < ntags; i++)
- c->tags[i] = seltags[i];
+ memcpy(c->tags, seltags, sizeof seltags);
}
void
if(barwin == ev->window) {
x = 0;
- for(i = 0; i < ntags; i++) {
+ for(i = 0; i < NTAGS; i++) {
x += textw(tags[i]);
if(ev->x < x) {
if(ev->button == Button1) {
movemouse(c);
}
else if(ev->button == Button2) {
- if(ISTILE && !c->isfixed && c->isfloating)
+ if((ISTILE) && !c->isfixed && c->isfloating)
togglefloating(NULL);
else
zoom(NULL);
XFreeCursor(dpy, cursor[CurMove]);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
- free(seltags);
}
void
int i, x;
dc.x = dc.y = 0;
- for(i = 0; i < ntags; i++) {
+ for(i = 0; i < NTAGS; i++) {
dc.w = textw(tags[i]);
if(seltags[i]) {
drawtext(tags[i], dc.sel);
idxoftag(const char *tag) {
unsigned int i;
- for(i = 0; i < ntags; i++)
- if(tags[i] == tag)
- return i;
- return 0;
+ for(i = 0; (i < NTAGS) && (tags[i] != tag); i++);
+ return (i < NTAGS) ? i : 0;
}
void
isvisible(Client *c) {
unsigned int i;
- for(i = 0; i < ntags; i++)
+ for(i = 0; i < NTAGS; i++)
if(c->tags[i] && seltags[i])
return True;
return False;
void
manage(Window w, XWindowAttributes *wa) {
- unsigned int i;
Client *c, *t = NULL;
Window trans;
Status rettrans;
XWindowChanges wc;
c = emallocz(sizeof(Client));
- c->tags = emallocz(ntags * sizeof(Bool));
+ c->tags = emallocz(sizeof seltags);
c->win = w;
c->x = wa->x;
c->y = wa->y;
if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
for(t = clients; t && t->win != trans; t = t->next);
if(t)
- for(i = 0; i < ntags; i++)
- c->tags[i] = t->tags[i];
+ memcpy(c->tags, t->tags, sizeof seltags);
applyrules(c);
if(!c->isfloating)
c->isfloating = (rettrans == Success) || c->isfixed;
default: break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
- if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
+ if(!c->isfloating && (c->isfloating = (NULL != getclient(trans))))
arrange();
break;
case XA_WM_NORMAL_HINTS:
void
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
- double dx, dy, max, min, ratio;
- XWindowChanges wc;
+ XWindowChanges wc;
if(sizehints) {
- if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0 && (w - c->basew) > 0) {
- dx = (double)(w - c->basew);
- dy = (double)(h - c->baseh);
- min = (double)(c->minax) / (double)(c->minay);
- max = (double)(c->maxax) / (double)(c->maxay);
- ratio = dx / dy;
- if(max > 0 && min > 0 && ratio > 0) {
- if(ratio < min) {
- dy = (dx * min + dy) / (min * min + 1);
- dx = dy * min;
- w = (int)dx + c->basew;
- h = (int)dy + c->baseh;
- }
- else if(ratio > max) {
- dy = (dx * min + dy) / (max * max + 1);
- dx = dy * min;
- w = (int)dx + c->basew;
- h = (int)dy + c->baseh;
- }
- }
+ /* set minimum possible */
+ if (w < 1)
+ w = 1;
+ if (h < 1)
+ h = 1;
+
+ /* temporarily remove base dimensions */
+ w -= c->basew;
+ h -= c->baseh;
+
+ /* adjust for aspect limits */
+ if (c->minay > 0 && c->maxay > 0 && c->minax > 0 && c->maxax > 0) {
+ if (w * c->maxay > h * c->maxax)
+ w = h * c->maxax / c->maxay;
+ else if (w * c->minay < h * c->minax)
+ h = w * c->minay / c->minax;
}
- if(c->minw && w < c->minw)
+
+ /* adjust for increment value */
+ if(c->incw)
+ w -= w % c->incw;
+ if(c->inch)
+ h -= h % c->inch;
+
+ /* restore base dimensions */
+ w += c->basew;
+ h += c->baseh;
+
+ if(c->minw > 0 && w < c->minw)
w = c->minw;
- if(c->minh && h < c->minh)
+ if(c->minh > 0 && h < c->minh)
h = c->minh;
- if(c->maxw && w > c->maxw)
+ if(c->maxw > 0 && w > c->maxw)
w = c->maxw;
- if(c->maxh && h > c->maxh)
+ if(c->maxh > 0 && h > c->maxh)
h = c->maxh;
- if(c->incw)
- w -= (w - c->basew) % c->incw;
- if(c->inch)
- h -= (h - c->baseh) % c->inch;
}
if(w <= 0 || h <= 0)
return;
setmwfact(const char *arg) {
double delta;
- if(!ISTILE)
+ if(!(ISTILE))
return;
/* arg handling, manipulate mwfact */
if(arg == NULL)
/* init tags */
compileregs();
- for(ntags = 0; tags[ntags]; ntags++);
- seltags = emallocz(sizeof(Bool) * ntags);
- seltags[0] = True;
/* init appearance */
dc.norm[ColBorder] = getcolor(NORMBORDERCOLOR);
if(!sel)
return;
- for(i = 0; i < ntags; i++)
- sel->tags[i] = arg == NULL;
- i = idxoftag(arg);
- if(i >= 0 && i < ntags)
- sel->tags[i] = True;
+ for(i = 0; i < NTAGS; i++)
+ sel->tags[i] = (NULL == arg);
+ sel->tags[idxoftag(arg)] = True;
arrange();
}
void
tile(void) {
unsigned int i, n, nx, ny, nw, nh, mw, th;
- Client *c;
+ Client *c, *mc;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
nx = wax;
ny = way;
- for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
+ nw = 0; /* gcc stupidity requires this */
+ for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next), i++) {
c->ismax = False;
if(i == 0) { /* master */
nw = mw - 2 * c->border;
else { /* tile window */
if(i == 1) {
ny = way;
- nx += mw;
+ nx += mc->w + 2 * mc->border;
+ nw = waw - nx - 2 * c->border;
}
- nw = waw - mw - 2 * c->border;
if(i + 1 == n) /* remainder */
nh = (way + wah) - ny - 2 * c->border;
else
nh = th - 2 * c->border;
}
- resize(c, nx, ny, nw, nh, RESIZEHINTS);
+ resize(c, nx, ny, nw, nh, True);
+ if((c->h < bh) || (c->h > nh) || (c->w < bh) || (c->w > nw))
+ /* client doesn't accept size constraints */
+ resize(c, nx, ny, nw, nh, False);
if(n > 1 && th != wah)
- ny += nh + 2 * c->border;
+ ny = c->y + c->h + 2 * c->border;
}
}
return;
i = idxoftag(arg);
sel->tags[i] = !sel->tags[i];
- for(j = 0; j < ntags && !sel->tags[j]; j++);
- if(j == ntags)
- sel->tags[i] = True;
+ for(j = 0; j < NTAGS && !sel->tags[j]; j++);
+ if(j == NTAGS)
+ sel->tags[i] = True; /* at least one tag must be enabled */
arrange();
}
i = idxoftag(arg);
seltags[i] = !seltags[i];
- for(j = 0; j < ntags && !seltags[j]; j++);
- if(j == ntags)
+ for(j = 0; j < NTAGS && !seltags[j]; j++);
+ if(j == NTAGS)
seltags[i] = True; /* at least one tag must be viewed */
arrange();
}
view(const char *arg) {
unsigned int i;
- for(i = 0; i < ntags; i++)
+ memcpy(prevtags, seltags, sizeof seltags);
+ for(i = 0; i < NTAGS; i++)
seltags[i] = arg == NULL;
- i = idxoftag(arg);
- if(i >= 0 && i < ntags)
- seltags[i] = True;
+ seltags[idxoftag(arg)] = True;
+ arrange();
+}
+
+void
+viewprevtag(const char *arg) {
+ static Bool tmptags[sizeof tags / sizeof tags[0]];
+
+ memcpy(tmptags, seltags, sizeof seltags);
+ memcpy(seltags, prevtags, sizeof seltags);
+ memcpy(prevtags, tmptags, sizeof seltags);
arrange();
}
zoom(const char *arg) {
Client *c;
- if(!sel || !ISTILE || sel->isfloating)
+ if(!sel || !(ISTILE) || sel->isfloating)
return;
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))