Compare commits

..

87 Commits
3.6.1 ... 4.1

Author SHA1 Message Date
fa32f02a43 no that change breaks fullscreen apps 2007-05-16 22:05:02 +02:00
598e22907e raise barwin in restack, that's the most elegant solution I think 2007-05-16 21:59:53 +02:00
1e826ddd3e simplification 2007-05-15 14:06:18 +02:00
a967d7f664 raising the barwin has no effect becasue of restack 2007-05-15 13:58:29 +02:00
ce450c5bf1 fix 2007-05-15 13:56:47 +02:00
8f5f7a5b5a barwindow raising 2007-05-15 13:56:06 +02:00
5ad2828c57 using BarTop as fallback if BARPOS is set to BarOff as default for toggling 2007-05-15 13:49:43 +02:00
b896b58d6d removed strip, added -s to LDFLAGS 2007-05-15 13:44:04 +02:00
fef6c5c66b added new Mod1-b functionality to dwm(1) 2007-05-15 13:42:07 +02:00
37e062b0ed another fix, call lt->arrange() in togglebar only 2007-05-15 13:36:04 +02:00
cf58091736 fixed bpos init 2007-05-15 13:23:51 +02:00
2aef8b9b4c made bar togglalble 2007-05-15 12:09:18 +02:00
d96307cbe4 thanks to Jukka 2007-05-14 16:24:01 +02:00
124866e269 added the GTK Save-As bug report to BUGS section of dwm(1) 2007-05-14 13:42:00 +02:00
ab3d6a7dfe applied dfenze cleanups, fixed some comments in dwm.h 2007-05-14 11:54:30 +02:00
c67dbb28e4 small fix of fix 2007-05-10 13:49:17 +02:00
b8bccb4ac5 fixed a potential security flaw 2007-05-10 13:47:44 +02:00
b6b2f584ec applied Maarten Maathuis recenter-patch for floating clients only requesting new width and height exceeding the screen space 2007-05-09 11:31:14 +02:00
f7bdb39d9e s/remain/remainder/ 2007-05-09 10:12:55 +02:00
ecd9c3e222 fixing remaining space calculation 2007-05-09 10:11:34 +02:00
216099d072 thanks to Juka to check -Wall ;) 2007-05-08 08:52:34 +02:00
fc2e3eae20 next version is 4.1 2007-05-07 13:14:55 +02:00
f9e7a33019 applied patch of Paul Liu to allow onthefly resizing due to xrandr changes 2007-05-07 13:12:41 +02:00
7c9fa2566f Added tag 4.0 for changeset 018c38468422 2007-04-19 09:26:44 +02:00
22399a3bc0 fixed the border issue for mplayer, ff is definately broken when using F11 (fullscreen mode) 2007-04-19 09:24:25 +02:00
ad2508f957 touch border 2007-04-19 08:53:40 +02:00
b078599833 set border at manage time 2007-04-18 21:11:46 +02:00
1e80207876 using pixelcarnage-monospace (proggyclean), because this is better to the eyes 2007-04-18 17:29:38 +02:00
464fc2cd18 changed border handling 2007-04-17 14:56:46 +02:00
be8d6d40f6 changing order of c->border restorage 2007-04-13 12:22:00 +02:00
f0c2353393 I used 2006 in other places as well 2007-04-13 11:41:39 +02:00
a730213c3b yet another fix of copyright compactisition 2007-04-13 11:40:09 +02:00
399993c6b5 making Copyright notices more compact 2007-04-13 11:32:38 +02:00
4d318060a2 next version will be 4.0, so don't expect it within the next days 2007-04-11 15:18:16 +02:00
540d5eed46 make also transients floating when we do not know the main window 2007-04-11 15:17:29 +02:00
7d071ce2bd Added tag 3.9 for changeset 55478328b242 2007-04-02 11:11:47 +02:00
93aeaa53c9 next version will be 3.9, but don't expect it this week 2007-03-29 15:18:30 +02:00
06f9f346e6 add an additional check in resize() to prevent a crash of dwm 2007-03-29 15:17:57 +02:00
5c48012ad2 Added tag 3.8 for changeset 2ea201354cf0 2007-03-05 11:54:59 +01:00
a686c9ccd2 we don't need to set the font all the time 2007-03-02 15:14:40 +01:00
9ca5c3b108 some changes to updatesizehints, I don't change the aspect ratio algorithm now - I can't think, it is a mess 2007-03-01 12:33:45 +01:00
bab5b1178d removed sendevent 2007-02-26 16:24:51 +01:00
ee8fb0c6e4 Escape -s in dwm.1 2007-02-26 10:47:11 +01:00
0d9d3e79e9 Added tag 3.7 for changeset baee494346e5 2007-02-24 15:41:05 +01:00
12280f0253 prepared 3.7, ready to rambo 2007-02-24 15:40:50 +01:00
a58731e835 removed an unnecessary newline 2007-02-24 14:08:27 +01:00
1df45593ed removed superfluous externs (except for tags, because tags is defined in the source) 2007-02-24 14:06:35 +01:00
2122e39ce1 replacing Mod1-i with Mod1-Shift-j, Mod1-d with Mod1-Shift-k 2007-02-23 13:37:55 +01:00
e70139428a oops, small bugfix in my config 2007-02-23 11:17:07 +01:00
3d1d75a224 default masterwidth should also be at 600 2007-02-23 11:13:57 +01:00
35f08f4231 changed order if h/l 2007-02-23 11:09:18 +01:00
0ea0343a63 well I agree to several people claiming h/j/k/l is the better default than Tab/S-Tab/g/s for focus and master resizing 2007-02-23 10:40:32 +01:00
338c083858 renamed untiled into floating, keeping tiled instead of tiling (afaik tiled sounds more correct) - English speakers convinced me 2007-02-22 22:10:16 +01:00
671442e89d hahaha, untiled and non-untiled sounded really cumbersome 2007-02-22 18:22:51 +01:00
8d111632f5 made Fnt an anonymous inner struct 2007-02-22 18:17:07 +01:00
fe5acb939a made Fnt an anonymous inner struct 2007-02-22 18:08:31 +01:00
cac492b0e9 nah, I don't want 640 as MASTERWIDTH 2007-02-22 17:58:45 +01:00
ef9b3e173c using MASTERWIDTH=640 and 32px steps by default (incmasterw()) 2007-02-22 17:52:45 +01:00
5a13632afb simplified focusclient() 2007-02-22 17:51:34 +01:00
587100873a renamed versatile into untiled 2007-02-22 17:43:41 +01:00
27b0595af7 merged focus{prev.next} into focusclient(1/-1) 2007-02-22 15:25:19 +01:00
12d5a26fd2 made dwm.h more tidy (thx Jukka for the zoom() hint) 2007-02-22 15:06:56 +01:00
89b7f1503e oops 2007-02-22 12:16:58 +01:00
5711609203 small bugfix 2007-02-22 12:15:48 +01:00
825b7c3eb1 fixed some issues due to the Arg->const char * transition 2007-02-22 12:00:02 +01:00
ba96131af0 restoring default keybindings as Sander complained 2007-02-22 11:45:03 +01:00
2c477cf661 replaced Arg union with const char *arg, seems cleaner to me, even if we need atoi() in some places 2007-02-22 11:42:08 +01:00
986ca73074 re-added xterm to config.default.h 2007-02-22 11:15:31 +01:00
288098893c removed button4/5-bindings for incnmaster on mode label - that is misleading 2007-02-22 11:09:44 +01:00
cb9607c284 fixed order of key bindings described in dwm.1 2007-02-22 11:06:37 +01:00
4bd4f421d3 status needs update even in togglemax() - since we got an indicator for this 2007-02-22 10:59:42 +01:00
84432e6b36 reusing drawsquare for client title, empty square before title means versatile window, filled square before title means versatile maximized window. 2007-02-22 10:57:19 +01:00
1a25414ace dwm draws a small caret before the client title if it's a versatile client 2007-02-22 10:52:57 +01:00
3171371498 nah grouped keybindings by context 2007-02-22 09:29:38 +01:00
92105e7862 fixed exit condition in togglemax() 2007-02-22 08:08:36 +01:00
6ee9f13457 fixing missing extern declars in dwm.h for {de,at}tach() 2007-02-22 08:02:04 +01:00
352cae4380 several changes, made togglemax extern and separated it from zoom() - moved zoom() and togglemax() into layout.c, changed void (*func)(Arg *) into void (*func)(Arg), changed default keybindings of focusnext/focusprev and incmasterw to h/j/k/l accordingly, made keys in config*h appear alphabetically (special keys first), renamed resizemaster into incmasterw, renamed MASTER into MASTERWIDTH 2007-02-22 07:59:13 +01:00
b3b58c08e4 just ignore the FD_ISSET check in main.c of xfd, just call XPending (which does the same afair) 2007-02-21 21:36:54 +01:00
204f0a340d optimizing background color of terminals 2007-02-21 17:00:06 +01:00
78666b99b8 using 333 as background, hey proggyclean is really good 2007-02-21 16:57:21 +01:00
0bdcf75e25 switching to 13pt proggyclean (this fits better my 1920x1200 resolution than 12pt terminus which is too small or 14pt terminus which is too fat) 2007-02-21 16:53:25 +01:00
f1009285d8 using smaller font 2007-02-21 16:47:53 +01:00
f76b3a4685 using a green selborder 2007-02-21 15:47:52 +01:00
84ae6e12eb reverting to bg 555 2007-02-21 13:31:04 +01:00
784659565a s/555/357/ for SELCOLOR 2007-02-21 13:29:02 +01:00
7ae0c198b3 switching to urxvtcd for the moment (the uxterm flicker makes me headaches, st is really highest prio now) 2007-02-21 13:24:37 +01:00
dc6623728d Added tag 3.6.1 for changeset 20ec6976cee1 2007-02-21 12:09:10 +01:00
15 changed files with 627 additions and 555 deletions

View File

@ -38,3 +38,8 @@ d3876aa792923f9a95f7ad0c7f0134533404df35 3.2.2
9ede7b2d2450537e750d5505789fbe63960e97e6 3.4 9ede7b2d2450537e750d5505789fbe63960e97e6 3.4
63ad05e7f9e1f4f1881fb02f529cb6c6ae81e693 3.5 63ad05e7f9e1f4f1881fb02f529cb6c6ae81e693 3.5
75b1b25fe0d7e29400baf30568153f668324928b 3.6 75b1b25fe0d7e29400baf30568153f668324928b 3.6
20ec6976cee1fcfee0c2f354ae382ee3f9f68efa 3.6.1
baee494346e520f8dee2cee9491b8350064770d2 3.7
2ea201354cf016407ea93e1e390d1422940d29b0 3.8
55478328b2422c700c5404a774c85e77322f41a3 3.9
018c3846842291cb6c009dc087e7fe2f0ef53bea 4.0

View File

@ -1,7 +1,7 @@
MIT/X Consortium License MIT/X Consortium License
(C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
(C)opyright MMVI-MMVII Sander van Dijk <a dot h dot vandijk at gmail dot com> © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
Permission is hereby granted, free of charge, to any person obtaining a Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"), copy of this software and associated documentation files (the "Software"),

View File

@ -1,5 +1,5 @@
# dwm - dynamic window manager # dwm - dynamic window manager
# (C)opyright MMVI-MMVII Anselm R. Garbe # © 2006-2007 Anselm R. Garbe, Sander van Dijk
include config.mk include config.mk
@ -27,7 +27,6 @@ config.h:
dwm: ${OBJ} dwm: ${OBJ}
@echo CC -o $@ @echo CC -o $@
@${CC} -o $@ ${OBJ} ${LDFLAGS} @${CC} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean: clean:
@echo cleaning @echo cleaning

177
client.c
View File

@ -1,6 +1,6 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -83,24 +83,6 @@ setclientstate(Client *c, long state) {
PropModeReplace, (unsigned char *)data, 2); PropModeReplace, (unsigned char *)data, 2);
} }
static void
togglemax(Client *c) {
XEvent ev;
if(c->isfixed)
return;
if((c->ismax = !c->ismax)) {
c->rx = c->x;
c->ry = c->y;
c->rw = c->w;
c->rh = c->h;
resize(c, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
}
else
resize(c, c->rx, c->ry, c->rw, c->rh, True);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
static int static int
xerrordummy(Display *dsply, XErrorEvent *ee) { xerrordummy(Display *dsply, XErrorEvent *ee) {
return 0; return 0;
@ -171,19 +153,37 @@ focus(Client *c) {
} }
void void
killclient(Arg *arg) { focustopvisible(void) {
Client *c;
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
}
void
killclient(const char *arg) {
XEvent ev;
if(!sel) if(!sel)
return; return;
if(isprotodel(sel)) if(isprotodel(sel)) {
sendevent(sel->win, wmatom[WMProtocols], wmatom[WMDelete]); ev.type = ClientMessage;
ev.xclient.window = sel->win;
ev.xclient.message_type = wmatom[WMProtocols];
ev.xclient.format = 32;
ev.xclient.data.l[0] = wmatom[WMDelete];
ev.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, sel->win, False, NoEventMask, &ev);
}
else else
XKillClient(dpy, sel->win); XKillClient(dpy, sel->win);
} }
void void
manage(Window w, XWindowAttributes *wa) { manage(Window w, XWindowAttributes *wa) {
Client *c, *t; Client *c, *t = NULL;
Window trans; Window trans;
Status rettrans;
XWindowChanges wc; XWindowChanges wc;
c = emallocz(sizeof(Client)); c = emallocz(sizeof(Client));
@ -193,13 +193,13 @@ manage(Window w, XWindowAttributes *wa) {
c->y = wa->y; c->y = wa->y;
c->w = wa->width; c->w = wa->width;
c->h = wa->height; c->h = wa->height;
c->oldborder = wa->border_width;
if(c->w == sw && c->h == sh) { if(c->w == sw && c->h == sh) {
c->border = 0;
c->x = sx; c->x = sx;
c->y = sy; c->y = sy;
c->border = wa->border_width;
} }
else { else {
c->border = BORDERPX;
if(c->x + c->w + 2 * c->border > wax + waw) if(c->x + c->w + 2 * c->border > wax + waw)
c->x = wax + waw - c->w - 2 * c->border; c->x = wax + waw - c->w - 2 * c->border;
if(c->y + c->h + 2 * c->border > way + wah) if(c->y + c->h + 2 * c->border > way + wah)
@ -208,21 +208,22 @@ manage(Window w, XWindowAttributes *wa) {
c->x = wax; c->x = wax;
if(c->y < way) if(c->y < way)
c->y = way; c->y = way;
c->border = BORDERPX;
} }
updatesizehints(c);
XSelectInput(dpy, w,
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
XGetTransientForHint(dpy, w, &trans);
grabbuttons(c, False);
wc.border_width = c->border; wc.border_width = c->border;
XConfigureWindow(dpy, w, CWBorderWidth, &wc); XConfigureWindow(dpy, w, CWBorderWidth, &wc);
XSetWindowBorder(dpy, w, dc.norm[ColBorder]); XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
configure(c); /* propagates border_width, if size doesn't change */ configure(c); /* propagates border_width, if size doesn't change */
updatesizehints(c);
XSelectInput(dpy, w,
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
grabbuttons(c, False);
updatetitle(c); updatetitle(c);
for(t = clients; t && t->win != trans; t = t->next); if((rettrans = XGetTransientForHint(dpy, w, &trans) == Success))
for(t = clients; t && t->win != trans; t = t->next);
settags(c, t); settags(c, t);
if(!c->isversatile) if(!c->isfloating)
c->isversatile = (t != NULL) || c->isfixed; c->isfloating = (rettrans == Success) || c->isfixed;
attach(c); attach(c);
attachstack(c); attachstack(c);
c->isbanned = True; c->isbanned = True;
@ -236,12 +237,33 @@ manage(Window w, XWindowAttributes *wa) {
void void
resize(Client *c, int x, int y, int w, int h, Bool sizehints) { resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
float actual, dx, dy, max, min; float dx, dy, max, min, ratio;
XWindowChanges wc; XWindowChanges wc;
if(w <= 0 || h <= 0) if(w <= 0 || h <= 0)
return; return;
if(sizehints) { if(sizehints) {
if(c->minay > 0 && c->maxay > 0 && (h - c->baseh) > 0) {
dx = (float)(w - c->basew);
dy = (float)(h - c->baseh);
min = (float)(c->minax) / (float)(c->minay);
max = (float)(c->maxax) / (float)(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;
}
}
}
if(c->minw && w < c->minw) if(c->minw && w < c->minw)
w = c->minw; w = c->minw;
if(c->minh && h < c->minh) if(c->minh && h < c->minh)
@ -250,37 +272,13 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
w = c->maxw; w = c->maxw;
if(c->maxh && h > c->maxh) if(c->maxh && h > c->maxh)
h = c->maxh; h = c->maxh;
/* inspired by algorithm from fluxbox */
if(c->minay > 0 && c->maxay && (h - c->baseh) > 0) {
dx = (float)(w - c->basew);
dy = (float)(h - c->baseh);
min = (float)(c->minax) / (float)(c->minay);
max = (float)(c->maxax) / (float)(c->maxay);
actual = dx / dy;
if(max > 0 && min > 0 && actual > 0) {
if(actual < min) {
dy = (dx * min + dy) / (min * min + 1);
dx = dy * min;
w = (int)dx + c->basew;
h = (int)dy + c->baseh;
}
else if(actual > max) {
dy = (dx * min + dy) / (max * max + 1);
dx = dy * min;
w = (int)dx + c->basew;
h = (int)dy + c->baseh;
}
}
}
if(c->incw) if(c->incw)
w -= (w - c->basew) % c->incw; w -= (w - c->basew) % c->incw;
if(c->inch) if(c->inch)
h -= (h - c->baseh) % c->inch; h -= (h - c->baseh) % c->inch;
} }
if(w == sw && h == sh) if(w <= 0 || h <= 0)
c->border = 0; return;
else
c->border = BORDERPX;
/* offscreen appearance fixes */ /* offscreen appearance fixes */
if(x > sw) if(x > sw)
x = sw - w - 2 * c->border; x = sw - w - 2 * c->border;
@ -303,10 +301,10 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
} }
void void
toggleversatile(Arg *arg) { togglefloating(const char *arg) {
if(!sel || lt->arrange == versatile) if(!sel || lt->arrange == floating)
return; return;
sel->isversatile = !sel->isversatile; sel->isfloating = !sel->isfloating;
lt->arrange(); lt->arrange();
} }
@ -322,6 +320,10 @@ updatesizehints(Client *c) {
c->basew = size.base_width; c->basew = size.base_width;
c->baseh = size.base_height; c->baseh = size.base_height;
} }
else if(c->flags & PMinSize) {
c->basew = size.min_width;
c->baseh = size.min_height;
}
else else
c->basew = c->baseh = 0; c->basew = c->baseh = 0;
if(c->flags & PResizeInc) { if(c->flags & PResizeInc) {
@ -340,16 +342,20 @@ updatesizehints(Client *c) {
c->minw = size.min_width; c->minw = size.min_width;
c->minh = size.min_height; c->minh = size.min_height;
} }
else if(c->flags & PBaseSize) {
c->minw = size.base_width;
c->minh = size.base_height;
}
else else
c->minw = c->minh = 0; c->minw = c->minh = 0;
if(c->flags & PAspect) { if(c->flags & PAspect) {
c->minax = size.min_aspect.x; c->minax = size.min_aspect.x;
c->minay = size.min_aspect.y;
c->maxax = size.max_aspect.x; c->maxax = size.max_aspect.x;
c->minay = size.min_aspect.y;
c->maxay = size.max_aspect.y; c->maxay = size.max_aspect.y;
} }
else else
c->minax = c->minay = c->maxax = c->maxay = 0; c->minax = c->maxax = c->minay = c->maxay = 0;
c->isfixed = (c->maxw && c->minw && c->maxh && c->minh c->isfixed = (c->maxw && c->minw && c->maxh && c->minh
&& c->maxw == c->minw && c->maxh == c->minh); && c->maxw == c->minw && c->maxh == c->minh);
} }
@ -368,31 +374,32 @@ updatetitle(Client *c) {
if(!name.nitems) if(!name.nitems)
return; return;
if(name.encoding == XA_STRING) if(name.encoding == XA_STRING)
strncpy(c->name, (char *)name.value, sizeof c->name); strncpy(c->name, (char *)name.value, sizeof c->name - 1);
else { else {
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
&& n > 0 && *list) && n > 0 && *list)
{ {
strncpy(c->name, *list, sizeof c->name); strncpy(c->name, *list, sizeof c->name - 1);
XFreeStringList(list); XFreeStringList(list);
} }
} }
c->name[sizeof c->name - 1] = '\0';
XFree(name.value); XFree(name.value);
} }
void void
unmanage(Client *c) { unmanage(Client *c) {
Client *nc; XWindowChanges wc;
wc.border_width = c->oldborder;
/* The server grab construct avoids race conditions. */ /* The server grab construct avoids race conditions. */
XGrabServer(dpy); XGrabServer(dpy);
XSetErrorHandler(xerrordummy); XSetErrorHandler(xerrordummy);
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
detach(c); detach(c);
detachstack(c); detachstack(c);
if(sel == c) { if(sel == c)
for(nc = stack; nc && !isvisible(nc); nc = nc->snext); focustopvisible();
focus(nc);
}
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
setclientstate(c, WithdrawnState); setclientstate(c, WithdrawnState);
free(c->tags); free(c->tags);
@ -402,25 +409,3 @@ unmanage(Client *c) {
XUngrabServer(dpy); XUngrabServer(dpy);
lt->arrange(); lt->arrange();
} }
void
zoom(Arg *arg) {
unsigned int n;
Client *c;
if(!sel)
return;
if(sel->isversatile || (lt->arrange == versatile)) {
togglemax(sel);
return;
}
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))
return;
detach(c);
attach(c);
focus(c);
lt->arrange();
}

View File

@ -1,25 +1,24 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
/* appearance */ /* appearance */
#define BARPOS BarTop /* BarBot, BarOff */
#define BORDERPX 1 #define BORDERPX 1
#define FONT "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*" #define FONT "-*-pixelcarnage monospace-*-r-*-*-14-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#333" #define NORMBORDERCOLOR "#333"
#define NORMBGCOLOR "#222" #define NORMBGCOLOR "#222"
#define NORMFGCOLOR "#ccc" #define NORMFGCOLOR "#ccc"
#define SELBORDERCOLOR "#69c" #define SELBORDERCOLOR "#8c8"
#define SELBGCOLOR "#555" #define SELBGCOLOR "#555"
#define SELFGCOLOR "#fff" #define SELFGCOLOR "#fff"
#define TOPBAR True /* False */
/* behavior */ /* tagging */
#define SNAP 40 /* pixel */
#define TAGS \ #define TAGS \
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL }; const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
#define RULES \ #define RULES \
static Rule rule[] = { \ static Rule rule[] = { \
/* class:instance:title regex tags regex isversatile */ \ /* class:instance:title regex tags regex isfloating */ \
{ "Firefox", "3", False }, \ { "Firefox", "3", False }, \
{ "Gimp", NULL, True }, \ { "Gimp", NULL, True }, \
{ "MPlayer", NULL, True }, \ { "MPlayer", NULL, True }, \
@ -31,69 +30,71 @@ static Rule rule[] = { \
static Layout layout[] = { \ static Layout layout[] = { \
/* symbol function */ \ /* symbol function */ \
{ "[]=", tile }, /* first entry is default */ \ { "[]=", tile }, /* first entry is default */ \
{ "><>", versatile }, \ { "><>", floating }, \
}; };
#define MASTER 600 /* per thousand */ #define MASTERWIDTH 600 /* master width per thousand */
#define NMASTER 1 /* clients in master area */ #define NMASTER 1 /* clients in master area */
#define SNAP 32 /* snap pixel */
/* key definitions */ /* key definitions */
#define MODKEY Mod1Mask #define MODKEY Mod1Mask
#define KEYS \ #define KEYS \
static Key key[] = { \ static Key key[] = { \
/* modifier key function argument */ \ /* modifier key function argument */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec uxterm -bg '#222' -fg '#eee' -cr '#eee' +sb -fn '"FONT"'" } }, \
{ MODKEY, XK_p, spawn, \ { MODKEY, XK_p, spawn, \
{ .cmd = "exe=\"$(lsx `echo $PATH | sed 's/:/ /g'` | sort -u " \ "exe=`dmenu_path | dmenu -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"'" \
" | dmenu -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' " \ " -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'` && exec $exe" }, \
"-sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"')\" && exec $exe" } }, \ { MODKEY|ShiftMask, XK_Return, spawn, \
{ MODKEY, XK_j, focusnext, { 0 } }, \ "exec urxvtcd -tr -bg '#222' -fg '#eee' -cr '#eee' +sb -fn '"FONT"'" }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \ { MODKEY, XK_space, setlayout, NULL }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \ { MODKEY, XK_b, togglebar, NULL }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \ { MODKEY, XK_h, incmasterw, "-32" }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \ { MODKEY, XK_l, incmasterw, "32" }, \
{ MODKEY, XK_i, incnmaster, { .i = 1 } }, \ { MODKEY|ShiftMask, XK_j, incnmaster, "1" }, \
{ MODKEY, XK_d, incnmaster, { .i = -1 } }, \ { MODKEY|ShiftMask, XK_k, incnmaster, "-1" }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \ { MODKEY, XK_j, focusclient, "1" }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \ { MODKEY, XK_k, focusclient, "-1" }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \ { MODKEY, XK_m, togglemax, NULL }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \ { MODKEY, XK_Return, zoom, NULL }, \
{ MODKEY|ShiftMask, XK_4, tag, { .i = 3 } }, \ { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, \
{ MODKEY|ShiftMask, XK_5, tag, { .i = 4 } }, \ { MODKEY|ShiftMask, XK_c, killclient, NULL }, \
{ MODKEY|ShiftMask, XK_6, tag, { .i = 5 } }, \ { MODKEY, XK_0, view, NULL }, \
{ MODKEY|ShiftMask, XK_7, tag, { .i = 6 } }, \ { MODKEY, XK_1, view, "0" }, \
{ MODKEY|ShiftMask, XK_8, tag, { .i = 7 } }, \ { MODKEY, XK_2, view, "1" }, \
{ MODKEY|ShiftMask, XK_9, tag, { .i = 8 } }, \ { MODKEY, XK_3, view, "2" }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \ { MODKEY, XK_4, view, "3" }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \ { MODKEY, XK_5, view, "4" }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \ { MODKEY, XK_6, view, "5" }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \ { MODKEY, XK_7, view, "6" }, \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \ { MODKEY, XK_8, view, "7" }, \
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, { .i = 5 } }, \ { MODKEY, XK_9, view, "8" }, \
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, { .i = 6 } }, \ { MODKEY|ControlMask, XK_1, toggleview, "0" }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \ { MODKEY|ControlMask, XK_2, toggleview, "1" }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \ { MODKEY|ControlMask, XK_3, toggleview, "2" }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \ { MODKEY|ControlMask, XK_4, toggleview, "3" }, \
{ MODKEY, XK_space, setlayout, { .i = -1 } }, \ { MODKEY|ControlMask, XK_5, toggleview, "4" }, \
{ MODKEY|ShiftMask, XK_space, toggleversatile,{ 0 } }, \ { MODKEY|ControlMask, XK_6, toggleview, "5" }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \ { MODKEY|ControlMask, XK_7, toggleview, "6" }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \ { MODKEY|ControlMask, XK_8, toggleview, "7" }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \ { MODKEY|ControlMask, XK_9, toggleview, "8" }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \ { MODKEY|ShiftMask, XK_0, tag, NULL }, \
{ MODKEY, XK_4, view, { .i = 3 } }, \ { MODKEY|ShiftMask, XK_1, tag, "0" }, \
{ MODKEY, XK_5, view, { .i = 4 } }, \ { MODKEY|ShiftMask, XK_2, tag, "1" }, \
{ MODKEY, XK_6, view, { .i = 5 } }, \ { MODKEY|ShiftMask, XK_3, tag, "2" }, \
{ MODKEY, XK_7, view, { .i = 6 } }, \ { MODKEY|ShiftMask, XK_4, tag, "3" }, \
{ MODKEY, XK_8, view, { .i = 7 } }, \ { MODKEY|ShiftMask, XK_5, tag, "4" }, \
{ MODKEY, XK_9, view, { .i = 8 } }, \ { MODKEY|ShiftMask, XK_6, tag, "5" }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \ { MODKEY|ShiftMask, XK_7, tag, "6" }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \ { MODKEY|ShiftMask, XK_8, tag, "7" }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \ { MODKEY|ShiftMask, XK_9, tag, "8" }, \
{ MODKEY|ControlMask, XK_4, toggleview, { .i = 3 } }, \ { MODKEY|ControlMask|ShiftMask, XK_1, toggletag, "0" }, \
{ MODKEY|ControlMask, XK_5, toggleview, { .i = 4 } }, \ { MODKEY|ControlMask|ShiftMask, XK_2, toggletag, "1" }, \
{ MODKEY|ControlMask, XK_6, toggleview, { .i = 5 } }, \ { MODKEY|ControlMask|ShiftMask, XK_3, toggletag, "2" }, \
{ MODKEY|ControlMask, XK_7, toggleview, { .i = 6 } }, \ { MODKEY|ControlMask|ShiftMask, XK_4, toggletag, "3" }, \
{ MODKEY|ControlMask, XK_8, toggleview, { .i = 7 } }, \ { MODKEY|ControlMask|ShiftMask, XK_5, toggletag, "4" }, \
{ MODKEY|ControlMask, XK_9, toggleview, { .i = 8 } }, \ { MODKEY|ControlMask|ShiftMask, XK_6, toggletag, "5" }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \ { MODKEY|ControlMask|ShiftMask, XK_7, toggletag, "6" }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, "7" }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, "8" }, \
{ MODKEY|ShiftMask, XK_q, quit, NULL }, \
}; };

View File

@ -1,8 +1,9 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
/* appearance */ /* appearance */
#define BARPOS BarTop /* BarBot, BarOff */
#define BORDERPX 1 #define BORDERPX 1
#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*" #define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#dddddd" #define NORMBORDERCOLOR "#dddddd"
@ -11,17 +12,15 @@
#define SELBORDERCOLOR "#ff0000" #define SELBORDERCOLOR "#ff0000"
#define SELBGCOLOR "#006699" #define SELBGCOLOR "#006699"
#define SELFGCOLOR "#ffffff" #define SELFGCOLOR "#ffffff"
#define TOPBAR True /* False */
/* behavior */ /* tagging */
#define SNAP 20 /* pixel */
#define TAGS \ #define TAGS \
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL }; const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
/* Query class:instance:title for regex matching info with following command: /* Query class:instance:title for regex matching info with following command:
* xprop | awk -F '"' '/^WM_CLASS/ { printf("%s:%s:",$4,$2) }; /^WM_NAME/ { printf("%s\n",$2) }' */ * xprop | awk -F '"' '/^WM_CLASS/ { printf("%s:%s:",$4,$2) }; /^WM_NAME/ { printf("%s\n",$2) }' */
#define RULES \ #define RULES \
static Rule rule[] = { \ static Rule rule[] = { \
/* class:instance:title regex tags regex isversatile */ \ /* class:instance:title regex tags regex isfloating */ \
{ "Gimp", NULL, True }, \ { "Gimp", NULL, True }, \
{ "MPlayer", NULL, True }, \ { "MPlayer", NULL, True }, \
{ "Acroread", NULL, True }, \ { "Acroread", NULL, True }, \
@ -32,64 +31,68 @@ static Rule rule[] = { \
static Layout layout[] = { \ static Layout layout[] = { \
/* symbol function */ \ /* symbol function */ \
{ "[]=", tile }, /* first entry is default */ \ { "[]=", tile }, /* first entry is default */ \
{ "><>", versatile }, \ { "><>", floating }, \
}; };
#define MASTER 600 /* per thousand */ #define MASTERWIDTH 600 /* master width per thousand */
#define NMASTER 1 /* clients in master area */ #define NMASTER 1 /* clients in master area */
#define SNAP 32 /* snap pixel */
/* key definitions */ /* key definitions */
#define MODKEY Mod1Mask #define MODKEY Mod1Mask
#define KEYS \ #define KEYS \
static Key key[] = { \ static Key key[] = { \
/* modifier key function argument */ \ /* modifier key function argument */ \
{ MODKEY|ShiftMask, XK_Return, spawn, { .cmd = "exec xterm" } }, \ { MODKEY|ShiftMask, XK_Return, spawn, "exec xterm" }, \
{ MODKEY, XK_Tab, focusnext, { 0 } }, \ { MODKEY, XK_p, spawn, "exe=`dmenu_path | dmenu` && exec $exe" }, \
{ MODKEY|ShiftMask, XK_Tab, focusprev, { 0 } }, \ { MODKEY, XK_space, setlayout, NULL }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \ { MODKEY, XK_b, togglebar, NULL }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \ { MODKEY, XK_h, incmasterw, "-32" }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \ { MODKEY, XK_l, incmasterw, "32" }, \
{ MODKEY, XK_i, incnmaster, { .i = 1 } }, \ { MODKEY|ShiftMask, XK_j, incnmaster, "1" }, \
{ MODKEY, XK_d, incnmaster, { .i = -1 } }, \ { MODKEY|ShiftMask, XK_k, incnmaster, "-1" }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \ { MODKEY, XK_j, focusclient, "1" }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \ { MODKEY, XK_k, focusclient, "-1" }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \ { MODKEY, XK_m, togglemax, NULL }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \ { MODKEY, XK_Return, zoom, NULL }, \
{ MODKEY|ShiftMask, XK_4, tag, { .i = 3 } }, \ { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, \
{ MODKEY|ShiftMask, XK_5, tag, { .i = 4 } }, \ { MODKEY|ShiftMask, XK_c, killclient, NULL }, \
{ MODKEY|ShiftMask, XK_6, tag, { .i = 5 } }, \ { MODKEY, XK_0, view, NULL }, \
{ MODKEY|ShiftMask, XK_7, tag, { .i = 6 } }, \ { MODKEY, XK_1, view, "0" }, \
{ MODKEY|ShiftMask, XK_8, tag, { .i = 7 } }, \ { MODKEY, XK_2, view, "1" }, \
{ MODKEY|ShiftMask, XK_9, tag, { .i = 8 } }, \ { MODKEY, XK_3, view, "2" }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \ { MODKEY, XK_4, view, "3" }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \ { MODKEY, XK_5, view, "4" }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \ { MODKEY, XK_6, view, "5" }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \ { MODKEY, XK_7, view, "6" }, \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \ { MODKEY, XK_8, view, "7" }, \
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, { .i = 5 } }, \ { MODKEY, XK_9, view, "8" }, \
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, { .i = 6 } }, \ { MODKEY|ControlMask, XK_1, toggleview, "0" }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \ { MODKEY|ControlMask, XK_2, toggleview, "1" }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \ { MODKEY|ControlMask, XK_3, toggleview, "2" }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \ { MODKEY|ControlMask, XK_4, toggleview, "3" }, \
{ MODKEY, XK_space, setlayout, { .i = -1 } }, \ { MODKEY|ControlMask, XK_5, toggleview, "4" }, \
{ MODKEY|ShiftMask, XK_space, toggleversatile,{ 0 } }, \ { MODKEY|ControlMask, XK_6, toggleview, "5" }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \ { MODKEY|ControlMask, XK_7, toggleview, "6" }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \ { MODKEY|ControlMask, XK_8, toggleview, "7" }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \ { MODKEY|ControlMask, XK_9, toggleview, "8" }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \ { MODKEY|ShiftMask, XK_0, tag, NULL }, \
{ MODKEY, XK_4, view, { .i = 3 } }, \ { MODKEY|ShiftMask, XK_1, tag, "0" }, \
{ MODKEY, XK_5, view, { .i = 4 } }, \ { MODKEY|ShiftMask, XK_2, tag, "1" }, \
{ MODKEY, XK_6, view, { .i = 5 } }, \ { MODKEY|ShiftMask, XK_3, tag, "2" }, \
{ MODKEY, XK_7, view, { .i = 6 } }, \ { MODKEY|ShiftMask, XK_4, tag, "3" }, \
{ MODKEY, XK_8, view, { .i = 7 } }, \ { MODKEY|ShiftMask, XK_5, tag, "4" }, \
{ MODKEY, XK_9, view, { .i = 8 } }, \ { MODKEY|ShiftMask, XK_6, tag, "5" }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \ { MODKEY|ShiftMask, XK_7, tag, "6" }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \ { MODKEY|ShiftMask, XK_8, tag, "7" }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \ { MODKEY|ShiftMask, XK_9, tag, "8" }, \
{ MODKEY|ControlMask, XK_4, toggleview, { .i = 3 } }, \ { MODKEY|ControlMask|ShiftMask, XK_1, toggletag, "0" }, \
{ MODKEY|ControlMask, XK_5, toggleview, { .i = 4 } }, \ { MODKEY|ControlMask|ShiftMask, XK_2, toggletag, "1" }, \
{ MODKEY|ControlMask, XK_6, toggleview, { .i = 5 } }, \ { MODKEY|ControlMask|ShiftMask, XK_3, toggletag, "2" }, \
{ MODKEY|ControlMask, XK_7, toggleview, { .i = 6 } }, \ { MODKEY|ControlMask|ShiftMask, XK_4, toggletag, "3" }, \
{ MODKEY|ControlMask, XK_8, toggleview, { .i = 7 } }, \ { MODKEY|ControlMask|ShiftMask, XK_5, toggletag, "4" }, \
{ MODKEY|ControlMask, XK_9, toggleview, { .i = 8 } }, \ { MODKEY|ControlMask|ShiftMask, XK_6, toggletag, "5" }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \ { MODKEY|ControlMask|ShiftMask, XK_7, toggletag, "6" }, \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, "7" }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, "8" }, \
{ MODKEY|ShiftMask, XK_q, quit, NULL }, \
}; };

View File

@ -1,5 +1,5 @@
# dwm version # dwm version
VERSION = 3.6.1 VERSION = 4.1
# Customize below to fit your system # Customize below to fit your system
@ -16,7 +16,7 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# flags # flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS} LDFLAGS = -s ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" #CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS} #LDFLAGS = -g ${LIBS}

25
draw.c
View File

@ -1,6 +1,6 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <string.h> #include <string.h>
@ -79,7 +79,12 @@ drawstatus(void) {
drawtext(stext, dc.norm); drawtext(stext, dc.norm);
if((dc.w = dc.x - x) > bh) { if((dc.w = dc.x - x) > bh) {
dc.x = x; dc.x = x;
drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm); if(sel) {
drawtext(sel->name, dc.sel);
drawsquare(sel->ismax, sel->isfloating, dc.sel);
}
else
drawtext(NULL, dc.norm);
} }
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0); XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, sw, bh, 0, 0);
XSync(dpy, False); XSync(dpy, False);
@ -90,7 +95,6 @@ drawtext(const char *text, unsigned long col[ColLast]) {
int x, y, w, h; int x, y, w, h;
static char buf[256]; static char buf[256];
unsigned int len, olen; unsigned int len, olen;
XGCValues gcv;
XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XSetForeground(dpy, dc.gc, col[ColBG]); XSetForeground(dpy, dc.gc, col[ColBG]);
@ -119,16 +123,11 @@ drawtext(const char *text, unsigned long col[ColLast]) {
} }
if(w > dc.w) if(w > dc.w)
return; /* too long */ return; /* too long */
gcv.foreground = col[ColFG]; XSetForeground(dpy, dc.gc, col[ColFG]);
if(dc.font.set) { if(dc.font.set)
XChangeGC(dpy, dc.gc, GCForeground, &gcv);
XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len); XmbDrawString(dpy, dc.drawable, dc.font.set, dc.gc, x, y, buf, len);
} else
else {
gcv.font = dc.font.xfont->fid;
XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len); XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
}
} }
unsigned int unsigned int

114
dwm.1
View File

@ -1,29 +1,31 @@
.TH DWM 1 dwm-VERSION .TH DWM 1 dwm\-VERSION
.SH NAME .SH NAME
dwm \- dynamic window manager dwm \- dynamic window manager
.SH SYNOPSIS .SH SYNOPSIS
.B dwm .B dwm
.RB [ \-v ] .RB [ \-v ]
.SH DESCRIPTION .SH DESCRIPTION
dwm is a dynamic window manager for X. It manages windows in tiling and dwm is a dynamic window manager for X. It manages windows in tiled and
versatile layouts. Either layout can be applied dynamically, optimizing the floating layouts. Either layout can be applied dynamically, optimizing the
environment for the application in use and the task performed. environment for the application in use and the task performed.
.P .P
In tiling layout windows are managed in a master and stacking area. The master In tiled layout windows are managed in a master and stacking area. The master
area contains the windows which currently need most attention, whereas the area contains the windows which currently need most attention, whereas the
stacking area contains all other windows. In versatile layout windows can be stacking area contains all other windows. In floating layout windows can be
resized and moved freely. Dialog windows are always managed versatile, resized and moved freely. Dialog windows are always managed floating,
regardless of the layout applied. regardless of the layout applied.
.P .P
Windows are grouped by tags. Each window can be tagged with one or multiple Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags. tags. Selecting certain tags displays all windows with these tags.
.P .P
dwm contains a small status bar which displays all available tags, the layout, dwm contains a small status bar which displays all available tags, the layout,
the title of the focused window, and the text read from standard input. The the title of the focused window, and the text read from standard input. A
selected tags are indicated with a different color. The tags of the focused floating window is indicated with an empty square and a maximized
window are indicated with a filled square in the top left corner. The tags floating window is indicated with a filled square before the windows
which are applied to one or more windows are indicated with an empty square in title. The selected tags are indicated with a different color. The tags of
the top left corner. the focused window are indicated with a filled square in the top left
corner. The tags which are applied to one or more windows are indicated
with an empty square in the top left corner.
.P .P
dwm draws a small border around windows to indicate the focus state. dwm draws a small border around windows to indicate the focus state.
.SH OPTIONS .SH OPTIONS
@ -38,96 +40,96 @@ is read and displayed in the status text area.
.TP .TP
.B Button1 .B Button1
click on a tag label to display all windows with that tag, click on the layout click on a tag label to display all windows with that tag, click on the layout
label toggles between tiling and versatile layout. label toggles between tiled and floating layout.
.TP .TP
.B Button3 .B Button3
click on a tag label adds/removes all windows with that tag to/from the view. click on a tag label adds/removes all windows with that tag to/from the view.
.TP .TP
.B Button4 .B Mod1\-Button1
click on the layout label increases the number of windows in the master area (tiling layout only).
.TP
.B Button5
click on the layout label decreases the number of windows in the master area (tiling layout only).
.TP
.B Mod1-Button1
click on a tag label applies that tag to the focused window. click on a tag label applies that tag to the focused window.
.TP .TP
.B Mod1-Button3 .B Mod1\-Button3
click on a tag label adds/removes that tag to/from the focused window. click on a tag label adds/removes that tag to/from the focused window.
.SS Keyboard commands .SS Keyboard commands
.TP .TP
.B Mod1-Shift-Return .B Mod1\-Shift\-Return
Start Start
.BR xterm (1). .BR xterm.
.TP .TP
.B Mod1-Tab .B Mod1\-Return
Zooms/cycles current window to/from master area (tiled layout only).
.TP
.B Mod1\-b
Shows/hides the status bar.
.TP
.B Mod1\-j
Focus next window. Focus next window.
.TP .TP
.B Mod1-Shift-Tab .B Mod1\-k
Focus previous window. Focus previous window.
.TP .TP
.B Mod1-Return .B Mod1\-Shift\-j
Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (versatile layout). Increase the number of windows in the master area (tiled layout only).
.TP .TP
.B Mod1-g .B Mod1\-Shift\-k
Grow master area (tiling layout only). Decrease the number of windows in the master area (tiled layout only).
.TP .TP
.B Mod1-s .B Mod1\-l
Shrink master area (tiling layout only). Increase master area width (tiled layout only).
.TP .TP
.B Mod1-i .B Mod1\-h
Increase the number of windows in the master area (tiling layout only). Decrease master area width (tiled layout only).
.TP .TP
.B Mod1-d .B Mod1\-m
Decrease the number of windows in the master area (tiling layout only). Toggles maximization of current window (floating layout only).
.TP .TP
.B Mod1-Shift-[1..n] .B Mod1\-Shift\-[1..n]
Apply Apply
.RB nth .RB nth
tag to current window. tag to current window.
.TP .TP
.B Mod1-Shift-0 .B Mod1\-Shift\-0
Apply all tags to current window. Apply all tags to current window.
.TP .TP
.B Mod1-Control-Shift-[1..n] .B Mod1\-Control\-Shift\-[1..n]
Add/remove Add/remove
.B nth .B nth
tag to/from current window. tag to/from current window.
.TP .TP
.B Mod1-Shift-c .B Mod1\-Shift\-c
Close focused window. Close focused window.
.TP .TP
.B Mod1-space .B Mod1\-space
Toggle between tiling and versatile layout (affects all windows). Toggle between tiled and floating layout (affects all windows).
.TP .TP
.B Mod1-Shift-space .B Mod1\-Shift\-space
Toggle focused window between versatile and non-versatile state (tiling layout only). Toggle focused window between tiled and floating state (tiled layout only).
.TP .TP
.B Mod1-[1..n] .B Mod1\-[1..n]
View all windows with View all windows with
.BR nth .BR nth
tag. tag.
.TP .TP
.B Mod1-0 .B Mod1\-0
View all windows with any tag. View all windows with any tag.
.TP .TP
.B Mod1-Control-[1..n] .B Mod1\-Control\-[1..n]
Add/remove all windows with Add/remove all windows with
.BR nth .BR nth
tag to/from the view. tag to/from the view.
.TP .TP
.B Mod1-Shift-q .B Mod1\-Shift\-q
Quit dwm. Quit dwm.
.SS Mouse commands .SS Mouse commands
.TP .TP
.B Mod1-Button1 .B Mod1\-Button1
Move current window while dragging (versatile layout only). Move current window while dragging (floating layout only).
.TP .TP
.B Mod1-Button2 .B Mod1\-Button2
Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (versatile layout). Zooms/cycles current window to/from master area (tiled layout only).
.TP .TP
.B Mod1-Button3 .B Mod1\-Button3
Resize current window while dragging (versatile layout only). Resize current window while dragging (floating layout only).
.SH CUSTOMIZATION .SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple. code. This keeps it fast, secure and simple.
@ -147,3 +149,11 @@ you can use JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or you
can set the following environment variable (to use the older Motif can set the following environment variable (to use the older Motif
backend instead): backend instead):
.BR AWT_TOOLKIT=MToolkit . .BR AWT_TOOLKIT=MToolkit .
.P
Recent GTK 2.10.9+ versions contain a broken
.BR Save\-As
file dialog implementation,
which requests to reconfigure its window size in an endless loop. However, its
window is still respondable during this state, so you can simply ignore the flicker
until a new GTK version appears, which will fix this bug, approximately
GTK 2.10.12+ versions.

160
dwm.h
View File

@ -1,4 +1,5 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
* See LICENSE file for license details. * See LICENSE file for license details.
* *
* dynamic window manager is designed like any other X client as well. It is * dynamic window manager is designed like any other X client as well. It is
@ -36,32 +37,11 @@
/* mask shorthands, used in event.c and client.c */ /* mask shorthands, used in event.c and client.c */
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ enum { BarTop, BarBot, BarOff }; /* bar position */
enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
typedef union { enum { WMProtocols, WMDelete, WMState, WMLast }; /* default atoms */
const char *cmd;
int i;
} Arg; /* argument type */
typedef struct {
int ascent;
int descent;
int height;
XFontSet set;
XFontStruct *xfont;
} Fnt;
typedef struct {
int x, y, w, h;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
Drawable drawable;
Fnt font;
GC gc;
} DC; /* draw context */
typedef struct Client Client; typedef struct Client Client;
struct Client { struct Client {
@ -69,10 +49,10 @@ struct Client {
int x, y, w, h; int x, y, w, h;
int rx, ry, rw, rh; /* revert geometry */ int rx, ry, rw, rh; /* revert geometry */
int basew, baseh, incw, inch, maxw, maxh, minw, minh; int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int minax, minay, maxax, maxay; int minax, maxax, minay, maxay;
long flags; long flags;
unsigned int border; unsigned int border, oldborder;
Bool isbanned, isfixed, ismax, isversatile; Bool isbanned, isfixed, ismax, isfloating;
Bool *tags; Bool *tags;
Client *next; Client *next;
Client *prev; Client *prev;
@ -80,77 +60,93 @@ struct Client {
Window win; Window win;
}; };
typedef struct {
int x, y, w, h;
unsigned long norm[ColLast];
unsigned long sel[ColLast];
Drawable drawable;
GC gc;
struct {
int ascent;
int descent;
int height;
XFontSet set;
XFontStruct *xfont;
} font;
} DC; /* draw context */
typedef struct { typedef struct {
const char *symbol; const char *symbol;
void (*arrange)(void); void (*arrange)(void);
} Layout; } Layout;
extern const char *tags[]; /* all tags */ extern const char *tags[]; /* all tags */
extern char stext[256]; /* status text */ char stext[256]; /* status text */
extern int screen, sx, sy, sw, sh; /* screen geometry */ int screen, sx, sy, sw, sh; /* screen geometry */
extern int wax, way, wah, waw; /* windowarea geometry */ int wax, way, wah, waw; /* windowarea geometry */
extern unsigned int bh, blw; /* bar height, bar layout label width */ unsigned int bh, blw, bpos; /* bar height, bar layout label width, bar position */
extern unsigned int master, nmaster; /* master percent, number of master clients */ unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */
extern unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */ void (*handler[LASTEvent])(XEvent *); /* event handler */
extern void (*handler[LASTEvent])(XEvent *); /* event handler */ Atom wmatom[WMLast], netatom[NetLast];
extern Atom wmatom[WMLast], netatom[NetLast]; Bool selscreen, *seltag; /* seltag is array of Bool */
extern Bool selscreen, *seltag; /* seltag is array of Bool */ Client *clients, *sel, *stack; /* global client list and stack */
extern Client *clients, *sel, *stack; /* global client list and stack */ Cursor cursor[CurLast];
extern Cursor cursor[CurLast]; DC dc; /* global draw context */
extern DC dc; /* global draw context */ Display *dpy;
extern Display *dpy; Layout *lt;
extern Layout *lt; Window root, barwin;
extern Window root, barwin;
/* client.c */ /* client.c */
extern void configure(Client *c); /* send synthetic configure event */ void attach(Client *c); /* attaches c to global client list */
extern void focus(Client *c); /* focus c, c may be NULL */ void configure(Client *c); /* send synthetic configure event */
extern void killclient(Arg *arg); /* kill c nicely */ void detach(Client *c); /* detaches c from global client list */
extern void manage(Window w, XWindowAttributes *wa); /* manage new client */ void focus(Client *c); /* focus c, c may be NULL */
extern void resize(Client *c, int x, int y, void focustopvisible(void); /* focus top visible window on stack */
void killclient(const char *arg); /* kill sel nicely */
void manage(Window w, XWindowAttributes *wa); /* manage new client */
void resize(Client *c, int x, int y,
int w, int h, Bool sizehints); /* resize with given coordinates c*/ int w, int h, Bool sizehints); /* resize with given coordinates c*/
extern void toggleversatile(Arg *arg); /* toggles focused client between versatile/and non-versatile state */ void togglefloating(const char *arg); /* toggles sel between floating/tiled state */
extern void updatesizehints(Client *c); /* update the size hint variables of c */ void updatesizehints(Client *c); /* update the size hint variables of c */
extern void updatetitle(Client *c); /* update the name of c */ void updatetitle(Client *c); /* update the name of c */
extern void unmanage(Client *c); /* destroy c */ void unmanage(Client *c); /* destroy c */
extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */
/* draw.c */ /* draw.c */
extern void drawstatus(void); /* draw the bar */ void drawstatus(void); /* draw the bar */
extern void drawtext(const char *text, void drawtext(const char *text, unsigned long col[ColLast]); /* draw text */
unsigned long col[ColLast]); /* draw text */ unsigned int textw(const char *text); /* return the width of text in px*/
extern unsigned int textw(const char *text); /* return the width of text in px*/
/* event.c */ /* event.c */
extern void grabkeys(void); /* grab all keys defined in config.h */ void grabkeys(void); /* grab all keys defined in config.h */
/* layout.c */ /* layout.c */
extern void focusnext(Arg *arg); /* focuses next visible client, arg is ignored */ void floating(void); /* arranges all windows floating */
extern void focusprev(Arg *arg); /* focuses previous visible client, arg is ignored */ void focusclient(const char *arg); /* focuses next(1)/previous(-1) visible client */
extern void incnmaster(Arg *arg); /* increments nmaster with arg's index value */ void incmasterw(const char *arg); /* increments the master width with arg's index value */
extern void initlayouts(void); /* initialize layout array */ void incnmaster(const char *arg); /* increments nmaster with arg's index value */
extern Client *nexttiled(Client *c); /* returns tiled successor of c */ void initlayouts(void); /* initialize layout array */
extern void resizemaster(Arg *arg); /* resizes the master percent with arg's index value */ Client *nexttiled(Client *c); /* returns tiled successor of c */
extern void restack(void); /* restores z layers of all clients */ void restack(void); /* restores z layers of all clients */
extern void setlayout(Arg *arg); /* sets layout, -1 toggles */ void setlayout(const char *arg); /* sets layout, -1 toggles */
extern void versatile(void); /* arranges all windows versatile */ void togglebar(const char *arg); /* shows/hides the bar */
void togglemax(const char *arg); /* toggles maximization of floating client */
void zoom(const char *arg); /* zooms the focused client to master area, arg is ignored */
/* main.c */ /* main.c */
extern void quit(Arg *arg); /* quit dwm nicely */ void updatebarpos(void); /* updates the bar position */
extern void sendevent(Window w, Atom a, long value); /* send synthetic event to w */ void quit(const char *arg); /* quit dwm nicely */
extern int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */ int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */
/* tag.c */ /* tag.c */
extern void compileregs(void); /* initialize regexps of rules defined in config.h */ void compileregs(void); /* initialize regexps of rules defined in config.h */
extern Bool isvisible(Client *c); /* returns True if client is visible */ Bool isvisible(Client *c); /* returns True if client is visible */
extern void settags(Client *c, Client *trans); /* sets tags of c */ void settags(Client *c, Client *trans); /* sets tags of c */
extern void tag(Arg *arg); /* tags c with arg's index */ void tag(const char *arg); /* tags sel with arg's index */
extern void toggletag(Arg *arg); /* toggles c tags with arg's index */ void toggletag(const char *arg); /* toggles sel tags with arg's index */
extern void toggleview(Arg *arg); /* toggles the tag with arg's index (in)visible */ void toggleview(const char *arg); /* toggles the tag with arg's index (in)visible */
extern void view(Arg *arg); /* views the tag with arg's index */ void view(const char *arg); /* views the tag with arg's index */
/* util.c */ /* util.c */
extern void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */ void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */
extern void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */ void eprint(const char *errstr, ...); /* prints errstr and exits with 1 */
extern void spawn(Arg *arg); /* forks a new subprocess with arg's cmd */ void spawn(const char *arg); /* forks a new subprocess with arg's cmd */

74
event.c
View File

@ -1,7 +1,8 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <X11/keysym.h> #include <X11/keysym.h>
#include <X11/Xatom.h> #include <X11/Xatom.h>
@ -11,8 +12,8 @@
typedef struct { typedef struct {
unsigned long mod; unsigned long mod;
KeySym keysym; KeySym keysym;
void (*func)(Arg *arg); void (*func)(const char *arg);
Arg arg; const char *arg;
} Key; } Key;
KEYS KEYS
@ -112,27 +113,29 @@ resizemouse(Client *c) {
static void static void
buttonpress(XEvent *e) { buttonpress(XEvent *e) {
int x; static char buf[32];
Arg a; unsigned int i, x;
Client *c; Client *c;
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
buf[0] = 0;
if(barwin == ev->window) { if(barwin == ev->window) {
x = 0; x = 0;
for(a.i = 0; a.i < ntags; a.i++) { for(i = 0; i < ntags; i++) {
x += textw(tags[a.i]); x += textw(tags[i]);
if(ev->x < x) { if(ev->x < x) {
snprintf(buf, sizeof buf, "%d", i);
if(ev->button == Button1) { if(ev->button == Button1) {
if(ev->state & MODKEY) if(ev->state & MODKEY)
tag(&a); tag(buf);
else else
view(&a); view(buf);
} }
else if(ev->button == Button3) { else if(ev->button == Button3) {
if(ev->state & MODKEY) if(ev->state & MODKEY)
toggletag(&a); toggletag(buf);
else else
toggleview(&a); toggleview(buf);
} }
return; return;
} }
@ -140,16 +143,7 @@ buttonpress(XEvent *e) {
if(ev->x < x + blw) if(ev->x < x + blw)
switch(ev->button) { switch(ev->button) {
case Button1: case Button1:
a.i = -1; setlayout(NULL);
setlayout(&a);
break;
case Button4:
a.i = 1;
incnmaster(&a);
break;
case Button5:
a.i = -1;
incnmaster(&a);
break; break;
} }
} }
@ -157,14 +151,14 @@ buttonpress(XEvent *e) {
focus(c); focus(c);
if(CLEANMASK(ev->state) != MODKEY) if(CLEANMASK(ev->state) != MODKEY)
return; return;
if(ev->button == Button1 && (lt->arrange == versatile || c->isversatile)) { if(ev->button == Button1 && (lt->arrange == floating || c->isfloating)) {
restack(); restack();
movemouse(c); movemouse(c);
} }
else if(ev->button == Button2) else if(ev->button == Button2)
zoom(NULL); zoom(NULL);
else if(ev->button == Button3 else if(ev->button == Button3
&& (lt->arrange == versatile || c->isversatile) && !c->isfixed) && (lt->arrange == floating || c->isfloating) && !c->isfixed)
{ {
restack(); restack();
resizemouse(c); resizemouse(c);
@ -182,7 +176,7 @@ configurerequest(XEvent *e) {
c->ismax = False; c->ismax = False;
if(ev->value_mask & CWBorderWidth) if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width; c->border = ev->border_width;
if(c->isfixed || c->isversatile || (lt->arrange == versatile)) { if(c->isfixed || c->isfloating || (lt->arrange == floating)) {
if(ev->value_mask & CWX) if(ev->value_mask & CWX)
c->x = ev->x; c->x = ev->x;
if(ev->value_mask & CWY) if(ev->value_mask & CWY)
@ -191,6 +185,10 @@ configurerequest(XEvent *e) {
c->w = ev->width; c->w = ev->width;
if(ev->value_mask & CWHeight) if(ev->value_mask & CWHeight)
c->h = ev->height; c->h = ev->height;
if((c->x + c->w) > sw && c->isfloating)
c->x = sw / 2 - c->w / 2; /* center in x direction */
if((c->y + c->h) > sh && c->isfloating)
c->y = sh / 2 - c->h / 2; /* center in y direction */
if((ev->value_mask & (CWX | CWY)) if((ev->value_mask & (CWX | CWY))
&& !(ev->value_mask & (CWWidth | CWHeight))) && !(ev->value_mask & (CWWidth | CWHeight)))
configure(c); configure(c);
@ -213,6 +211,22 @@ configurerequest(XEvent *e) {
XSync(dpy, False); XSync(dpy, False);
} }
static void
configurenotify(XEvent *e) {
XConfigureEvent *ev = &e->xconfigure;
if (ev->window == root && (ev->width != sw || ev->height != sh)) {
sw = ev->width;
sh = ev->height;
wah = sh - bh;
waw = sw;
XFreePixmap(dpy, dc.drawable);
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
XResizeWindow(dpy, barwin, sw, bh);
lt->arrange();
}
}
static void static void
destroynotify(XEvent *e) { destroynotify(XEvent *e) {
Client *c; Client *c;
@ -233,8 +247,7 @@ enternotify(XEvent *e) {
focus(c); focus(c);
else if(ev->window == root) { else if(ev->window == root) {
selscreen = True; selscreen = True;
for(c = stack; c && !isvisible(c); c = c->snext); focustopvisible();
focus(c);
} }
} }
@ -261,7 +274,7 @@ keypress(XEvent *e) {
&& CLEANMASK(key[i].mod) == CLEANMASK(ev->state)) && CLEANMASK(key[i].mod) == CLEANMASK(ev->state))
{ {
if(key[i].func) if(key[i].func)
key[i].func(&key[i].arg); key[i].func(key[i].arg);
} }
} }
@ -310,7 +323,7 @@ propertynotify(XEvent *e) {
default: break; default: break;
case XA_WM_TRANSIENT_FOR: case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans); XGetTransientForHint(dpy, c->win, &trans);
if(!c->isversatile && (c->isversatile = (getclient(trans) != NULL))) if(!c->isfloating && (c->isfloating = (getclient(trans) != NULL)))
lt->arrange(); lt->arrange();
break; break;
case XA_WM_NORMAL_HINTS: case XA_WM_NORMAL_HINTS:
@ -339,6 +352,7 @@ unmapnotify(XEvent *e) {
void (*handler[LASTEvent]) (XEvent *) = { void (*handler[LASTEvent]) (XEvent *) = {
[ButtonPress] = buttonpress, [ButtonPress] = buttonpress,
[ConfigureRequest] = configurerequest, [ConfigureRequest] = configurerequest,
[ConfigureNotify] = configurenotify,
[DestroyNotify] = destroynotify, [DestroyNotify] = destroynotify,
[EnterNotify] = enternotify, [EnterNotify] = enternotify,
[LeaveNotify] = leavenotify, [LeaveNotify] = leavenotify,

206
layout.c
View File

@ -1,28 +1,30 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <stdlib.h>
unsigned int master = MASTER;
unsigned int nmaster = NMASTER;
unsigned int blw = 0; unsigned int blw = 0;
Layout *lt = NULL; Layout *lt = NULL;
/* static */ /* static */
static unsigned int nlayouts = 0; static unsigned int nlayouts = 0;
static unsigned int masterw = MASTERWIDTH;
static unsigned int nmaster = NMASTER;
static void static void
tile(void) { tile(void) {
unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th; unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, remainder;
Client *c; Client *c;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++; n++;
/* window geoms */ /* window geoms */
mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1); mh = (n > nmaster) ? wah / nmaster : wah / (n > 0 ? n : 1);
mw = (n > nmaster) ? (waw * master) / 1000 : waw; mw = (n > nmaster) ? (waw * masterw) / 1000 : waw;
th = (n > nmaster) ? wah / (n - nmaster) : 0; th = (n > nmaster) ? wah / (n - nmaster) : 0;
remainder = (n > nmaster) ? wah - th * (n - nmaster) : 0;
tw = waw - mw; tw = waw - mw;
for(i = 0, c = clients; c; c = c->next) for(i = 0, c = clients; c; c = c->next)
@ -30,25 +32,27 @@ tile(void) {
if(c->isbanned) if(c->isbanned)
XMoveWindow(dpy, c->win, c->x, c->y); XMoveWindow(dpy, c->win, c->x, c->y);
c->isbanned = False; c->isbanned = False;
if(c->isversatile) if(c->isfloating)
continue; continue;
c->ismax = False; c->ismax = False;
nx = wax; nx = wax;
ny = way; ny = way;
if(i < nmaster) { if(i < nmaster) {
ny += i * mh; ny += i * mh;
nw = mw - 2 * BORDERPX; nw = mw - 2 * c->border;
nh = mh - 2 * BORDERPX; nh = mh - 2 * c->border;
} }
else { /* tile window */ else { /* tile window */
nx += mw; nx += mw;
nw = tw - 2 * BORDERPX; nw = tw - 2 * c->border;
if(th > 2 * BORDERPX) { if(th > 2 * c->border) {
ny += (i - nmaster) * th; ny += (i - nmaster) * th;
nh = th - 2 * BORDERPX; nh = th - 2 * c->border;
if (i == n - 1)
nh += remainder;
} }
else /* fallback if th <= 2 * BORDERPX */ else /* fallback if th <= 2 * c->border */
nh = wah - 2 * BORDERPX; nh = wah - 2 * c->border;
} }
resize(c, nx, ny, nw, nh, False); resize(c, nx, ny, nw, nh, False);
i++; i++;
@ -57,10 +61,8 @@ tile(void) {
c->isbanned = True; c->isbanned = True;
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
} }
if(!sel || !isvisible(sel)) { if(!sel || !isvisible(sel))
for(c = stack; c && !isvisible(c); c = c->snext); focustopvisible();
focus(c);
}
restack(); restack();
} }
@ -69,30 +71,43 @@ LAYOUTS
/* extern */ /* extern */
void void
focusnext(Arg *arg) { floating(void) {
Client *c; Client *c;
if(!sel) for(c = clients; c; c = c->next) {
return; if(isvisible(c)) {
for(c = sel->next; c && !isvisible(c); c = c->next); if(c->isbanned)
if(!c) XMoveWindow(dpy, c->win, c->x, c->y);
for(c = clients; c && !isvisible(c); c = c->next); c->isbanned = False;
if(c) { resize(c, c->x, c->y, c->w, c->h, True);
focus(c); }
restack(); else {
c->isbanned = True;
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
}
} }
if(!sel || !isvisible(sel))
focustopvisible();
restack();
} }
void void
focusprev(Arg *arg) { focusclient(const char *arg) {
Client *c; Client *c;
if(!sel) if(!sel || !arg)
return; return;
for(c = sel->prev; c && !isvisible(c); c = c->prev); if(atoi(arg) < 0) {
if(!c) { for(c = sel->prev; c && !isvisible(c); c = c->prev);
for(c = clients; c && c->next; c = c->next); if(!c) {
for(; c && !isvisible(c); c = c->prev); for(c = clients; c && c->next; c = c->next);
for(; c && !isvisible(c); c = c->prev);
}
}
else {
for(c = sel->next; c && !isvisible(c); c = c->next);
if(!c)
for(c = clients; c && !isvisible(c); c = c->next);
} }
if(c) { if(c) {
focus(c); focus(c);
@ -101,11 +116,35 @@ focusprev(Arg *arg) {
} }
void void
incnmaster(Arg *arg) { incmasterw(const char *arg) {
if((lt->arrange != tile) || (nmaster + arg->i < 1) int i;
|| (wah / (nmaster + arg->i) <= 2 * BORDERPX)) if(lt->arrange != tile)
return; return;
nmaster += arg->i; if(!arg)
masterw = MASTERWIDTH;
else {
i = atoi(arg);
if(waw * (masterw + i) / 1000 >= waw - 2 * BORDERPX
|| waw * (masterw + i) / 1000 <= 2 * BORDERPX)
return;
masterw += i;
}
lt->arrange();
}
void
incnmaster(const char *arg) {
int i;
if(!arg)
nmaster = NMASTER;
else {
i = atoi(arg);
if((lt->arrange != tile) || (nmaster + i < 1)
|| (wah / (nmaster + i) <= 2 * BORDERPX))
return;
nmaster += i;
}
if(sel) if(sel)
lt->arrange(); lt->arrange();
else else
@ -127,25 +166,10 @@ initlayouts(void) {
Client * Client *
nexttiled(Client *c) { nexttiled(Client *c) {
for(; c && (c->isversatile || !isvisible(c)); c = c->next); for(; c && (c->isfloating || !isvisible(c)); c = c->next);
return c; return c;
} }
void
resizemaster(Arg *arg) {
if(lt->arrange != tile)
return;
if(arg->i == 0)
master = MASTER;
else {
if(waw * (master + arg->i) / 1000 >= waw - 2 * BORDERPX
|| waw * (master + arg->i) / 1000 <= 2 * BORDERPX)
return;
master += arg->i;
}
lt->arrange();
}
void void
restack(void) { restack(void) {
Client *c; Client *c;
@ -154,10 +178,10 @@ restack(void) {
drawstatus(); drawstatus();
if(!sel) if(!sel)
return; return;
if(sel->isversatile || lt->arrange == versatile) if(sel->isfloating || lt->arrange == floating)
XRaiseWindow(dpy, sel->win); XRaiseWindow(dpy, sel->win);
if(lt->arrange != versatile) { if(lt->arrange != floating) {
if(!sel->isversatile) if(!sel->isfloating)
XLowerWindow(dpy, sel->win); XLowerWindow(dpy, sel->win);
for(c = nexttiled(clients); c; c = nexttiled(c->next)) { for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
if(c == sel) if(c == sel)
@ -170,10 +194,10 @@ restack(void) {
} }
void void
setlayout(Arg *arg) { setlayout(const char *arg) {
unsigned int i; int i;
if(arg->i == -1) { if(!arg) {
for(i = 0; i < nlayouts && lt != &layout[i]; i++); for(i = 0; i < nlayouts && lt != &layout[i]; i++);
if(i == nlayouts - 1) if(i == nlayouts - 1)
lt = &layout[0]; lt = &layout[0];
@ -181,9 +205,10 @@ setlayout(Arg *arg) {
lt = &layout[++i]; lt = &layout[++i];
} }
else { else {
if(arg->i < 0 || arg->i >= nlayouts) i = atoi(arg);
if(i < 0 || i >= nlayouts)
return; return;
lt = &layout[arg->i]; lt = &layout[i];
} }
if(sel) if(sel)
lt->arrange(); lt->arrange();
@ -192,24 +217,45 @@ setlayout(Arg *arg) {
} }
void void
versatile(void) { togglebar(const char *arg) {
if(bpos == BarOff)
bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
else
bpos = BarOff;
updatebarpos();
lt->arrange();
}
void
togglemax(const char *arg) {
XEvent ev;
if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
return;
if((sel->ismax = !sel->ismax)) {
sel->rx = sel->x;
sel->ry = sel->y;
sel->rw = sel->w;
sel->rh = sel->h;
resize(sel, wax, way, waw - 2 * BORDERPX, wah - 2 * BORDERPX, True);
}
else
resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
drawstatus();
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
zoom(const char *arg) {
Client *c; Client *c;
for(c = clients; c; c = c->next) { if(!sel || lt->arrange != tile || sel->isfloating)
if(isvisible(c)) { return;
if(c->isbanned) if((c = sel) == nexttiled(clients))
XMoveWindow(dpy, c->win, c->x, c->y); if(!(c = nexttiled(c->next)))
c->isbanned = False; return;
resize(c, c->x, c->y, c->w, c->h, True); detach(c);
} attach(c);
else { focus(c);
c->isbanned = True; lt->arrange();
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
}
}
if(!sel || !isvisible(sel)) {
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
}
restack();
} }

76
main.c
View File

@ -1,7 +1,6 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <errno.h> #include <errno.h>
#include <locale.h> #include <locale.h>
@ -19,7 +18,7 @@
char stext[256]; char stext[256];
int screen, sx, sy, sw, sh, wax, way, waw, wah; int screen, sx, sy, sw, sh, wax, way, waw, wah;
unsigned int bh, ntags, numlockmask; unsigned int bh, bpos, ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast]; Atom wmatom[WMLast], netatom[NetLast];
Bool *seltag; Bool *seltag;
Bool selscreen = True; Bool selscreen = True;
@ -82,7 +81,7 @@ initfont(const char *fontstr) {
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def); dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
if(missing) { if(missing) {
while(n--) while(n--)
fprintf(stderr, "missing fontset: %s\n", missing[n]); fprintf(stderr, "dwm: missing fontset: %s\n", missing[n]);
XFreeStringList(missing); XFreeStringList(missing);
} }
if(dc.font.set) { if(dc.font.set) {
@ -164,9 +163,10 @@ setup(void) {
XFreeModifiermap(modmap); XFreeModifiermap(modmap);
/* select for events */ /* select for events */
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
| EnterWindowMask | LeaveWindowMask; | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
wa.cursor = cursor[CurNormal]; wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
XSelectInput(dpy, root, wa.event_mask);
grabkeys(); grabkeys();
compileregs(); compileregs();
for(ntags = 0; tags[ntags]; ntags++); for(ntags = 0; tags[ntags]; ntags++);
@ -190,21 +190,20 @@ setup(void) {
wa.override_redirect = 1; wa.override_redirect = 1;
wa.background_pixmap = ParentRelative; wa.background_pixmap = ParentRelative;
wa.event_mask = ButtonPressMask | ExposureMask; wa.event_mask = ButtonPressMask | ExposureMask;
barwin = XCreateWindow(dpy, root, sx, sy + (TOPBAR ? 0 : sh - bh), sw, bh, 0, barwin = XCreateWindow(dpy, root, sx, sy, sw, bh, 0,
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]); XDefineCursor(dpy, barwin, cursor[CurNormal]);
bpos = BARPOS;
updatebarpos();
XMapRaised(dpy, barwin); XMapRaised(dpy, barwin);
strcpy(stext, "dwm-"VERSION); strcpy(stext, "dwm-"VERSION);
/* windowarea */
wax = sx;
way = sy + (TOPBAR ? bh : 0);
wah = sh - bh;
waw = sw;
/* pixmap for everything */ /* pixmap for everything */
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen)); dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
dc.gc = XCreateGC(dpy, root, 0, 0); dc.gc = XCreateGC(dpy, root, 0, 0);
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
if(!dc.font.set)
XSetFont(dpy, dc.gc, dc.font.xfont->fid);
/* multihead support */ /* multihead support */
selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask); selscreen = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
} }
@ -222,22 +221,34 @@ xerrorstart(Display *dsply, XErrorEvent *ee) {
/* extern */ /* extern */
void void
sendevent(Window w, Atom a, long value) { quit(const char *arg) {
XEvent e; readin = running = False;
e.type = ClientMessage;
e.xclient.window = w;
e.xclient.message_type = a;
e.xclient.format = 32;
e.xclient.data.l[0] = value;
e.xclient.data.l[1] = CurrentTime;
XSendEvent(dpy, w, False, NoEventMask, &e);
XSync(dpy, False);
} }
void void
quit(Arg *arg) { updatebarpos(void) {
readin = running = False; XEvent ev;
wax = sx;
way = sy;
wah = sh;
waw = sw;
switch(bpos) {
default:
wah -= bh;
way += bh;
XMoveWindow(dpy, barwin, sx, sy);
break;
case BarBot:
wah -= bh;
XMoveWindow(dpy, barwin, sx, sy + wah);
break;
case BarOff:
XMoveWindow(dpy, barwin, sx, sy - bh);
break;
}
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
} }
/* There's no way to check accesses to destroyed windows, thus those cases are /* There's no way to check accesses to destroyed windows, thus those cases are
@ -268,7 +279,7 @@ main(int argc, char *argv[]) {
XEvent ev; XEvent ev;
if(argc == 2 && !strncmp("-v", argv[1], 3)) if(argc == 2 && !strncmp("-v", argv[1], 3))
eprint("dwm-"VERSION", (C)opyright MMVI-MMVII Anselm R. Garbe\n"); eprint("dwm-"VERSION", © 2004-2007 Anselm R. Garbe, Sander van Dijk\n");
else if(argc != 1) else if(argc != 1)
eprint("usage: dwm [-v]\n"); eprint("usage: dwm [-v]\n");
setlocale(LC_CTYPE, ""); setlocale(LC_CTYPE, "");
@ -325,12 +336,11 @@ main(int argc, char *argv[]) {
} }
drawstatus(); drawstatus();
} }
if(FD_ISSET(xfd, &rd)) while(XPending(dpy)) {
while(XPending(dpy)) { XNextEvent(dpy, &ev);
XNextEvent(dpy, &ev); if(handler[ev.type])
if(handler[ev.type]) (handler[ev.type])(&ev); /* call handler */
(handler[ev.type])(&ev); /* call handler */ }
}
} }
cleanup(); cleanup();
XCloseDisplay(dpy); XCloseDisplay(dpy);

58
tag.c
View File

@ -1,6 +1,6 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <regex.h> #include <regex.h>
#include <stdio.h> #include <stdio.h>
@ -12,7 +12,7 @@
typedef struct { typedef struct {
const char *prop; const char *prop;
const char *tags; const char *tags;
Bool isversatile; Bool isfloating;
} Rule; } Rule;
typedef struct { typedef struct {
@ -83,7 +83,7 @@ settags(Client *c, Client *trans) {
ch.res_name ? ch.res_name : "", c->name); ch.res_name ? ch.res_name : "", c->name);
for(i = 0; i < nrules; i++) for(i = 0; i < nrules; i++)
if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) { if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
c->isversatile = rule[i].isversatile; c->isfloating = rule[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)) { if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
matched = True; matched = True;
@ -102,49 +102,53 @@ settags(Client *c, Client *trans) {
} }
void void
tag(Arg *arg) { tag(const char *arg) {
unsigned int i; int i;
if(!sel) if(!sel)
return; return;
for(i = 0; i < ntags; i++) for(i = 0; i < ntags; i++)
sel->tags[i] = (arg->i == -1) ? True : False; sel->tags[i] = arg == NULL;
if(arg->i >= 0 && arg->i < ntags) i = arg ? atoi(arg) : 0;
sel->tags[arg->i] = True; if(i >= 0 && i < ntags)
sel->tags[i] = True;
lt->arrange(); lt->arrange();
} }
void void
toggletag(Arg *arg) { toggletag(const char *arg) {
unsigned int i; int i, j;
if(!sel) if(!sel)
return; return;
sel->tags[arg->i] = !sel->tags[arg->i]; i = arg ? atoi(arg) : 0;
for(i = 0; i < ntags && !sel->tags[i]; i++); sel->tags[i] = !sel->tags[i];
if(i == ntags) for(j = 0; j < ntags && !sel->tags[j]; j++);
sel->tags[arg->i] = True; if(j == ntags)
sel->tags[i] = True;
lt->arrange(); lt->arrange();
} }
void void
toggleview(Arg *arg) { toggleview(const char *arg) {
unsigned int i; int i, j;
seltag[arg->i] = !seltag[arg->i]; i = arg ? atoi(arg) : 0;
for(i = 0; i < ntags && !seltag[i]; i++); seltag[i] = !seltag[i];
if(i == ntags) for(j = 0; j < ntags && !seltag[j]; j++);
seltag[arg->i] = True; /* cannot toggle last view */ if(j == ntags)
seltag[i] = True; /* cannot toggle last view */
lt->arrange(); lt->arrange();
} }
void void
view(Arg *arg) { view(const char *arg) {
unsigned int i; int i;
for(i = 0; i < ntags; i++) for(i = 0; i < ntags; i++)
seltag[i] = (arg->i == -1) ? True : False; seltag[i] = arg == NULL;
if(arg->i >= 0 && arg->i < ntags) i = arg ? atoi(arg) : 0;
seltag[arg->i] = True; if(i >= 0 && i < ntags)
seltag[i] = True;
lt->arrange(); lt->arrange();
} }

14
util.c
View File

@ -1,6 +1,6 @@
/* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com> /* © 2006-2007 Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details. * © 2006-2007 Sander van Dijk <a dot h dot vandijk at gmail dot com>
*/ * See LICENSE file for license details. */
#include "dwm.h" #include "dwm.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -30,12 +30,12 @@ eprint(const char *errstr, ...) {
} }
void void
spawn(Arg *arg) { spawn(const char *arg) {
static char *shell = NULL; static char *shell = NULL;
if(!shell && !(shell = getenv("SHELL"))) if(!shell && !(shell = getenv("SHELL")))
shell = "/bin/sh"; shell = "/bin/sh";
if(!arg->cmd) if(!arg)
return; return;
/* The double-fork construct avoids zombie processes and keeps the code /* The double-fork construct avoids zombie processes and keeps the code
* clean from stupid signal handlers. */ * clean from stupid signal handlers. */
@ -44,8 +44,8 @@ spawn(Arg *arg) {
if(dpy) if(dpy)
close(ConnectionNumber(dpy)); close(ConnectionNumber(dpy));
setsid(); setsid();
execl(shell, shell, "-c", arg->cmd, (char *)NULL); execl(shell, shell, "-c", arg, (char *)NULL);
fprintf(stderr, "dwm: execl '%s -c %s'", shell, arg->cmd); fprintf(stderr, "dwm: execl '%s -c %s'", shell, arg);
perror(" failed"); perror(" failed");
} }
exit(0); exit(0);