Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
f777d21899 | |||
82064af2d7 | |||
d54444cfd7 | |||
525ef3c178 | |||
5ef6ef1bac | |||
f4208e7cac | |||
ecc95c903b | |||
a207949b65 | |||
86d12249dd | |||
b098c94ed4 | |||
6a39a496d0 | |||
3d73084b5e | |||
12b1d439e4 | |||
1076161bf3 | |||
e21d93b7bd | |||
f504aea132 | |||
9955ddc978 | |||
0dfe729f90 | |||
8f698bd4cc | |||
99b126d0af | |||
a2d56f6dce | |||
db876f9fb0 | |||
05a618b06e | |||
72608f0d5a | |||
bba044de4f | |||
4d55eee754 | |||
d41b232b52 | |||
b35575574b | |||
666b4563a0 | |||
7315bb08ad | |||
f80688f1c7 | |||
dc5c070c44 | |||
8cc7f3bace | |||
5d3fd3707b | |||
1bf0c4a8e7 | |||
863656d2bc | |||
f1a34ae1e4 | |||
3000cad507 |
1
.hgtags
1
.hgtags
@ -3,3 +3,4 @@ d31b5ad96b0ba7b5b0a30928fcf000428339a577 0.1
|
||||
7e66082e5092fb0bccd18a3695a0bec52c80fdb2 0.3
|
||||
eb3165734f00fe7f7da8aeebaed00e60a57caac9 0.4
|
||||
22213b9a2114167ee8ba019a012e27da0422a61a 0.5
|
||||
c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 0.6
|
||||
|
52
Makefile
52
Makefile
@ -5,8 +5,6 @@ include config.mk
|
||||
|
||||
SRC = client.c draw.c event.c main.c tag.c util.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
MAN1 = dwm.1
|
||||
BIN = dwm
|
||||
|
||||
all: options dwm
|
||||
@echo finished
|
||||
@ -21,40 +19,44 @@ options:
|
||||
@echo CC $<
|
||||
@${CC} -c ${CFLAGS} $<
|
||||
|
||||
${OBJ}: dwm.h
|
||||
${OBJ}: dwm.h config.h
|
||||
|
||||
config.h:
|
||||
@echo creating $@ from config.default.h
|
||||
@cp config.default.h $@
|
||||
|
||||
dwm: ${OBJ}
|
||||
@echo LD $@
|
||||
@${CC} -o $@ ${OBJ} ${LDFLAGS}
|
||||
@strip $@
|
||||
|
||||
clean:
|
||||
rm -f dwm *.o dwm-${VERSION}.tar.gz
|
||||
@echo cleaning
|
||||
@rm -f dwm ${OBJ} dwm-${VERSION}.tar.gz
|
||||
|
||||
dist: clean
|
||||
mkdir -p dwm-${VERSION}
|
||||
cp -R Makefile README LICENSE config.mk *.h *.c ${MAN1} dwm-${VERSION}
|
||||
tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
||||
gzip dwm-${VERSION}.tar
|
||||
rm -rf dwm-${VERSION}
|
||||
@echo creating dist tarball
|
||||
@mkdir -p dwm-${VERSION}
|
||||
@cp -R LICENSE Makefile README config.*.h config.mk \
|
||||
dwm.1 dwm.h ${SRC} dwm-${VERSION}
|
||||
@tar -cf dwm-${VERSION}.tar dwm-${VERSION}
|
||||
@gzip dwm-${VERSION}.tar
|
||||
@rm -rf dwm-${VERSION}
|
||||
|
||||
install: all
|
||||
@echo installing executable file to ${DESTDIR}${PREFIX}/bin
|
||||
@mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
@cp -f ${BIN} ${DESTDIR}${PREFIX}/bin
|
||||
@for i in ${BIN}; do \
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
|
||||
done
|
||||
@echo installed executable files to ${DESTDIR}${PREFIX}/bin
|
||||
@cp -f dwm ${DESTDIR}${PREFIX}/bin
|
||||
@chmod 755 ${DESTDIR}${PREFIX}/bin/dwm
|
||||
@echo installing manual page to ${DESTDIR}${MANPREFIX}/man1
|
||||
@mkdir -p ${DESTDIR}${MANPREFIX}/man1
|
||||
@cp -f ${MAN1} ${DESTDIR}${MANPREFIX}/man1
|
||||
@for i in ${MAN1}; do \
|
||||
chmod 444 ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
|
||||
done
|
||||
@echo installed manual pages to ${DESTDIR}${MANPREFIX}/man1
|
||||
@cp -f dwm.1 ${DESTDIR}${MANPREFIX}/man1
|
||||
@chmod 644 ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
uninstall:
|
||||
for i in ${BIN}; do \
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/`basename $$i`; \
|
||||
done
|
||||
for i in ${MAN1}; do \
|
||||
rm -f ${DESTDIR}${MANPREFIX}/man1/`basename $$i`; \
|
||||
done
|
||||
@echo removing executable file from ${DESTDIR}${PREFIX}/bin
|
||||
@rm -f ${DESTDIR}${PREFIX}/bin/dwm
|
||||
@echo removing manual page from ${DESTDIR}${MANPREFIX}/man1
|
||||
@rm -f ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
|
||||
.PHONY: all options clean dist install uninstall
|
||||
|
4
README
4
README
@ -16,7 +16,6 @@ the /usr/local namespace by default).
|
||||
Afterwards enter the following command to build and install dwm (if
|
||||
necessary as root):
|
||||
|
||||
cp config.default.h config.h
|
||||
make clean install
|
||||
|
||||
|
||||
@ -45,4 +44,5 @@ like this in your .xinitrc:
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
The configuration of dwm is done by editing config.h.
|
||||
The configuration of dwm is done by creating a custom config.h
|
||||
and (re)compiling the source code.
|
||||
|
32
client.c
32
client.c
@ -16,9 +16,9 @@ resizetitle(Client *c)
|
||||
int i;
|
||||
|
||||
c->tw = 0;
|
||||
for(i = 0; i < TLast; i++)
|
||||
for(i = 0; i < ntags; i++)
|
||||
if(c->tags[i])
|
||||
c->tw += textw(c->tags[i]);
|
||||
c->tw += textw(tags[i]);
|
||||
c->tw += textw(c->name);
|
||||
if(c->tw > c->w)
|
||||
c->tw = c->w + 2;
|
||||
@ -211,6 +211,7 @@ manage(Window w, XWindowAttributes *wa)
|
||||
XSetWindowAttributes twa;
|
||||
|
||||
c = emallocz(sizeof(Client));
|
||||
c->tags = emallocz(ntags * sizeof(Bool));
|
||||
c->win = w;
|
||||
c->x = c->tx = wa->x;
|
||||
c->y = c->ty = wa->y;
|
||||
@ -244,10 +245,30 @@ manage(Window w, XWindowAttributes *wa)
|
||||
|
||||
XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button1, MODKEY | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button1, MODKEY | NUMLOCKMASK, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button1, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
|
||||
XGrabButton(dpy, Button2, MODKEY, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button2, MODKEY | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button2, MODKEY | NUMLOCKMASK, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button2, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
|
||||
XGrabButton(dpy, Button3, MODKEY, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button3, MODKEY | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button3, MODKEY | NUMLOCKMASK, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
XGrabButton(dpy, Button3, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
|
||||
GrabModeAsync, GrabModeSync, None, None);
|
||||
|
||||
settags(c);
|
||||
if(!c->isfloat)
|
||||
@ -429,6 +450,7 @@ unmanage(Client *c)
|
||||
if(!sel)
|
||||
sel = clients;
|
||||
}
|
||||
free(c->tags);
|
||||
free(c);
|
||||
|
||||
XSync(dpy, False);
|
||||
@ -444,12 +466,14 @@ zoom(Arg *arg)
|
||||
{
|
||||
Client *c;
|
||||
|
||||
if(!sel)
|
||||
if(!sel || (arrange != dotile) || sel->isfloat)
|
||||
return;
|
||||
|
||||
if(sel == getnext(clients) && sel->next) {
|
||||
if(sel == getnext(clients)) {
|
||||
if((c = getnext(sel->next)))
|
||||
sel = c;
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
/* pop */
|
||||
|
70
config.arg.h
70
config.arg.h
@ -3,71 +3,59 @@
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
enum { Tfnord, Tdev, Tnet, Twork, Tmisc, TLast };
|
||||
#define TAGS \
|
||||
char *tags[TLast] = { \
|
||||
[Tfnord] = "fnord", \
|
||||
[Tdev] = "dev", \
|
||||
[Tnet] = "net", \
|
||||
[Twork] = "work", \
|
||||
[Tmisc] = "misc", \
|
||||
};
|
||||
const char *tags[] = { "fnord", "dev", "net", "work", "misc", NULL };
|
||||
|
||||
#define DEFMODE dotile /* dofloat */
|
||||
#define DEFTAG Tdev
|
||||
#define DEFTAG 1 /* index */
|
||||
#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
|
||||
#define BGCOLOR "#0a2c2d"
|
||||
#define FGCOLOR "#ddeeee"
|
||||
#define BORDERCOLOR "#176164"
|
||||
#define MODKEY Mod1Mask
|
||||
#define NUMLOCKMASK Mod2Mask
|
||||
#define MASTERW 52 /* percent */
|
||||
#define MASTERW 60 /* percent */
|
||||
|
||||
#define KEYS \
|
||||
const char *browse[] = { "firefox", NULL }; \
|
||||
const char *gimp[] = { "gimp", NULL }; \
|
||||
const char *term[] = { \
|
||||
"urxvt", "-tr", "+sb", "-bg", "black", "-fg", "white", "-cr", "white", \
|
||||
"-fn", "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*", NULL \
|
||||
}; \
|
||||
const char *xlock[] = { "xlock", NULL }; \
|
||||
static Key key[] = { \
|
||||
/* modifier key function arguments */ \
|
||||
{ MODKEY, XK_0, view, { .i = Tfnord } }, \
|
||||
{ MODKEY, XK_1, view, { .i = Tdev } }, \
|
||||
{ MODKEY, XK_2, view, { .i = Tnet } }, \
|
||||
{ MODKEY, XK_3, view, { .i = Twork } }, \
|
||||
{ MODKEY, XK_4, view, { .i = Tmisc} }, \
|
||||
{ MODKEY, XK_0, view, { .i = 0 } }, \
|
||||
{ MODKEY, XK_1, view, { .i = 1 } }, \
|
||||
{ MODKEY, XK_2, view, { .i = 2 } }, \
|
||||
{ MODKEY, XK_3, view, { .i = 3 } }, \
|
||||
{ MODKEY, XK_4, view, { .i = 4 } }, \
|
||||
{ MODKEY, XK_h, viewprev, { 0 } }, \
|
||||
{ MODKEY, XK_j, focusnext, { 0 } }, \
|
||||
{ MODKEY, XK_k, focusprev, { 0 } }, \
|
||||
{ MODKEY, XK_l, viewnext, { 0 } }, \
|
||||
{ MODKEY, XK_m, togglemax, { 0 } }, \
|
||||
{ MODKEY, XK_p, spawn, \
|
||||
{ .cmd = "exec `ls -lL /usr/bin /usr/local/bin 2>/dev/null |" \
|
||||
" awk 'NF>2 && $1 ~ /^[^d].*x/ {print $NF}' | sort | uniq | dmenu`" } }, \
|
||||
{ MODKEY, XK_space, togglemode, { 0 } }, \
|
||||
{ MODKEY, XK_Return, zoom, { 0 } }, \
|
||||
{ MODKEY|ControlMask, XK_0, appendtag, { .i = Tfnord } }, \
|
||||
{ MODKEY|ControlMask, XK_1, appendtag, { .i = Tdev } }, \
|
||||
{ MODKEY|ControlMask, XK_2, appendtag, { .i = Tnet } }, \
|
||||
{ MODKEY|ControlMask, XK_3, appendtag, { .i = Twork } }, \
|
||||
{ MODKEY|ControlMask, XK_4, appendtag, { .i = Tmisc } }, \
|
||||
{ MODKEY|ShiftMask, XK_0, replacetag, { .i = Tfnord } }, \
|
||||
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = Tdev } }, \
|
||||
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = Tnet } }, \
|
||||
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = Twork } }, \
|
||||
{ MODKEY|ShiftMask, XK_4, replacetag, { .i = Tmisc } }, \
|
||||
{ MODKEY|ControlMask, XK_0, appendtag, { .i = 0 } }, \
|
||||
{ MODKEY|ControlMask, XK_1, appendtag, { .i = 1 } }, \
|
||||
{ MODKEY|ControlMask, XK_2, appendtag, { .i = 2 } }, \
|
||||
{ MODKEY|ControlMask, XK_3, appendtag, { .i = 3 } }, \
|
||||
{ MODKEY|ControlMask, XK_4, appendtag, { .i = 4 } }, \
|
||||
{ MODKEY|ShiftMask, XK_0, replacetag, { .i = 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = 1 } }, \
|
||||
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = 2 } }, \
|
||||
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = 3 } }, \
|
||||
{ MODKEY|ShiftMask, XK_4, replacetag, { .i = 5 } }, \
|
||||
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, { .argv = term } }, \
|
||||
{ MODKEY|ShiftMask, XK_g, spawn, { .argv = gimp } }, \
|
||||
{ MODKEY|ShiftMask, XK_l, spawn, { .argv = xlock } }, \
|
||||
{ MODKEY|ShiftMask, XK_w, spawn, { .argv = browse } }, \
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, \
|
||||
{ .cmd = "exec urxvt -tr +sb -bg black -fg white -cr white " \
|
||||
"-fn '-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*'" } }, \
|
||||
};
|
||||
|
||||
#define RULES \
|
||||
static Rule rule[] = { \
|
||||
/* class:instance tags isfloat */ \
|
||||
{ "Firefox.*", { [Tnet] = "net" }, False }, \
|
||||
{ "Gimp.*", { 0 }, True}, \
|
||||
{ "MPlayer.*", { 0 }, True}, \
|
||||
{ "Acroread.*", { 0 }, True}, \
|
||||
/* class:instance regex tags regex isfloat */ \
|
||||
{ "Firefox.*", "net", False }, \
|
||||
{ "Gimp.*", NULL, True}, \
|
||||
{ "MPlayer.*", NULL, True}, \
|
||||
{ "Acroread.*", NULL, True}, \
|
||||
};
|
||||
|
@ -3,35 +3,27 @@
|
||||
* See LICENSE file for license details.
|
||||
*/
|
||||
|
||||
enum { Tfnord, Tdev, Tnet, Twork, Tmisc, TLast };
|
||||
#define TAGS \
|
||||
char *tags[TLast] = { \
|
||||
[Tfnord] = "fnord", \
|
||||
[Tdev] = "dev", \
|
||||
[Tnet] = "net", \
|
||||
[Twork] = "work", \
|
||||
[Tmisc] = "misc", \
|
||||
};
|
||||
const char *tags[] = { "0", "1", "2", "3", "4", NULL };
|
||||
|
||||
#define DEFMODE dotile /* dofloat */
|
||||
#define DEFTAG Tdev
|
||||
#define DEFTAG 1 /* index */
|
||||
#define FONT "fixed"
|
||||
#define BGCOLOR "#666699"
|
||||
#define FGCOLOR "#eeeeee"
|
||||
#define BORDERCOLOR "#9999CC"
|
||||
#define MODKEY Mod1Mask
|
||||
#define NUMLOCKMASK Mod2Mask
|
||||
#define MASTERW 52 /* percent */
|
||||
#define MASTERW 60 /* percent */
|
||||
|
||||
#define KEYS \
|
||||
const char *term[] = { "xterm", NULL }; \
|
||||
static Key key[] = { \
|
||||
/* modifier key function arguments */ \
|
||||
{ MODKEY, XK_0, view, { .i = Tfnord } }, \
|
||||
{ MODKEY, XK_1, view, { .i = Tdev } }, \
|
||||
{ MODKEY, XK_2, view, { .i = Tnet } }, \
|
||||
{ MODKEY, XK_3, view, { .i = Twork } }, \
|
||||
{ MODKEY, XK_4, view, { .i = Tmisc} }, \
|
||||
{ MODKEY, XK_0, view, { .i = 0 } }, \
|
||||
{ MODKEY, XK_1, view, { .i = 1 } }, \
|
||||
{ MODKEY, XK_2, view, { .i = 2 } }, \
|
||||
{ MODKEY, XK_3, view, { .i = 3 } }, \
|
||||
{ MODKEY, XK_4, view, { .i = 4 } }, \
|
||||
{ MODKEY, XK_h, viewprev, { 0 } }, \
|
||||
{ MODKEY, XK_j, focusnext, { 0 } }, \
|
||||
{ MODKEY, XK_k, focusprev, { 0 } }, \
|
||||
@ -39,24 +31,24 @@ static Key key[] = { \
|
||||
{ MODKEY, XK_m, togglemax, { 0 } }, \
|
||||
{ MODKEY, XK_space, togglemode, { 0 } }, \
|
||||
{ MODKEY, XK_Return, zoom, { 0 } }, \
|
||||
{ MODKEY|ControlMask, XK_0, appendtag, { .i = Tfnord } }, \
|
||||
{ MODKEY|ControlMask, XK_1, appendtag, { .i = Tdev } }, \
|
||||
{ MODKEY|ControlMask, XK_2, appendtag, { .i = Tnet } }, \
|
||||
{ MODKEY|ControlMask, XK_3, appendtag, { .i = Twork } }, \
|
||||
{ MODKEY|ControlMask, XK_4, appendtag, { .i = Tmisc } }, \
|
||||
{ MODKEY|ShiftMask, XK_0, replacetag, { .i = Tfnord } }, \
|
||||
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = Tdev } }, \
|
||||
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = Tnet } }, \
|
||||
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = Twork } }, \
|
||||
{ MODKEY|ShiftMask, XK_4, replacetag, { .i = Tmisc } }, \
|
||||
{ MODKEY|ControlMask, XK_0, appendtag, { .i = 0 } }, \
|
||||
{ MODKEY|ControlMask, XK_1, appendtag, { .i = 1 } }, \
|
||||
{ MODKEY|ControlMask, XK_2, appendtag, { .i = 2 } }, \
|
||||
{ MODKEY|ControlMask, XK_3, appendtag, { .i = 3 } }, \
|
||||
{ MODKEY|ControlMask, XK_4, appendtag, { .i = 4 } }, \
|
||||
{ MODKEY|ShiftMask, XK_0, replacetag, { .i = 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = 1 } }, \
|
||||
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = 2 } }, \
|
||||
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = 3 } }, \
|
||||
{ MODKEY|ShiftMask, XK_4, replacetag, { .i = 4 } }, \
|
||||
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, { .argv = term } }, \
|
||||
{ MODKEY|ShiftMask, XK_Return, spawn, { .cmd = "exec xterm" } }, \
|
||||
};
|
||||
|
||||
#define RULES \
|
||||
static Rule rule[] = { \
|
||||
/* class:instance tags isfloat */ \
|
||||
{ "Firefox.*", { [Tnet] = "net" }, False }, \
|
||||
{ "Gimp.*", { 0 }, True}, \
|
||||
/* class:instance regex tags regex isfloat */ \
|
||||
{ "Firefox.*", "2", False }, \
|
||||
{ "Gimp.*", NULL, True}, \
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
# dwm version
|
||||
VERSION = 0.6
|
||||
VERSION = 0.7
|
||||
|
||||
# Customize below to fit your system
|
||||
|
||||
@ -15,7 +15,7 @@ INCS = -I/usr/lib -I${X11INC}
|
||||
LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
|
||||
|
||||
# flags
|
||||
CFLAGS = -O3 ${INCS} -DVERSION=\"${VERSION}\"
|
||||
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
|
||||
LDFLAGS = ${LIBS}
|
||||
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
|
||||
#LDFLAGS = -g ${LIBS}
|
||||
|
12
draw.c
12
draw.c
@ -30,7 +30,7 @@ drawborder(void)
|
||||
}
|
||||
|
||||
static unsigned int
|
||||
textnw(char *text, unsigned int len)
|
||||
textnw(const char *text, unsigned int len)
|
||||
{
|
||||
XRectangle r;
|
||||
|
||||
@ -114,7 +114,7 @@ drawstatus()
|
||||
drawtext(NULL, !istile, False);
|
||||
|
||||
dc.w = 0;
|
||||
for(i = 0; i < TLast; i++) {
|
||||
for(i = 0; i < ntags; i++) {
|
||||
dc.x += dc.w;
|
||||
dc.w = textw(tags[i]);
|
||||
if(istile)
|
||||
@ -153,11 +153,11 @@ drawtitle(Client *c)
|
||||
dc.x = dc.y = 0;
|
||||
|
||||
dc.w = 0;
|
||||
for(i = 0; i < TLast; i++) {
|
||||
for(i = 0; i < ntags; i++) {
|
||||
if(c->tags[i]) {
|
||||
dc.x += dc.w;
|
||||
dc.w = textw(c->tags[i]);
|
||||
drawtext(c->tags[i], !istile, True);
|
||||
dc.w = textw(tags[i]);
|
||||
drawtext(tags[i], !istile, True);
|
||||
}
|
||||
}
|
||||
dc.x += dc.w;
|
||||
@ -229,7 +229,7 @@ setfont(const char *fontstr)
|
||||
}
|
||||
|
||||
unsigned int
|
||||
textw(char *text)
|
||||
textw(const char *text)
|
||||
{
|
||||
return textnw(text, strlen(text)) + dc.font.height;
|
||||
}
|
||||
|
35
dwm.1
35
dwm.1
@ -1,4 +1,4 @@
|
||||
.TH DWM 1 dwm-0.6
|
||||
.TH DWM 1 dwm-0.7
|
||||
.SH NAME
|
||||
dwm \- dynamic window manager
|
||||
.SH SYNOPSIS
|
||||
@ -7,24 +7,25 @@ dwm \- dynamic window manager
|
||||
.SH DESCRIPTION
|
||||
.B dwm
|
||||
is a dynamic window manager for X11. It manages windows in tiling and floating
|
||||
modes. Either mode can be applied dynamically, depending on the application in
|
||||
use and the task performed.
|
||||
modes. Either mode can be applied dynamically, optimizing the environment for
|
||||
the application in use and the task performed.
|
||||
.P
|
||||
In tiling mode windows are managed in a master and stacking column. The master
|
||||
column contains the window which needs most attention at a time, whereas the
|
||||
stacking column contains all other windows in a stack. Dialog windows are
|
||||
managed floating, however. In floating mode windows can be resized and moved
|
||||
freely.
|
||||
column contains the window which currently needs most attention, whereas the
|
||||
stacking column contains all other windows. In floating mode windows can be
|
||||
resized and moved freely. Dialog windows are always managed floating,
|
||||
regardless of the mode selected.
|
||||
.P
|
||||
Windows are grouped by tags. All windows with a specific tag can be viewed at a
|
||||
time. But each window may contain more than one tag, which makes it visible in
|
||||
several views.
|
||||
Windows are grouped by tags. Each window can be tagged with one or multiple
|
||||
tags. Selecting a certain tag for viewing will display all windows with that
|
||||
tag.
|
||||
.P
|
||||
.B dwm
|
||||
has a small status bar which reads the text displayed from standard
|
||||
input, if written. It draws 1-pixel borders around windows to indicate the
|
||||
focus state. Unfocused windows contain a small bar in front of the window
|
||||
displaying the tags and the window title.
|
||||
has a small status bar which displays the text read from standard
|
||||
input, if written. Besides that, it displays all available tags, and the title
|
||||
of the focused window. It draws a 1-pixel border around windows to
|
||||
indicate the focus state. Unfocused windows contain a small bar in front of
|
||||
them displaying their tags and title.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-v
|
||||
@ -105,5 +106,7 @@ Resizes current
|
||||
while dragging
|
||||
.SH CUSTOMIZATION
|
||||
.B dwm
|
||||
is customized by editing the file config.h of the source code.
|
||||
This keeps it fast, secure and simple.
|
||||
is customized by creating a custom config.h and (re)compiling the source
|
||||
code. This keeps it fast, secure and simple.
|
||||
.SH SEE ALSO
|
||||
.BR dmenu (1)
|
||||
|
11
dwm.h
11
dwm.h
@ -17,7 +17,7 @@ typedef struct DC DC;
|
||||
typedef struct Fnt Fnt;
|
||||
|
||||
union Arg {
|
||||
const char **argv;
|
||||
const char *cmd;
|
||||
int i;
|
||||
};
|
||||
|
||||
@ -51,7 +51,6 @@ struct DC { /* draw context */
|
||||
|
||||
struct Client {
|
||||
char name[256];
|
||||
char *tags[TLast];
|
||||
int proto;
|
||||
int x, y, w, h;
|
||||
int tx, ty, tw, th; /* title */
|
||||
@ -61,14 +60,17 @@ struct Client {
|
||||
unsigned int border;
|
||||
Bool isfloat;
|
||||
Bool ismax;
|
||||
Bool *tags;
|
||||
Client *next;
|
||||
Client *prev;
|
||||
Window win;
|
||||
Window title;
|
||||
};
|
||||
|
||||
extern char *tags[TLast], stext[1024];
|
||||
extern const char *tags[];
|
||||
extern char stext[1024];
|
||||
extern int tsel, screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
|
||||
extern unsigned int ntags;
|
||||
extern void (*handler[LASTEvent])(XEvent *);
|
||||
extern void (*arrange)(Arg *);
|
||||
extern Atom wmatom[WMLast], netatom[NetLast];
|
||||
@ -104,7 +106,7 @@ extern void drawstatus();
|
||||
extern void drawtitle(Client *c);
|
||||
extern unsigned long getcolor(const char *colstr);
|
||||
extern void setfont(const char *fontstr);
|
||||
extern unsigned int textw(char *text);
|
||||
extern unsigned int textw(const char *text);
|
||||
|
||||
/* event.c */
|
||||
extern void grabkeys();
|
||||
@ -119,6 +121,7 @@ extern int xerror(Display *dsply, XErrorEvent *ee);
|
||||
extern void appendtag(Arg *arg);
|
||||
extern void dofloat(Arg *arg);
|
||||
extern void dotile(Arg *arg);
|
||||
extern void initrregs();
|
||||
extern Client *getnext(Client *c);
|
||||
extern Client *getprev(Client *c);
|
||||
extern void replacetag(Arg *arg);
|
||||
|
15
dwm.html
15
dwm.html
@ -39,7 +39,7 @@
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
dwm has no Lua integration, no 9P support, no menu, no editable
|
||||
dwm has no Lua integration, no 9P support, no editable
|
||||
tagbars, no shell-based configuration, no remote control, and comes
|
||||
without any additional tools like printing the selection or warping
|
||||
the mouse.
|
||||
@ -88,18 +88,22 @@
|
||||
It can be downloaded and distributed under the conditions
|
||||
of the <a href="http://10kloc.org/cgi-bin/hgwebdir.cgi/dwm?f=f10eb1139362;file=LICENSE;style=raw">MIT/X Consortium license</a>.
|
||||
</li>
|
||||
<li>
|
||||
Optionally you can install <b>dmenu</b> to extend dwm with a wmii-alike menu.
|
||||
</li>
|
||||
</ul>
|
||||
<h4>Links</h4>
|
||||
<ul>
|
||||
<li><a href="http://10kloc.org/cgi-bin/man/man2html?query=dwm">Man page</a></li>
|
||||
<li><a href="http://10kloc.org/shots/dwm-20060714.png">Screenshot</a> (20060714)</li>
|
||||
<li><a href="http://10kloc.org/shots/dwm-20060801.png">Screenshot</a> (20060801)</li>
|
||||
<li><a href="http://10kloc.org/download/poster.ps">A4 poster (PostScript)</a></li>
|
||||
<li>Mailing List: <a href="http://10kloc.org/cgi-bin/mailman/listinfo/dwm">dwm at wmii dot de</a> <a href="http://10kloc.org/pipermail/dwm/">(Archives)</a></li>
|
||||
<li>IRC channel: <code>#dwm</code> at <code>irc.oftc.net</code></li>
|
||||
</ul>
|
||||
<h3>Download</h3>
|
||||
<ul>
|
||||
<li><a href="http://10kloc.org/download/dwm-0.5.tar.gz">dwm 0.5</a> (13kb) (20060721)</li>
|
||||
<li><a href="http://10kloc.org/download/dwm-0.7.tar.gz">dwm 0.7</a> (14kb) (20060807)</li>
|
||||
<li><a href="http://10kloc.org/download/dmenu-0.2.tar.gz">dmenu 0.2</a> (7kb) (20060807)</li>
|
||||
</ul>
|
||||
<h3>Development</h3>
|
||||
<p>
|
||||
@ -108,11 +112,14 @@
|
||||
<p>
|
||||
<code>hg clone http://10kloc.org/cgi-bin/hgwebdir.cgi/dwm</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>hg clone http://10kloc.org/cgi-bin/hgwebdir.cgi/dmenu</code>
|
||||
</p>
|
||||
<h3>Miscellaneous</h3>
|
||||
<p>
|
||||
You can purchase this <a href="https://www.spreadshirt.net/shop.php?op=article&article_id=3298632&view=403">tricot</a>
|
||||
if you like dwm and the dwm logo, which has been designed by Anselm.
|
||||
</p>
|
||||
<p><small>--Anselm (20060801)</small></p>
|
||||
<p><small>--Anselm</small></p>
|
||||
</body>
|
||||
</html>
|
||||
|
30
event.c
30
event.c
@ -105,7 +105,7 @@ buttonpress(XEvent *e)
|
||||
switch(ev->button) {
|
||||
default:
|
||||
x = 0;
|
||||
for(a.i = 0; a.i < TLast; a.i++) {
|
||||
for(a.i = 0; a.i < ntags; a.i++) {
|
||||
x += textw(tags[a.i]);
|
||||
if(ev->x < x) {
|
||||
view(&a);
|
||||
@ -156,22 +156,17 @@ configurerequest(XEvent *e)
|
||||
|
||||
if((c = getclient(ev->window))) {
|
||||
gravitate(c, True);
|
||||
if(c->isfloat) {
|
||||
if(ev->value_mask & CWX)
|
||||
c->x = ev->x;
|
||||
if(ev->value_mask & CWY)
|
||||
c->y = ev->y;
|
||||
if(ev->value_mask & CWWidth)
|
||||
c->w = ev->width;
|
||||
if(ev->value_mask & CWHeight)
|
||||
c->h = ev->height;
|
||||
}
|
||||
if(ev->value_mask & CWX)
|
||||
c->x = ev->x;
|
||||
if(ev->value_mask & CWY)
|
||||
c->y = ev->y;
|
||||
if(ev->value_mask & CWWidth)
|
||||
c->w = ev->width;
|
||||
if(ev->value_mask & CWHeight)
|
||||
c->h = ev->height;
|
||||
if(ev->value_mask & CWBorderWidth)
|
||||
c->border = ev->border_width;
|
||||
gravitate(c, False);
|
||||
|
||||
resize(c, True, TopLeft);
|
||||
|
||||
wc.x = c->x;
|
||||
wc.y = c->y;
|
||||
wc.width = c->w;
|
||||
@ -193,6 +188,11 @@ configurerequest(XEvent *e)
|
||||
/* Send synthetic ConfigureNotify */
|
||||
XSendEvent(dpy, c->win, True, NoEventMask, &synev);
|
||||
}
|
||||
XSync(dpy, False);
|
||||
if(c->isfloat)
|
||||
resize(c, False, TopLeft);
|
||||
else
|
||||
arrange(NULL);
|
||||
}
|
||||
else {
|
||||
wc.x = ev->x;
|
||||
@ -203,8 +203,8 @@ configurerequest(XEvent *e)
|
||||
wc.sibling = ev->above;
|
||||
wc.stack_mode = ev->detail;
|
||||
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
XSync(dpy, False);
|
||||
}
|
||||
|
||||
static void
|
||||
|
14
main.c
14
main.c
@ -85,6 +85,7 @@ xerrorstart(Display *dsply, XErrorEvent *ee)
|
||||
char stext[1024];
|
||||
int tsel = DEFTAG;
|
||||
int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
|
||||
unsigned int ntags;
|
||||
Atom wmatom[WMLast], netatom[NetLast];
|
||||
Bool running = True;
|
||||
Bool issel = True;
|
||||
@ -101,9 +102,10 @@ getproto(Window w)
|
||||
int protos = 0;
|
||||
int i;
|
||||
long res;
|
||||
unsigned char *protocols;
|
||||
Atom *protocols;
|
||||
|
||||
res = win_property(w, wmatom[WMProtocols], XA_ATOM, 20L, &protocols);
|
||||
res = win_property(w, wmatom[WMProtocols], XA_ATOM, 20L,
|
||||
((unsigned char **)&protocols));
|
||||
if(res <= 0) {
|
||||
return protos;
|
||||
}
|
||||
@ -177,15 +179,14 @@ main(int argc, char *argv[])
|
||||
|
||||
dpy = XOpenDisplay(0);
|
||||
if(!dpy)
|
||||
eprint("dwm: cannot connect X server\n");
|
||||
eprint("dwm: cannot open display\n");
|
||||
|
||||
screen = DefaultScreen(dpy);
|
||||
root = RootWindow(dpy, screen);
|
||||
|
||||
/* check if another WM is already running */
|
||||
otherwm = False;
|
||||
XSetErrorHandler(xerrorstart);
|
||||
/* this causes an error if some other WM is running */
|
||||
/* this causes an error if some other window manager is running */
|
||||
XSelectInput(dpy, root, SubstructureRedirectMask);
|
||||
XSync(dpy, False);
|
||||
|
||||
@ -209,6 +210,9 @@ main(int argc, char *argv[])
|
||||
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
|
||||
|
||||
grabkeys();
|
||||
initrregs();
|
||||
|
||||
for(ntags = 0; tags[ntags]; ntags++);
|
||||
|
||||
/* style */
|
||||
dc.bg = getcolor(BGCOLOR);
|
||||
|
100
tag.c
100
tag.c
@ -5,21 +5,31 @@
|
||||
#include "dwm.h"
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
/* static */
|
||||
|
||||
typedef struct {
|
||||
const char *pattern;
|
||||
char *tags[TLast];
|
||||
const char *clpattern;
|
||||
const char *tpattern;
|
||||
Bool isfloat;
|
||||
} Rule;
|
||||
|
||||
typedef struct {
|
||||
regex_t *clregex;
|
||||
regex_t *tregex;
|
||||
} RReg;
|
||||
|
||||
/* static */
|
||||
|
||||
TAGS
|
||||
RULES
|
||||
|
||||
static RReg *rreg = NULL;
|
||||
static unsigned int len = 0;
|
||||
|
||||
void (*arrange)(Arg *) = DEFMODE;
|
||||
|
||||
/* extern */
|
||||
@ -30,7 +40,7 @@ appendtag(Arg *arg)
|
||||
if(!sel)
|
||||
return;
|
||||
|
||||
sel->tags[arg->i] = tags[arg->i];
|
||||
sel->tags[arg->i] = True;
|
||||
arrange(NULL);
|
||||
}
|
||||
|
||||
@ -47,14 +57,12 @@ dofloat(Arg *arg)
|
||||
else
|
||||
ban(c);
|
||||
}
|
||||
if(sel && !sel->tags[tsel]) {
|
||||
if((sel = getnext(clients))) {
|
||||
higher(sel);
|
||||
focus(sel);
|
||||
}
|
||||
else
|
||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||
if((sel = getnext(clients))) {
|
||||
higher(sel);
|
||||
focus(sel);
|
||||
}
|
||||
else
|
||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||
drawall();
|
||||
}
|
||||
|
||||
@ -112,14 +120,12 @@ dotile(Arg *arg)
|
||||
else
|
||||
ban(c);
|
||||
}
|
||||
if(!sel || (sel && !sel->tags[tsel])) {
|
||||
if((sel = getnext(clients))) {
|
||||
higher(sel);
|
||||
focus(sel);
|
||||
}
|
||||
else
|
||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||
if((sel = getnext(clients))) {
|
||||
higher(sel);
|
||||
focus(sel);
|
||||
}
|
||||
else
|
||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||
drawall();
|
||||
}
|
||||
|
||||
@ -137,6 +143,35 @@ getprev(Client *c)
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
initrregs()
|
||||
{
|
||||
unsigned int i;
|
||||
regex_t *reg;
|
||||
|
||||
if(rreg)
|
||||
return;
|
||||
len = sizeof(rule) / sizeof(rule[0]);
|
||||
rreg = emallocz(len * sizeof(RReg));
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
if(rule[i].clpattern) {
|
||||
reg = emallocz(sizeof(regex_t));
|
||||
if(regcomp(reg, rule[i].clpattern, 0))
|
||||
free(reg);
|
||||
else
|
||||
rreg[i].clregex = reg;
|
||||
}
|
||||
if(rule[i].tpattern) {
|
||||
reg = emallocz(sizeof(regex_t));
|
||||
if(regcomp(reg, rule[i].tpattern, 0))
|
||||
free(reg);
|
||||
else
|
||||
rreg[i].tregex = reg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
replacetag(Arg *arg)
|
||||
{
|
||||
@ -145,8 +180,8 @@ replacetag(Arg *arg)
|
||||
if(!sel)
|
||||
return;
|
||||
|
||||
for(i = 0; i < TLast; i++)
|
||||
sel->tags[i] = NULL;
|
||||
for(i = 0; i < ntags; i++)
|
||||
sel->tags[i] = False;
|
||||
appendtag(arg);
|
||||
}
|
||||
|
||||
@ -154,9 +189,7 @@ void
|
||||
settags(Client *c)
|
||||
{
|
||||
char classinst[256];
|
||||
static unsigned int len = sizeof(rule) / sizeof(rule[0]);
|
||||
unsigned int i, j;
|
||||
regex_t regex;
|
||||
regmatch_t tmp;
|
||||
Bool matched = False;
|
||||
XClassHint ch;
|
||||
@ -165,26 +198,23 @@ settags(Client *c)
|
||||
snprintf(classinst, sizeof(classinst), "%s:%s",
|
||||
ch.res_class ? ch.res_class : "",
|
||||
ch.res_name ? ch.res_name : "");
|
||||
for(i = 0; !matched && i < len; i++) {
|
||||
if(!regcomp(®ex, rule[i].pattern, 0)) {
|
||||
if(!regexec(®ex, classinst, 1, &tmp, 0)) {
|
||||
for(j = 0; j < TLast; j++) {
|
||||
if(rule[i].tags[j])
|
||||
matched = True;
|
||||
c->tags[j] = rule[i].tags[j];
|
||||
for(i = 0; !matched && i < len; i++)
|
||||
if(rreg[i].clregex && !regexec(rreg[i].clregex, classinst, 1, &tmp, 0)) {
|
||||
c->isfloat = rule[i].isfloat;
|
||||
for(j = 0; rreg[i].tregex && j < ntags; j++) {
|
||||
if(!regexec(rreg[i].tregex, tags[j], 1, &tmp, 0)) {
|
||||
matched = True;
|
||||
c->tags[j] = True;
|
||||
}
|
||||
c->isfloat = rule[i].isfloat;
|
||||
}
|
||||
regfree(®ex);
|
||||
}
|
||||
}
|
||||
if(ch.res_class)
|
||||
XFree(ch.res_class);
|
||||
if(ch.res_name)
|
||||
XFree(ch.res_name);
|
||||
}
|
||||
if(!matched)
|
||||
c->tags[tsel] = tags[tsel];
|
||||
c->tags[tsel] = True;
|
||||
}
|
||||
|
||||
void
|
||||
@ -205,13 +235,13 @@ view(Arg *arg)
|
||||
void
|
||||
viewnext(Arg *arg)
|
||||
{
|
||||
arg->i = (tsel < TLast-1) ? tsel+1 : 0;
|
||||
arg->i = (tsel < ntags-1) ? tsel+1 : 0;
|
||||
view(arg);
|
||||
}
|
||||
|
||||
void
|
||||
viewprev(Arg *arg)
|
||||
{
|
||||
arg->i = (tsel > 0) ? tsel-1 : TLast-1;
|
||||
arg->i = (tsel > 0) ? tsel-1 : ntags-1;
|
||||
view(arg);
|
||||
}
|
||||
|
14
util.c
14
util.c
@ -30,7 +30,8 @@ emallocz(unsigned int size)
|
||||
}
|
||||
|
||||
void
|
||||
eprint(const char *errstr, ...) {
|
||||
eprint(const char *errstr, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, errstr);
|
||||
@ -42,17 +43,20 @@ eprint(const char *errstr, ...) {
|
||||
void
|
||||
spawn(Arg *arg)
|
||||
{
|
||||
char **argv = (char **)arg->argv;
|
||||
static char *shell = NULL;
|
||||
|
||||
if(!argv || !argv[0])
|
||||
if(!shell && !(shell = getenv("SHELL")))
|
||||
shell = "/bin/sh";
|
||||
|
||||
if(!arg->cmd)
|
||||
return;
|
||||
if(fork() == 0) {
|
||||
if(fork() == 0) {
|
||||
if(dpy)
|
||||
close(ConnectionNumber(dpy));
|
||||
setsid();
|
||||
execvp(argv[0], argv);
|
||||
fprintf(stderr, "dwm: execvp %s", argv[0]);
|
||||
execl(shell, shell, "-c", arg->cmd, NULL);
|
||||
fprintf(stderr, "dwm: execl '%s'", arg->cmd);
|
||||
perror(" failed");
|
||||
}
|
||||
exit(0);
|
||||
|
Reference in New Issue
Block a user