Compare commits
75 Commits
Author | SHA1 | Date | |
---|---|---|---|
0680c76a6f | |||
c3e5f5cc9a | |||
1c620d27d8 | |||
fde45ebed8 | |||
4bd0d33f57 | |||
00255728aa | |||
4b0328f209 | |||
30561a0161 | |||
a4c4998c8b | |||
8e053b6476 | |||
b79b5facb1 | |||
c53f0fca91 | |||
c225e1afc2 | |||
92e55c7c53 | |||
c86f131681 | |||
e943234d09 | |||
9fc24e371b | |||
cac467d52c | |||
04f17d2669 | |||
dff15a02f7 | |||
42277b1110 | |||
095f9e143e | |||
9fbb2ebb90 | |||
dbcf87ce76 | |||
4250c26e9b | |||
e48de30516 | |||
1f0060caa3 | |||
c732cc90ab | |||
4e2c5b5f25 | |||
d9386a0c07 | |||
66e16c92d3 | |||
6a8e176df1 | |||
632c7f3410 | |||
045f1840e0 | |||
45d16d090b | |||
525c5ff4d8 | |||
5952157c3b | |||
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 |
2
.hgtags
2
.hgtags
@ -3,3 +3,5 @@ d31b5ad96b0ba7b5b0a30928fcf000428339a577 0.1
|
||||
7e66082e5092fb0bccd18a3695a0bec52c80fdb2 0.3
|
||||
eb3165734f00fe7f7da8aeebaed00e60a57caac9 0.4
|
||||
22213b9a2114167ee8ba019a012e27da0422a61a 0.5
|
||||
c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 0.6
|
||||
3fb41412e2492f66476d92ce8f007a8b48fb1d2a 0.7
|
||||
|
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.mk
|
||||
|
||||
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
|
||||
@sed 's/VERSION/${VERSION}/g' < dwm.1 > ${DESTDIR}${MANPREFIX}/man1/dwm.1
|
||||
@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.
|
||||
|
41
client.c
41
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;
|
||||
@ -49,6 +49,8 @@ ban(Client *c)
|
||||
void
|
||||
focus(Client *c)
|
||||
{
|
||||
if (!issel)
|
||||
return;
|
||||
Client *old = sel;
|
||||
XEvent ev;
|
||||
|
||||
@ -196,13 +198,6 @@ killclient(Arg *arg)
|
||||
XKillClient(dpy, sel->win);
|
||||
}
|
||||
|
||||
void
|
||||
lower(Client *c)
|
||||
{
|
||||
XLowerWindow(dpy, c->title);
|
||||
XLowerWindow(dpy, c->win);
|
||||
}
|
||||
|
||||
void
|
||||
manage(Window w, XWindowAttributes *wa)
|
||||
{
|
||||
@ -211,6 +206,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 +240,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 +445,7 @@ unmanage(Client *c)
|
||||
if(!sel)
|
||||
sel = clients;
|
||||
}
|
||||
free(c->tags);
|
||||
free(c);
|
||||
|
||||
XSync(dpy, False);
|
||||
@ -444,12 +461,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 */
|
||||
|
72
config.arg.h
72
config.arg.h
@ -3,71 +3,53 @@
|
||||
* 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[] = { "work", "net", "fnord", NULL };
|
||||
|
||||
#define DEFMODE dotile /* dofloat */
|
||||
#define DEFTAG Tdev
|
||||
#define FONT "-*-terminus-medium-*-*-*-13-*-*-*-*-*-iso10646-*"
|
||||
#define BGCOLOR "#0a2c2d"
|
||||
#define FGCOLOR "#ddeeee"
|
||||
#define BORDERCOLOR "#176164"
|
||||
#define DEFTAG 0 /* index */
|
||||
#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
|
||||
#define BGCOLOR "#eeeeee"
|
||||
#define FGCOLOR "#666699"
|
||||
#define BORDERCOLOR "#9999CC"
|
||||
#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_1, view, { .i = 0 } }, \
|
||||
{ MODKEY, XK_2, view, { .i = 1 } }, \
|
||||
{ MODKEY, XK_3, view, { .i = 2 } }, \
|
||||
{ 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_1, appendtag, { .i = 0 } }, \
|
||||
{ MODKEY|ControlMask, XK_2, appendtag, { .i = 1 } }, \
|
||||
{ MODKEY|ControlMask, XK_3, appendtag, { .i = 2 } }, \
|
||||
{ MODKEY|ShiftMask, XK_1, replacetag, { .i = 0 } }, \
|
||||
{ MODKEY|ShiftMask, XK_2, replacetag, { .i = 1 } }, \
|
||||
{ MODKEY|ShiftMask, XK_3, replacetag, { .i = 2 } }, \
|
||||
{ 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 uxterm -bg '#dddddd' -fg '#000000' -cr '#000000' +sb " \
|
||||
"-fn '-*-terminus-medium-*-*-*-12-*-*-*-*-*-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.8
|
||||
|
||||
# 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}
|
||||
|
32
draw.c
32
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;
|
||||
|
||||
@ -42,7 +42,7 @@ textnw(char *text, unsigned int len)
|
||||
}
|
||||
|
||||
static void
|
||||
drawtext(const char *text, Bool invert, Bool border)
|
||||
drawtext(const char *text, Bool invert)
|
||||
{
|
||||
int x, y, w, h;
|
||||
static char buf[256];
|
||||
@ -52,14 +52,12 @@ drawtext(const char *text, Bool invert, Bool border)
|
||||
|
||||
XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
|
||||
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
|
||||
|
||||
w = 0;
|
||||
if(border)
|
||||
drawborder();
|
||||
|
||||
if(!text)
|
||||
return;
|
||||
|
||||
w = 0;
|
||||
len = strlen(text);
|
||||
if(len >= sizeof(buf))
|
||||
len = sizeof(buf) - 1;
|
||||
@ -111,24 +109,24 @@ drawstatus()
|
||||
|
||||
dc.x = dc.y = 0;
|
||||
dc.w = bw;
|
||||
drawtext(NULL, !istile, False);
|
||||
drawtext(NULL, !istile);
|
||||
|
||||
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)
|
||||
drawtext(tags[i], (i == tsel), True);
|
||||
drawtext(tags[i], (i == tsel));
|
||||
else
|
||||
drawtext(tags[i], (i != tsel), True);
|
||||
drawtext(tags[i], (i != tsel));
|
||||
}
|
||||
x = dc.x + dc.w;
|
||||
dc.w = textw(stext);
|
||||
dc.x = bx + bw - dc.w;
|
||||
drawtext(stext, !istile, False);
|
||||
drawtext(stext, !istile);
|
||||
if(sel && ((dc.w = dc.x - x) >= bh)) {
|
||||
dc.x = x;
|
||||
drawtext(sel->name, istile, True);
|
||||
drawtext(sel->name, istile);
|
||||
}
|
||||
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
|
||||
XSync(dpy, False);
|
||||
@ -140,7 +138,7 @@ drawtitle(Client *c)
|
||||
int i;
|
||||
Bool istile = arrange == dotile;
|
||||
|
||||
if(c == sel) {
|
||||
if(c == sel && issel) {
|
||||
drawstatus();
|
||||
XUnmapWindow(dpy, c->title);
|
||||
XSetWindowBorder(dpy, c->win, dc.fg);
|
||||
@ -153,16 +151,16 @@ 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);
|
||||
}
|
||||
}
|
||||
dc.x += dc.w;
|
||||
dc.w = textw(c->name);
|
||||
drawtext(c->name, !istile, True);
|
||||
drawtext(c->name, !istile);
|
||||
XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 0);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
@ -229,7 +227,7 @@ setfont(const char *fontstr)
|
||||
}
|
||||
|
||||
unsigned int
|
||||
textw(char *text)
|
||||
textw(const char *text)
|
||||
{
|
||||
return textnw(text, strlen(text)) + dc.font.height;
|
||||
}
|
||||
|
74
dwm.1
74
dwm.1
@ -1,4 +1,4 @@
|
||||
.TH DWM 1 dwm-0.6
|
||||
.TH DWM 1 dwm-VERSION
|
||||
.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
|
||||
@ -32,35 +33,35 @@ prints version information to standard output, then exits.
|
||||
.SH USAGE
|
||||
.TP
|
||||
.B Mod1-Return
|
||||
Zoom
|
||||
Zoom current
|
||||
.B window
|
||||
to the
|
||||
.B master
|
||||
column
|
||||
column.
|
||||
.TP
|
||||
.B Mod1-h
|
||||
Focus previous
|
||||
.B tag
|
||||
.B tag.
|
||||
.TP
|
||||
.B Mod1-j
|
||||
Focus next
|
||||
.B window
|
||||
.B window.
|
||||
.TP
|
||||
.B Mod1-k
|
||||
Focus previous
|
||||
.B window
|
||||
.B window.
|
||||
.TP
|
||||
.B Mod1-l
|
||||
Focus next
|
||||
.B tag
|
||||
.B tag.
|
||||
.TP
|
||||
.B Mod1-m
|
||||
Maximize current
|
||||
.B window
|
||||
.B window.
|
||||
.TP
|
||||
.B Mod1-[0..n]
|
||||
Focus
|
||||
.B nth tag
|
||||
.B nth tag.
|
||||
.TP
|
||||
.B Mod1-space
|
||||
Toggle between
|
||||
@ -68,42 +69,47 @@ Toggle between
|
||||
and
|
||||
.B floating
|
||||
mode (affects
|
||||
.BR "all windows" )
|
||||
.BR "all windows" ).
|
||||
.TP
|
||||
.B Mod1-Shift-[0..n]
|
||||
Apply
|
||||
.B nth tag
|
||||
to current
|
||||
.B window
|
||||
.B window.
|
||||
.TP
|
||||
.B Mod1-Shift-q
|
||||
Quit
|
||||
.B dwm
|
||||
.B dwm.
|
||||
.TP
|
||||
.B Mod1-Shift-Return
|
||||
Start
|
||||
.B terminal
|
||||
.B terminal.
|
||||
.TP
|
||||
.B Mod1-Control-[0..n]
|
||||
Append
|
||||
.B nth tag
|
||||
to current
|
||||
.B window
|
||||
.B window.
|
||||
.TP
|
||||
.B Mod1-Button1
|
||||
Moves current
|
||||
Move current
|
||||
.B window
|
||||
while dragging
|
||||
while dragging.
|
||||
.TP
|
||||
.B Mod1-Button2
|
||||
Lowers current
|
||||
Zoom current
|
||||
.B window
|
||||
to the
|
||||
.B master
|
||||
column.
|
||||
.TP
|
||||
.B Mod1-Button3
|
||||
Resizes current
|
||||
Resize current
|
||||
.B window
|
||||
while dragging
|
||||
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)
|
||||
|
12
dwm.h
12
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];
|
||||
@ -89,7 +91,6 @@ extern Client *getctitle(Window w);
|
||||
extern void gravitate(Client *c, Bool invert);
|
||||
extern void higher(Client *c);
|
||||
extern void killclient(Arg *arg);
|
||||
extern void lower(Client *c);
|
||||
extern void manage(Window w, XWindowAttributes *wa);
|
||||
extern void resize(Client *c, Bool sizehints, Corner sticky);
|
||||
extern void setsize(Client *c);
|
||||
@ -104,7 +105,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 +120,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);
|
||||
|
18
dwm.html
18
dwm.html
@ -21,7 +21,7 @@
|
||||
<p>
|
||||
dwm is a dynamic window manager for X11.
|
||||
</p>
|
||||
<h4>Philosophy</h4>
|
||||
<h4>Background</h4>
|
||||
<p>
|
||||
As founder and main developer of wmii I came to the conclusion that
|
||||
wmii is too clunky for my needs. I don't need so many funky features
|
||||
@ -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,23 @@
|
||||
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-20060810a.png">Screenshot of tiled mode</a> (20060810)</li>
|
||||
<li><a href="http://10kloc.org/shots/dwm-20060810b.png">Screenshotof floating mode</a> (20060810)</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.8.tar.gz">dwm 0.8</a> (14kb) (20060810)</li>
|
||||
<li><a href="http://10kloc.org/download/dmenu-0.3.tar.gz">dmenu 0.3</a> (7kb) (20060810)</li>
|
||||
</ul>
|
||||
<h3>Development</h3>
|
||||
<p>
|
||||
@ -108,11 +113,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>
|
||||
|
51
event.c
51
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);
|
||||
@ -114,32 +114,30 @@ buttonpress(XEvent *e)
|
||||
}
|
||||
break;
|
||||
case Button4:
|
||||
viewnext(&a);
|
||||
viewprev(&a);
|
||||
break;
|
||||
case Button5:
|
||||
viewprev(&a);
|
||||
viewnext(&a);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if((c = getclient(ev->window))) {
|
||||
higher(c);
|
||||
focus(c);
|
||||
switch(ev->button) {
|
||||
default:
|
||||
break;
|
||||
case Button1:
|
||||
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
|
||||
higher(c);
|
||||
if(!c->ismax && (arrange == dofloat || c->isfloat))
|
||||
movemouse(c);
|
||||
}
|
||||
break;
|
||||
case Button2:
|
||||
lower(c);
|
||||
if(!c->ismax && arrange != dofloat && !c->isfloat)
|
||||
zoom(NULL);
|
||||
break;
|
||||
case Button3:
|
||||
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
|
||||
higher(c);
|
||||
if(!c->ismax && (arrange == dofloat || c->isfloat))
|
||||
resizemouse(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -156,7 +154,6 @@ 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)
|
||||
@ -165,13 +162,9 @@ configurerequest(XEvent *e)
|
||||
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 +186,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,9 +201,9 @@ configurerequest(XEvent *e)
|
||||
wc.sibling = ev->above;
|
||||
wc.stack_mode = ev->detail;
|
||||
XConfigureWindow(dpy, ev->window, ev->value_mask, &wc);
|
||||
}
|
||||
XSync(dpy, False);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroynotify(XEvent *e)
|
||||
@ -223,13 +221,16 @@ enternotify(XEvent *e)
|
||||
Client *c;
|
||||
XCrossingEvent *ev = &e->xcrossing;
|
||||
|
||||
if(ev->detail == NotifyInferior)
|
||||
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
|
||||
return;
|
||||
|
||||
if((c = getclient(ev->window)) || (c = getctitle(ev->window)))
|
||||
focus(c);
|
||||
else if(ev->window == root)
|
||||
else if(ev->window == root) {
|
||||
issel = True;
|
||||
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
|
||||
drawall();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -269,8 +270,10 @@ leavenotify(XEvent *e)
|
||||
{
|
||||
XCrossingEvent *ev = &e->xcrossing;
|
||||
|
||||
if((ev->window == root) && !ev->same_screen)
|
||||
issel = True;
|
||||
if((ev->window == root) && !ev->same_screen) {
|
||||
issel = False;
|
||||
drawall();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -359,20 +362,12 @@ grabkeys()
|
||||
|
||||
for(i = 0; i < len; i++) {
|
||||
code = XKeysymToKeycode(dpy, key[i].keysym);
|
||||
/* normal */
|
||||
XUngrabKey(dpy, code, key[i].mod, root);
|
||||
XGrabKey(dpy, code, key[i].mod, root, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
/* capslock */
|
||||
XUngrabKey(dpy, code, key[i].mod | LockMask, root);
|
||||
XGrabKey(dpy, code, key[i].mod | LockMask, root, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
/* numlock */
|
||||
XUngrabKey(dpy, code, key[i].mod | NUMLOCKMASK, root);
|
||||
XGrabKey(dpy, code, key[i].mod | NUMLOCKMASK, root, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
/* capslock & numlock */
|
||||
XUngrabKey(dpy, code, key[i].mod | NUMLOCKMASK | LockMask, root);
|
||||
XGrabKey(dpy, code, key[i].mod | NUMLOCKMASK | LockMask, root, True,
|
||||
GrabModeAsync, GrabModeAsync);
|
||||
}
|
||||
|
20
main.c
20
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);
|
||||
@ -236,6 +240,8 @@ main(int argc, char *argv[])
|
||||
|
||||
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
|
||||
dc.gc = XCreateGC(dpy, root, 0, 0);
|
||||
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
drawstatus();
|
||||
|
||||
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
|
||||
@ -244,10 +250,10 @@ main(int argc, char *argv[])
|
||||
wa.cursor = cursor[CurNormal];
|
||||
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
|
||||
|
||||
strcpy(stext, "dwm-"VERSION);
|
||||
scan();
|
||||
|
||||
/* main event loop, reads status text from stdin as well */
|
||||
/* main event loop, also reads status text from stdin */
|
||||
XSync(dpy, False);
|
||||
while(running) {
|
||||
FD_ZERO(&rd);
|
||||
if(readin)
|
||||
|
81
tag.c
81
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);
|
||||
}
|
||||
drawall();
|
||||
}
|
||||
|
||||
@ -98,6 +106,9 @@ dotile(Arg *arg)
|
||||
c->x = sx + mw;
|
||||
c->y = sy + (i - 1) * h + bh;
|
||||
c->w = w - 2;
|
||||
if(i + 1 == n)
|
||||
c->h = sh - c->y - 2;
|
||||
else
|
||||
c->h = h - 2;
|
||||
}
|
||||
else { /* fallback if h < bh */
|
||||
@ -112,14 +123,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);
|
||||
}
|
||||
drawall();
|
||||
}
|
||||
|
||||
@ -137,6 +146,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 +183,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 +192,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,17 +201,14 @@ 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;
|
||||
}
|
||||
regfree(®ex);
|
||||
}
|
||||
}
|
||||
if(ch.res_class)
|
||||
@ -184,7 +217,7 @@ settags(Client *c)
|
||||
XFree(ch.res_name);
|
||||
}
|
||||
if(!matched)
|
||||
c->tags[tsel] = tags[tsel];
|
||||
c->tags[tsel] = True;
|
||||
}
|
||||
|
||||
void
|
||||
@ -205,13 +238,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 -c %s'", shell, arg->cmd);
|
||||
perror(" failed");
|
||||
}
|
||||
exit(0);
|
||||
|
Reference in New Issue
Block a user