enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
-enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
+enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
static void unmapnotify(XEvent *e);
static void updatebar(void);
static void updategeom(void);
+static void updatenumlockmask(void);
static void updatesizehints(Client *c);
static void updatetitle(Client *c);
static void updatewmhints(Client *c);
/* variables */
static char stext[256];
static int screen;
-static int sx, sy, sw, sh; /* display geometry x, y, width, height */
+static int sx, sy, sw, sh; /* X display screen geometry x, y, width, height */
static int by, bh, blw; /* bar geometry y, height and layout symbol width */
static int wx, wy, ww, wh; /* window area geometry x, y, width, height, bar excluded */
static unsigned int seltags = 0, sellt = 0;
void
drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
+ char buf[256];
int i, x, y, h, len, olen;
XRectangle r = { dc.x, dc.y, dc.w, dc.h };
- char buf[256];
XSetForeground(dpy, dc.gc, col[invert ? ColFG : ColBG]);
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
if(!text)
return;
olen = strlen(text);
- len = MIN(olen, sizeof buf);
- memcpy(buf, text, len);
h = dc.font.ascent + dc.font.descent;
y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
x = dc.x + (h / 2);
/* shorten text if necessary */
- for(; len && (i = textnw(buf, len)) > dc.w - h; len--);
+ for(len = MIN(olen, sizeof buf); len && textnw(text, len) > dc.w - h; len--);
if(!len)
return;
+ memcpy(buf, text, len);
if(len < olen)
for(i = len; i && i > len - 3; buf[--i] = '.');
XSetForeground(dpy, dc.gc, col[invert ? ColBG : ColFG]);
void
grabbuttons(Client *c, Bool focused) {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
-
- XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
- if(focused) {
- 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);
- } else
- XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
- BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+ updatenumlockmask();
+ {
+ unsigned int i, j;
+ unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+ XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
+ if(focused) {
+ 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);
+ } else
+ XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
+ BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
+ }
}
void
grabkeys(void) {
- unsigned int i, j;
- unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
- KeyCode code;
- XModifierKeymap *modmap;
-
- /* init modifier map */
- modmap = XGetModifierMapping(dpy);
- for(i = 0; i < 8; i++)
- for(j = 0; j < modmap->max_keypermod; j++) {
- if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
- numlockmask = (1 << i);
+ updatenumlockmask();
+ { /* grab keys */
+ unsigned int i, j;
+ unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
+ KeyCode code;
+
+ XUngrabKey(dpy, AnyKey, AnyModifier, root);
+ for(i = 0; i < LENGTH(keys); i++) {
+ code = XKeysymToKeycode(dpy, keys[i].keysym);
+ for(j = 0; j < LENGTH(modifiers); j++)
+ XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True,
+ GrabModeAsync, GrabModeAsync);
}
- XFreeModifiermap(modmap);
-
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for(i = 0; i < LENGTH(keys); i++) {
- code = XKeysymToKeycode(dpy, keys[i].keysym);
- for(j = 0; j < LENGTH(modifiers); j++)
- XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, True,
- GrabModeAsync, GrabModeAsync);
}
}
int i, n;
missing = NULL;
- if(dc.font.set)
- XFreeFontSet(dpy, dc.font.set);
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
if(missing) {
while(n--)
void
manage(Window w, XWindowAttributes *wa) {
Client *c, *t = NULL;
- Window trans = 0;
+ Window trans = None;
XWindowChanges wc;
if(!(c = calloc(1, sizeof(Client))))
else
applyrules(c);
if(!c->isfloating)
- c->isfloating = trans || c->isfixed;
+ c->isfloating = trans != None || c->isfixed;
if(c->isfloating)
XRaiseWindow(dpy, c->win);
attach(c);
if(!(c = sel))
return;
restack();
- ocx = nx = c->x;
- ocy = ny = c->y;
+ ocx = c->x;
+ ocy = c->y;
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess)
return;
XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
- for(;;) {
+ do {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch (ev.type) {
- case ButtonRelease:
- XUngrabPointer(dpy, CurrentTime);
- return;
case ConfigureRequest:
case Expose:
case MapRequest:
break;
}
}
+ while(ev.type != ButtonRelease);
+ XUngrabPointer(dpy, CurrentTime);
}
Client *
XWindowChanges wc;
if(sizehints) {
+ /* see last two sentences in ICCCM 4.1.2.3 */
+ Bool baseismin = c->basew == c->minw && c->baseh == c->minh;
+
/* set minimum possible */
w = MAX(1, w);
h = MAX(1, h);
- /* temporarily remove base dimensions */
- w -= c->basew;
- h -= c->baseh;
+ if(!baseismin) { /* temporarily remove base dimensions */
+ w -= c->basew;
+ h -= c->baseh;
+ }
/* adjust for aspect limits */
if(c->mina > 0 && c->maxa > 0) {
- if(c->maxa < (float) w/h)
+ if(c->maxa < (float)(w / h))
w = h * c->maxa;
- else if(c->mina > (float) h/w)
+ else if(c->mina < (float)(h / w))
h = w * c->mina;
}
+ if(baseismin) { /* increment calculation requires this */
+ w -= c->basew;
+ h -= c->baseh;
+ }
+
/* adjust for increment value */
if(c->incw)
w -= w % c->incw;
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
- for(;;) {
- XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev);
+ do {
+ XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch(ev.type) {
- case 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));
- return;
case ConfigureRequest:
case Expose:
case MapRequest:
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));
}
void
void
scan(void) {
unsigned int i, num;
- Window *wins, d1, d2;
+ Window d1, d2, *wins = NULL;
XWindowAttributes wa;
- wins = NULL;
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(dpy, wins[i], &wa)
&& (wa.map_state == IsViewable || getstate(wins[i]) == IconicState))
manage(wins[i], &wa);
}
+ if(wins)
+ XFree(wins);
}
- if(wins)
- XFree(wins);
}
void
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
- wmatom[WMName] = XInternAtom(dpy, "WM_NAME", False);
wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False);
netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
-
- /* grab keys */
grabkeys();
}
void
toggletag(const Arg *arg) {
- unsigned int mask = sel->tags ^ (arg->ui & TAGMASK);
+ unsigned int mask;
+ if (!sel)
+ return;
+
+ mask = sel->tags ^ (arg->ui & TAGMASK);
if(sel && mask) {
sel->tags = mask;
arrange();
by = showbar ? (topbar ? wy - bh : wy + wh) : -bh;
}
+void
+updatenumlockmask(void) {
+ unsigned int i, j;
+ XModifierKeymap *modmap;
+
+ numlockmask = 0;
+ modmap = XGetModifierMapping(dpy);
+ for(i = 0; i < 8; i++)
+ for(j = 0; j < modmap->max_keypermod; j++)
+ if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
+ numlockmask = (1 << i);
+ XFreeModifiermap(modmap);
+}
+
void
updatesizehints(Client *c) {
long msize;
void
updatetitle(Client *c) {
if(!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name))
- gettextprop(c->win, wmatom[WMName], c->name, sizeof c->name);
+ gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name);
}
void
void
view(const Arg *arg) {
- if(arg && (arg->ui & TAGMASK) == tagset[seltags])
+ if((arg->ui & TAGMASK) == tagset[seltags])
return;
seltags ^= 1; /* toggle sel tagset */
- if(arg && (arg->ui & TAGMASK))
+ if(arg->ui & TAGMASK)
tagset[seltags] = arg->ui & TAGMASK;
clearurgent();
arrange();