* set the override_redirect flag. Clients are organized in a global
* doubly-linked client list, the focus history is remembered through a global
* stack list. Each client contains an array of Bools of the same size as the
- * global tags array to indicate the tags of a client. For each client dwm
- * creates a small title window, which is resized whenever the (_NET_)WM_NAME
- * properties are updated or the client is moved/resized.
+ * global tags array to indicate the tags of a client.
*
* Keys and tagging rules are organized as arrays and defined in config.h.
*
/* macros */
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
+#define LENGTH(x) (sizeof x / sizeof x[0])
+#define MAXTAGLEN 16
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
+
/* enums */
enum { BarTop, BarBot, BarOff }; /* bar position */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
-enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
+enum { NetSupported, NetWMCheck, NetWMName, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
/* typedefs */
long getstate(Window w);
Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
void grabbuttons(Client *c, Bool focused);
+void grabkeys(void);
unsigned int idxoftag(const char *tag);
void initfont(const char *fontstr);
Bool isoccupied(unsigned int t);
/* configuration, allows nested code to access above variables */
#include "config.h"
+Bool prevtags[LENGTH(tags)];
+
/* function implementations */
void
applyrules(Client *c) {
Client *c;
XButtonPressedEvent *ev = &e->xbutton;
- if(barwin == ev->window) {
+ if(ev->window == barwin) {
x = 0;
for(i = 0; i < LENGTH(tags); i++) {
x += textw(tags[i]);
if(CLEANMASK(ev->state) != MODKEY)
return;
if(ev->button == Button1) {
- if((floating == layout->arrange) || c->isfloating)
+ if((layout->arrange == floating) || c->isfloating)
restack();
else
togglefloating(NULL);
expose(XEvent *e) {
XExposeEvent *ev = &e->xexpose;
- if(0 == ev->count) {
- if(barwin == ev->window)
+ if(ev->count == 0) {
+ if(ev->window == barwin)
drawbar();
}
}
int n;
XTextProperty name;
- if(!text || 0 == size)
+ if(!text || size == 0)
return False;
text[0] = '\0';
XGetTextProperty(dpy, w, &name, atom);
strncpy(text, (char *)name.value, size - 1);
else {
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
- && n > 0 && *list)
- {
+ && n > 0 && *list) {
strncpy(text, *list, size - 1);
XFreeStringList(list);
}
GrabModeAsync, GrabModeSync, None, None);
}
+void
+grabkeys(void) {
+ unsigned int i;
+ KeyCode code;
+
+ XUngrabKey(dpy, AnyKey, AnyModifier, root);
+ for(i = 0; i < LENGTH(keys); i++) {
+ code = XKeysymToKeycode(dpy, keys[i].keysym);
+ XGrabKey(dpy, code, keys[i].mod, root, True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey(dpy, code, keys[i].mod | LockMask, root, True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True,
+ GrabModeAsync, GrabModeAsync);
+ XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True,
+ GrabModeAsync, GrabModeAsync);
+ }
+}
+
unsigned int
idxoftag(const char *tag) {
unsigned int i;
void
keypress(XEvent *e) {
- KEYS
unsigned int i;
- KeyCode code;
KeySym keysym;
XKeyEvent *ev;
- if(!e) { /* grabkeys */
- XUngrabKey(dpy, AnyKey, AnyModifier, root);
- for(i = 0; i < LENGTH(keys); i++) {
- code = XKeysymToKeycode(dpy, keys[i].keysym);
- XGrabKey(dpy, code, keys[i].mod, root, True,
- GrabModeAsync, GrabModeAsync);
- XGrabKey(dpy, code, keys[i].mod | LockMask, root, True,
- GrabModeAsync, GrabModeAsync);
- XGrabKey(dpy, code, keys[i].mod | numlockmask, root, True,
- GrabModeAsync, GrabModeAsync);
- XGrabKey(dpy, code, keys[i].mod | numlockmask | LockMask, root, True,
- GrabModeAsync, GrabModeAsync);
- }
- return;
- }
ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for(i = 0; i < LENGTH(keys); i++)
XRefreshKeyboardMapping(ev);
if(ev->request == MappingKeyboard)
- keypress(NULL);
+ grabkeys();
}
void
default: break;
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
- if(!c->isfloating && (c->isfloating = (NULL != getclient(trans))))
+ if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
arrange();
break;
case XA_WM_NORMAL_HINTS:
readin = running = False;
}
+
void
resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
XWindowChanges wc;
drawbar();
if(!sel)
return;
- if(sel->isfloating || (floating == layout->arrange))
+ if(sel->isfloating || (layout->arrange == floating))
XRaiseWindow(dpy, sel->win);
- if(floating != layout->arrange) {
+ if(layout->arrange != floating) {
wc.stack_mode = Below;
wc.sibling = barwin;
if(!sel->isfloating) {
void
run(void) {
char *p;
- int r, xfd;
+ char buf[sizeof stext];
fd_set rd;
+ int r, xfd;
+ unsigned int len, offset;
XEvent ev;
/* main event loop, also reads status text from stdin */
XSync(dpy, False);
xfd = ConnectionNumber(dpy);
readin = True;
+ offset = 0;
+ len = sizeof stext - 1;
+ buf[len] = stext[len] = '\0'; /* 0-terminator is never touched */
while(running) {
FD_ZERO(&rd);
if(readin)
eprint("select failed\n");
}
if(FD_ISSET(STDIN_FILENO, &rd)) {
- switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
+ switch((r = read(STDIN_FILENO, buf + offset, len - offset))) {
case -1:
- strncpy(stext, strerror(errno), sizeof stext - 1);
- stext[sizeof stext - 1] = '\0';
+ strncpy(stext, strerror(errno), len);
readin = False;
break;
case 0:
readin = False;
break;
default:
- for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
- for(; p >= stext && *p != '\n'; --p);
- if(p > stext)
- strncpy(stext, p + 1, sizeof stext);
+ for(p = buf + offset; r > 0; p++, r--, offset++)
+ if(*p == '\n' || *p == '\0') {
+ *p = '\0';
+ strncpy(stext, buf, len);
+ p += r - 1; /* p is buf + offset + r - 1 */
+ for(r = 0; *(p - r) && *(p - r) != '\n'; r++);
+ offset = r;
+ if(r)
+ memmove(buf, p - r + 1, r);
+ break;
+ }
+ break;
}
drawbar();
}
if(!domwfact)
return;
/* arg handling, manipulate mwfact */
- if(NULL == arg)
+ if(arg == NULL)
mwfact = MWFACT;
- else if(1 == sscanf(arg, "%lf", &delta)) {
+ else if(sscanf(arg, "%lf", &delta) == 1) {
if(arg[0] == '+' || arg[0] == '-')
mwfact += delta;
else
setup(void) {
int d;
unsigned int i, j, mask;
+ Atom utf8string;
Window w;
XModifierKeymap *modmap;
XSetWindowAttributes wa;
/* init atoms */
+ utf8string = XInternAtom(dpy, "UTF8_STRING", False);
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[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False);
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
- XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
- PropModeReplace, (unsigned char *) netatom, NetLast);
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
XSelectInput(dpy, root, wa.event_mask);
/* grab keys */
- keypress(NULL);
+ grabkeys();
/* init tags */
+ memcpy(prevtags, seltags, sizeof seltags);
compileregs();
/* init appearance */
/* multihead support */
selscreen = XQueryPointer(dpy, root, &w, &w, &d, &d, &d, &d, &mask);
+
+ /* EWMH properties */
+ XChangeProperty(dpy, barwin, netatom[NetWMCheck], XA_WINDOW, 32,
+ PropModeReplace, (unsigned char *) &barwin, 1);
+ /* HACK: dwm identifies itself as LookingGlass to workaround the XToolkit bug of Sun JDK */
+ XChangeProperty(dpy, barwin, netatom[NetWMName], utf8string, 8,
+ PropModeReplace, (unsigned char *) "LG3D", 4);
+ XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
+ PropModeReplace, (unsigned char *) &barwin, 1);
+ XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
+ PropModeReplace, (unsigned char *) netatom, NetLast);
}
void
return;
/* The double-fork construct avoids zombie processes and keeps the code
* clean from stupid signal handlers. */
- if(0 == fork()) {
- if(0 == fork()) {
+ if(fork() == 0) {
+ if(fork() == 0) {
if(dpy)
close(ConnectionNumber(dpy));
setsid();
nw = 0; /* gcc stupidity requires this */
for(i = 0, c = mc = nexttiled(clients); c; c = nexttiled(c->next), i++) {
c->ismax = False;
- if(0 == i) { /* master */
+ if(i == 0) { /* master */
nw = mw - 2 * c->border;
nh = wah - 2 * c->border;
}
if(!sel || sel->isfixed)
return;
if((sel->ismax = !sel->ismax)) {
- if((floating == layout->arrange) || sel->isfloating)
+ if((layout->arrange == floating) || sel->isfloating)
sel->wasfloating = True;
else {
togglefloating(NULL);
void
viewprevtag(const char *arg) {
- static Bool tmptags[sizeof tags / sizeof tags[0]];
+ static Bool tmp[LENGTH(tags)];
- memcpy(tmptags, seltags, sizeof seltags);
+ memcpy(tmp, seltags, sizeof seltags);
memcpy(seltags, prevtags, sizeof seltags);
- memcpy(prevtags, tmptags, sizeof seltags);
+ memcpy(prevtags, tmp, sizeof seltags);
arrange();
}
int
main(int argc, char *argv[]) {
if(argc == 2 && !strcmp("-v", argv[1]))
- eprint("dwm-"VERSION", © 2006-2007 A. R. Garbe, S. van Dijk, J. Salmi, P. Hruby, S. Nagy\n");
+ eprint("dwm-"VERSION", © 2006-2007 Anselm R. Garbe, Sander van Dijk, "
+ "Jukka Salmi, Premysl Hruby, Szabolcs Nagy\n");
else if(argc != 1)
eprint("usage: dwm [-v]\n");