Compare commits

...

54 Commits
0.8 ... 0.9

Author SHA1 Message Date
a1682b8927 prepared dwm-0.9 2006-08-15 10:11:29 +02:00
24d91e3b8a extended cleanup 2006-08-15 09:37:12 +02:00
ce04a66528 applied Sanders changes to config.arg.h 2006-08-15 08:38:19 +02:00
df74b26e5d applied jk_to_tab patch 2006-08-15 08:25:11 +02:00
b6ad663f87 changed main event loop 2006-08-15 07:31:42 +02:00
ee31e38dc7 removed NUMLOCKMASK, added dynamically calculated numlockmask instead 2006-08-14 19:18:02 +02:00
442334641e added Sander to LICENSE (since he has contributed/revised big portions) 2006-08-14 18:47:13 +02:00
dfa5ea6360 applied viewsel.patch 2006-08-14 18:46:07 +02:00
3e06edeb5d applied sanders man page patch, removed button2 from bar click 2006-08-14 18:14:08 +02:00
78b050c13c applied sanders tag()/toggletag() fixes 2006-08-14 17:50:48 +02:00
4ad20ffc2c fixed 2006-08-14 17:48:54 +02:00
57e6e3bb80 added missing arrange 2006-08-14 17:14:22 +02:00
19da197f58 changed replacetag into toggletag 2006-08-14 16:59:18 +02:00
666fae97e6 added some flicker prevention 2006-08-14 16:37:55 +02:00
823fb1118a remove unnecessary XSync 2006-08-14 16:26:06 +02:00
db1d62e184 changed order of selecting input at root window 2006-08-14 16:21:16 +02:00
d26ffc7fa3 removed finished message 2006-08-14 16:11:54 +02:00
0f3acce042 added mappingnotify event for kb refreshes 2006-08-14 16:08:52 +02:00
9eef9f7b02 removed unneecessary crap 2006-08-14 15:43:04 +02:00
aff4c787f4 applied the saner patch (removed the pathetic one) 2006-08-14 15:33:23 +02:00
fe3dfbbe90 pplied Sanders appendtag patch 2006-08-14 15:31:58 +02:00
2ffdc1936c some other small fixes 2006-08-14 15:11:02 +02:00
0fe52c63ea removed ungrabkeys again (because of sander's mail) 2006-08-14 11:38:43 +02:00
28a52197c4 fixed string cutting 2006-08-14 10:58:03 +02:00
2c0d1cc87b fixed a core dump 2006-08-14 10:49:22 +02:00
375a251d16 implemented ungrabkeys() which is called in cleanup() 2006-08-14 10:24:38 +02:00
d4b7a9a373 implemented restack behavior (floats are on top in tiled mode) 2006-08-14 10:18:24 +02:00
4d67199a4b fixed string cutting in draw.c 2006-08-14 08:52:15 +02:00
95766d6241 applied Sanders LD and resize patches 2006-08-14 08:43:19 +02:00
4cb78a170c removed viewnext/viewprev 2006-08-14 08:38:26 +02:00
2c66b422e7 supplying NULL args in select 2006-08-14 07:40:20 +02:00
e571de83e9 reducing ConnectionNumber calls to a bare minimum 2006-08-14 07:23:46 +02:00
4bb89e2cb1 updated man page, added CAVEATS section 2006-08-13 18:04:42 +02:00
349cadacf6 made shortcuts like proposed by Sander, renamed viewextend to toggleview (more clear) 2006-08-13 17:58:06 +02:00
292ccc4c43 implemented viewextend and added M-S-C-n shortcuts for extending the current view... updated man page (works great!) nice feature 2006-08-11 19:26:12 +02:00
d7413ffd2d implement multi-tag selection through button3 click on the specific tag 2006-08-11 18:37:41 +02:00
50729a2e73 after some days of experimenting with grey background, I finally give up and switch to white on black ;) 2006-08-11 18:11:39 +02:00
a3e3f0b9ed applied Sanders fixes to dwm.1 2006-08-11 17:12:48 +02:00
45aea23355 fixed dwm.1, added Mod1-Shift-c (was missing for an odd reason) 2006-08-11 12:32:34 +02:00
975b459c17 simplified drawtext 2006-08-11 11:52:55 +02:00
2b35faee06 updated dwm(1) 2006-08-11 10:54:29 +02:00
84818bdbb5 upgraded version info 2006-08-11 10:28:51 +02:00
895902b57a applied Sander's patch as well 2006-08-11 10:05:53 +02:00
7d4184dc5c realized that client focussing through the bar is pretty useless, better is sloppy view focussing for B1/B3 as well instead 2006-08-11 10:00:47 +02:00
8278f0a6be implemented focusprev on button1 press in the bar, and focusnext on button3 press in the bar 2006-08-11 09:16:40 +02:00
d3969634ac simplified unmanage 2006-08-11 08:47:55 +02:00
735ca9ccd6 removed the if(clients) check from popping code 2006-08-11 08:34:42 +02:00
4ee661d908 added dwm favicon 2006-08-10 18:44:19 +02:00
9fce8215b7 applied Sanders zoom_update patch 2006-08-10 17:48:50 +02:00
6521c2dd41 respecting inc hints in floating mode on togglemax 2006-08-10 17:33:11 +02:00
9ee9ce7e14 reverting last patch, that sucks, I don't care about retarded apps like gvim 2006-08-10 16:37:13 +02:00
9d39da6452 togglemax repects inc-hints (this way gvim can be toggle'maxed as well) 2006-08-10 16:35:36 +02:00
0228dcd58f applied grammar correction by ILF 2006-08-10 15:35:02 +02:00
3d35ea99bb Added tag 0.8 for changeset cd15de32e173f8ce97bfe1c9b6607937b59056b4 2006-08-10 15:19:31 +02:00
16 changed files with 430 additions and 282 deletions

View File

@ -5,3 +5,4 @@ eb3165734f00fe7f7da8aeebaed00e60a57caac9 0.4
22213b9a2114167ee8ba019a012e27da0422a61a 0.5
c11f86db4550cac5d0a648a3fe4d6d3b9a4fcf7e 0.6
3fb41412e2492f66476d92ce8f007a8b48fb1d2a 0.7
cd15de32e173f8ce97bfe1c9b6607937b59056b4 0.8

View File

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

View File

@ -7,13 +7,13 @@ SRC = client.c draw.c event.c main.c tag.c util.c
OBJ = ${SRC:.c=.o}
all: options dwm
@echo finished
options:
@echo dwm build options:
@echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "CC = ${CC}"
@echo "LD = ${LD}"
.c.o:
@echo CC $<
@ -27,7 +27,7 @@ config.h:
dwm: ${OBJ}
@echo LD $@
@${CC} -o $@ ${OBJ} ${LDFLAGS}
@${LD} -o $@ ${OBJ} ${LDFLAGS}
@strip $@
clean:

View File

@ -24,7 +24,7 @@ resizetitle(Client *c)
c->tw = c->w + 2;
c->tx = c->x + c->w - c->tw + 2;
c->ty = c->y;
if(c->tags[tsel])
if(isvisible(c))
XMoveResizeWindow(dpy, c->title, c->tx, c->ty, c->tw, c->th);
else
XMoveResizeWindow(dpy, c->title, c->tx + 2 * sw, c->ty, c->tw, c->th);
@ -49,18 +49,17 @@ ban(Client *c)
void
focus(Client *c)
{
Client *old = sel;
if (!issel)
return;
Client *old = sel;
XEvent ev;
if(sel && sel->ismax)
togglemax(NULL);
sel = c;
if(old && old != c)
drawtitle(old);
drawtitle(c);
XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
@ -71,14 +70,11 @@ focusnext(Arg *arg)
if(!sel)
return;
if(sel->ismax)
togglemax(NULL);
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
higher(c);
focus(c);
restack();
}
}
@ -90,16 +86,13 @@ focusprev(Arg *arg)
if(!sel)
return;
if(sel->ismax)
togglemax(NULL);
if(!(c = getprev(sel->prev))) {
for(c = clients; c && c->next; c = c->next);
c = getprev(c);
}
if(c) {
higher(c);
focus(c);
restack();
}
}
@ -180,13 +173,6 @@ gravitate(Client *c, Bool invert)
c->y += dy;
}
void
higher(Client *c)
{
XRaiseWindow(dpy, c->win);
XRaiseWindow(dpy, c->title);
}
void
killclient(Arg *arg)
{
@ -242,27 +228,27 @@ manage(Window w, XWindowAttributes *wa)
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,
XGrabButton(dpy, Button1, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
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,
XGrabButton(dpy, Button2, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
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,
XGrabButton(dpy, Button3, MODKEY | numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY | NUMLOCKMASK | LockMask, c->win, False, BUTTONMASK,
XGrabButton(dpy, Button3, MODKEY | numlockmask | LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
settags(c);
@ -271,12 +257,13 @@ manage(Window w, XWindowAttributes *wa)
|| (c->maxw && c->minw &&
c->maxw == c->minw && c->maxh == c->minh);
settitle(c);
arrange(NULL);
/* mapping the window now prevents flicker */
XMapRaised(dpy, c->win);
XMapRaised(dpy, c->title);
if(c->tags[tsel])
if(isvisible(c))
sel = c;
arrange(NULL);
XMapWindow(dpy, c->win);
XMapWindow(dpy, c->title);
if(isvisible(c))
focus(c);
}
@ -410,8 +397,8 @@ togglemax(Arg *arg)
sel->w = sw - 2;
sel->h = sh - 2 - bh;
higher(sel);
resize(sel, False, TopLeft);
restack();
resize(sel, arrange == dofloat, TopLeft);
sel->x = ox;
sel->y = oy;
@ -438,22 +425,17 @@ unmanage(Client *c)
c->next->prev = c->prev;
if(c == clients)
clients = c->next;
if(sel == c) {
sel = getnext(c->next);
if(!sel)
sel = getprev(c->prev);
if(!sel)
sel = clients;
}
if(sel == c)
sel = getnext(clients);
free(c->tags);
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
arrange(NULL);
if(sel)
focus(sel);
arrange(NULL);
}
void
@ -461,7 +443,7 @@ zoom(Arg *arg)
{
Client *c;
if(!sel || (arrange != dotile) || sel->isfloat)
if(!sel || (arrange != dotile) || sel->isfloat || sel->ismax)
return;
if(sel == getnext(clients)) {
@ -472,15 +454,13 @@ zoom(Arg *arg)
}
/* pop */
if(sel->prev)
sel->prev->next = sel->next;
sel->prev->next = sel->next;
if(sel->next)
sel->next->prev = sel->prev;
sel->prev = NULL;
if(clients)
clients->prev = sel;
clients->prev = sel;
sel->next = clients;
clients = sel;
arrange(NULL);
focus(sel);
arrange(NULL);
}

View File

@ -9,40 +9,39 @@ const char *tags[] = { "work", "net", "fnord", NULL };
#define DEFMODE dotile /* dofloat */
#define DEFTAG 0 /* index */
#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
#define BGCOLOR "#eeeeee"
#define FGCOLOR "#666699"
#define BORDERCOLOR "#9999CC"
#define BGCOLOR "#0d121d"
#define FGCOLOR "#eeeeee"
#define BORDERCOLOR "#3f484d"
#define MODKEY Mod1Mask
#define NUMLOCKMASK Mod2Mask
#define MASTERW 60 /* percent */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
{ 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, \
/* modifier key function arguments */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec urxvt +sb -tr -bg black -fg '#eeeeee' -fn '"FONT"'" } }, \
{ 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_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, \
{ .cmd = "exec uxterm -bg '#dddddd' -fg '#000000' -cr '#000000' +sb " \
"-fn '-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*'" } }, \
{ MODKEY, XK_j, focusnext, { 0 } }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
};
#define RULES \

View File

@ -13,37 +13,39 @@ const char *tags[] = { "0", "1", "2", "3", "4", NULL };
#define FGCOLOR "#eeeeee"
#define BORDERCOLOR "#9999CC"
#define MODKEY Mod1Mask
#define NUMLOCKMASK Mod2Mask
#define MASTERW 60 /* percent */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
{ 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_space, togglemode, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ 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, { .cmd = "exec xterm" } }, \
/* modifier key function arguments */ \
{ MODKEY|ShiftMask, XK_Return, spawn, { .cmd = "exec xterm" } }, \
{ MODKEY, XK_Tab, focusnext, { 0 } }, \
{ MODKEY|ShiftMask, XK_Tab, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_m, togglemax, { 0 } }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 2 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 3 } }, \
{ MODKEY|ShiftMask, XK_4, tag, { .i = 4 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_0, toggletag, { .i = 0 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 1 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 2 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 3 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 4 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ 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|ControlMask, XK_0, toggleview, { .i = 0 } }, \
{ MODKEY|ControlMask, XK_1, toggleview, { .i = 1 } }, \
{ MODKEY|ControlMask, XK_2, toggleview, { .i = 2 } }, \
{ MODKEY|ControlMask, XK_3, toggleview, { .i = 3 } }, \
{ MODKEY|ControlMask, XK_4, toggleview, { .i = 4 } }, \
{ MODKEY|ShiftMask, XK_q, quit, { 0 } }, \
};
#define RULES \

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 0.8
VERSION = 0.9
# Customize below to fit your system
@ -20,5 +20,6 @@ LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# compiler
# compiler and linker
CC = cc
LD = ${CC}

53
draw.c
View File

@ -9,26 +9,6 @@
/* static */
static void
drawborder(void)
{
XPoint points[5];
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
XSetForeground(dpy, dc.gc, dc.border);
points[0].x = dc.x;
points[0].y = dc.y;
points[1].x = dc.w - 1;
points[1].y = 0;
points[2].x = 0;
points[2].y = dc.h - 1;
points[3].x = -(dc.w - 1);
points[3].y = 0;
points[4].x = 0;
points[4].y = -(dc.h - 1);
XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
}
static unsigned int
textnw(const char *text, unsigned int len)
{
@ -46,19 +26,32 @@ drawtext(const char *text, Bool invert)
{
int x, y, w, h;
static char buf[256];
unsigned int len;
unsigned int len, olen;
XGCValues gcv;
XPoint points[5];
XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XSetForeground(dpy, dc.gc, invert ? dc.fg : dc.bg);
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
drawborder();
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
XSetForeground(dpy, dc.gc, dc.border);
points[0].x = dc.x;
points[0].y = dc.y;
points[1].x = dc.w - 1;
points[1].y = 0;
points[2].x = 0;
points[2].y = dc.h - 1;
points[3].x = -(dc.w - 1);
points[3].y = 0;
points[4].x = 0;
points[4].y = -(dc.h - 1);
XDrawLines(dpy, dc.drawable, dc.gc, points, 5, CoordModePrevious);
if(!text)
return;
w = 0;
len = strlen(text);
olen = len = strlen(text);
if(len >= sizeof(buf))
len = sizeof(buf) - 1;
memcpy(buf, text, len);
@ -71,6 +64,14 @@ drawtext(const char *text, Bool invert)
/* shorten text if necessary */
while(len && (w = textnw(buf, len)) > dc.w - h)
buf[--len] = 0;
if(len < olen) {
if(len > 1)
buf[len - 1] = '.';
if(len > 2)
buf[len - 2] = '.';
if(len > 3)
buf[len - 3] = '.';
}
if(w > dc.w)
return; /* too long */
@ -116,9 +117,9 @@ drawstatus()
dc.x += dc.w;
dc.w = textw(tags[i]);
if(istile)
drawtext(tags[i], (i == tsel));
drawtext(tags[i], seltag[i]);
else
drawtext(tags[i], (i != tsel));
drawtext(tags[i], !seltag[i]);
}
x = dc.x + dc.w;
dc.w = textw(stext);
@ -159,7 +160,7 @@ drawtitle(Client *c)
}
}
dc.x += dc.w;
dc.w = textw(c->name);
dc.w = c->tw - dc.x;
drawtext(c->name, !istile);
XCopyArea(dpy, dc.drawable, c->title, dc.gc, 0, 0, c->tw, c->th, 0, 0);
XSync(dpy, False);

111
dwm.1
View File

@ -31,37 +31,61 @@ them displaying their tags and title.
.B \-v
prints version information to standard output, then exits.
.SH USAGE
.SS Status bar
.TP
.B Standard input
is read and displayed in the status text area.
.TP
.B Button1
click on a tag label views all windows with that
.BR tag .
.TP
.B Button3
click on a tag label adds/removes all windows with that
.B tag
to/from the view.
.SS Keyboard commands
.TP
.B Mod1-Shift-Return
Start
.BR xterm (1).
.TP
.B Mod1-Tab
Focus next
.BR window .
.TP
.B Mod1-Shift-Tab
Focus previous
.BR window .
.TP
.B Mod1-Return
Zoom current
.B window
to the
.B master
column.
.TP
.B Mod1-h
Focus previous
.B tag.
.TP
.B Mod1-j
Focus next
.B window.
.TP
.B Mod1-k
Focus previous
.B window.
.TP
.B Mod1-l
Focus next
.B tag.
column
.RB ( tiling
mode only).
.TP
.B Mod1-m
Maximize current
.B window.
.BR window .
.TP
.B Mod1-[0..n]
Focus
.B nth tag.
.B Mod1-Shift-[0..n]
Apply
.B nth tag
to current
.BR window .
.TP
.B Mod1-Control-Shift-[0..n]
Add/remove
.B nth tag
to/from current
.BR window .
.TP
.B Mod1-Shift-c
Close focused
.B window.
.TP
.B Mod1-space
Toggle between
@ -71,45 +95,54 @@ and
mode (affects
.BR "all windows" ).
.TP
.B Mod1-Shift-[0..n]
Apply
.B nth tag
to current
.B window.
.B Mod1-[0..n]
View all windows with
.BR "tag n" .
.TP
.B Mod1-Control-[0..n]
Add/remove all windows with
.B tag n
to/from the view.
.TP
.B Mod1-Shift-q
Quit
.B dwm.
.TP
.B Mod1-Shift-Return
Start
.B terminal.
.TP
.B Mod1-Control-[0..n]
Append
.B nth tag
to current
.B window.
.SS Mouse commands
.TP
.B Mod1-Button1
Move current
.B window
while dragging.
while dragging
.RB ( floating
mode only).
.TP
.B Mod1-Button2
Zoom current
.B window
to the
.B master
column.
column
.RB ( tiling
mode only).
.TP
.B Mod1-Button3
Resize current
.B window
while dragging.
while dragging
.RB ( floating
mode only).
.SH CUSTOMIZATION
.B dwm
is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.
.SH CAVEATS
The status bar displays
.B broken pipe
when
.B dwm
has been started by
.BR xdm (1),
because it closes standard output before executing
.BR dwm .
.SH SEE ALSO
.BR dmenu (1)

18
dwm.h
View File

@ -69,12 +69,12 @@ struct Client {
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 int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
extern unsigned int ntags, numlockmask;
extern void (*handler[LASTEvent])(XEvent *);
extern void (*arrange)(Arg *);
extern Atom wmatom[WMLast], netatom[NetLast];
extern Bool running, issel;
extern Bool running, issel, *seltag;
extern Client *clients, *sel;
extern Cursor cursor[CurLast];
extern DC dc;
@ -89,7 +89,6 @@ extern void focusprev(Arg *arg);
extern Client *getclient(Window w);
extern Client *getctitle(Window w);
extern void gravitate(Client *c, Bool invert);
extern void higher(Client *c);
extern void killclient(Arg *arg);
extern void manage(Window w, XWindowAttributes *wa);
extern void resize(Client *c, Bool sizehints, Corner sticky);
@ -109,6 +108,7 @@ extern unsigned int textw(const char *text);
/* event.c */
extern void grabkeys();
extern void procevent();
/* main.c */
extern int getproto(Window w);
@ -117,20 +117,22 @@ extern void sendevent(Window w, Atom a, long value);
extern int xerror(Display *dsply, XErrorEvent *ee);
/* tag.c */
extern void appendtag(Arg *arg);
extern void dofloat(Arg *arg);
extern void dotile(Arg *arg);
extern void initrregs();
extern Bool isvisible(Client *c);
extern Client *getnext(Client *c);
extern Client *getprev(Client *c);
extern void replacetag(Arg *arg);
extern void restack();
extern void settags(Client *c);
extern void tag(Arg *arg);
extern void togglemode(Arg *arg);
extern void toggletag(Arg *arg);
extern void toggleview(Arg *arg);
extern void view(Arg *arg);
extern void viewnext(Arg *arg);
extern void viewprev(Arg *arg);
/* util.c */
extern void *emallocz(unsigned int size);
extern void eprint(const char *errstr, ...);
extern void *erealloc(void *ptr, unsigned int size);
extern void spawn(Arg *arg);

View File

@ -4,6 +4,7 @@
<meta name="author" content="Anselm R. Garbe">
<meta name="generator" content="ed">
<meta name="copyright" content="(C)opyright 2006 by Anselm R. Garbe">
<link rel="dwm icon" href="favicon.ico" type="image/x-icon" />
<style type="text/css">
body {
color: #000000;
@ -55,7 +56,7 @@
depending on the application in use and the task performed.
</li>
<li>
dwm don't distinguishes between layers, there is no floating or
dwm doesn't distinguishes between layers, there is no floating or
tiled layer. Wether the clients of currently selected tag are in
tiled mode or not, you can re-arrange all clients on the fly.
Popup- and fixed-size windows are treated floating, however.
@ -103,8 +104,8 @@
</ul>
<h3>Download</h3>
<ul>
<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>
<li><a href="http://10kloc.org/download/dwm-0.9.tar.gz">dwm 0.9</a> (15kb) (20060815)</li>
<li><a href="http://10kloc.org/download/dmenu-0.4.tar.gz">dmenu 0.4</a> (7kb) (20060815)</li>
</ul>
<h3>Development</h3>
<p>

81
event.c
View File

@ -18,7 +18,7 @@ typedef struct {
KEYS
#define CLEANMASK(mask) (mask & ~(NUMLOCKMASK | LockMask))
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
static void
movemouse(Client *c)
@ -58,6 +58,7 @@ static void
resizemouse(Client *c)
{
int ocx, ocy;
int nw, nh;
Corner sticky;
XEvent ev;
@ -76,8 +77,10 @@ resizemouse(Client *c)
break;
case MotionNotify:
XSync(dpy, False);
c->w = abs(ocx - ev.xmotion.x);
c->h = abs(ocy - ev.xmotion.y);
if((nw = abs(ocx - ev.xmotion.x)))
c->w = abs(ocx - ev.xmotion.x);
if((nh = abs(ocy - ev.xmotion.y)))
c->h = abs(ocy - ev.xmotion.y);
c->x = (ocx <= ev.xmotion.x) ? ocx : ocx - c->w;
c->y = (ocy <= ev.xmotion.y) ? ocy : ocy - c->h;
if(ocx <= ev.xmotion.x)
@ -102,42 +105,37 @@ buttonpress(XEvent *e)
XButtonPressedEvent *ev = &e->xbutton;
if(barwin == ev->window) {
switch(ev->button) {
default:
x = 0;
for(a.i = 0; a.i < ntags; a.i++) {
x += textw(tags[a.i]);
if(ev->x < x) {
x = 0;
for(a.i = 0; a.i < ntags; a.i++) {
x += textw(tags[a.i]);
if(ev->x < x) {
if(ev->button == Button1)
view(&a);
break;
}
else if(ev->button == Button3)
toggleview(&a);
return;
}
break;
case Button4:
viewprev(&a);
break;
case Button5:
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))
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
restack(c);
movemouse(c);
}
break;
case Button2:
if(!c->ismax && arrange != dofloat && !c->isfloat)
zoom(NULL);
zoom(NULL);
break;
case Button3:
if(!c->ismax && (arrange == dofloat || c->isfloat))
if(!c->ismax && (arrange == dofloat || c->isfloat)) {
restack(c);
resizemouse(c);
}
break;
}
}
@ -146,11 +144,11 @@ buttonpress(XEvent *e)
static void
configurerequest(XEvent *e)
{
unsigned long newmask;
Client *c;
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XEvent synev;
XWindowChanges wc;
unsigned long newmask;
if((c = getclient(ev->window))) {
gravitate(c, True);
@ -256,13 +254,15 @@ keypress(XEvent *e)
XKeyEvent *ev = &e->xkey;
keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
for(i = 0; i < len; i++)
for(i = 0; i < len; i++) {
if(keysym == key[i].keysym &&
CLEANMASK(key[i].mod) == CLEANMASK(ev->state)) {
CLEANMASK(key[i].mod) == CLEANMASK(ev->state))
{
if(key[i].func)
key[i].func(&key[i].arg);
return;
}
}
}
static void
@ -276,6 +276,16 @@ leavenotify(XEvent *e)
}
}
static void
mappingnotify(XEvent *e)
{
XMappingEvent *ev = &e->xmapping;
XRefreshKeyboardMapping(ev);
if(ev->request == MappingKeyboard)
grabkeys();
}
static void
maprequest(XEvent *e)
{
@ -348,6 +358,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
[LeaveNotify] = leavenotify,
[Expose] = expose,
[KeyPress] = keypress,
[MappingNotify] = mappingnotify,
[MapRequest] = maprequest,
[PropertyNotify] = propertynotify,
[UnmapNotify] = unmapnotify
@ -360,15 +371,29 @@ grabkeys()
unsigned int i;
KeyCode code;
XUngrabKey(dpy, AnyKey, AnyModifier, root);
for(i = 0; i < len; i++) {
code = XKeysymToKeycode(dpy, key[i].keysym);
XGrabKey(dpy, code, key[i].mod, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | LockMask, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | NUMLOCKMASK, root, True,
XGrabKey(dpy, code, key[i].mod | numlockmask, root, True,
GrabModeAsync, GrabModeAsync);
XGrabKey(dpy, code, key[i].mod | NUMLOCKMASK | LockMask, root, True,
XGrabKey(dpy, code, key[i].mod | numlockmask | LockMask, root, True,
GrabModeAsync, GrabModeAsync);
}
}
void
procevent()
{
XEvent ev;
while(XPending(dpy)) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 198 B

63
main.c
View File

@ -11,6 +11,7 @@
#include <unistd.h>
#include <sys/select.h>
#include <X11/cursorfont.h>
#include <X11/keysym.h>
#include <X11/Xatom.h>
#include <X11/Xproto.h>
@ -26,7 +27,16 @@ cleanup()
resize(sel, True, TopLeft);
unmanage(sel);
}
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
else
XFreeFont(dpy, dc.font.xfont);
XUngrabKey(dpy, AnyKey, AnyModifier, root);
XDestroyWindow(dpy, barwin);
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
}
static void
@ -36,6 +46,7 @@ scan()
Window *wins, d1, d2;
XWindowAttributes wa;
wins = NULL;
if(XQueryTree(dpy, root, &d1, &d2, &wins, &num)) {
for(i = 0; i < num; i++) {
if(!XGetWindowAttributes(dpy, wins[i], &wa))
@ -83,9 +94,9 @@ xerrorstart(Display *dsply, XErrorEvent *ee)
/* extern */
char stext[1024];
int tsel = DEFTAG;
Bool *seltag;
int screen, sx, sy, sw, sh, bx, by, bw, bh, mw;
unsigned int ntags;
unsigned int ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
Bool issel = True;
@ -162,12 +173,12 @@ xerror(Display *dpy, XErrorEvent *ee)
int
main(int argc, char *argv[])
{
int i;
int i, j, xfd;
unsigned int mask;
fd_set rd;
Bool readin = True;
Window w;
XEvent ev;
XModifierKeymap *modmap;
XSetWindowAttributes wa;
if(argc == 2 && !strncmp("-v", argv[1], 3)) {
@ -181,6 +192,7 @@ main(int argc, char *argv[])
if(!dpy)
eprint("dwm: cannot open display\n");
xfd = ConnectionNumber(dpy);
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
@ -193,8 +205,10 @@ main(int argc, char *argv[])
if(otherwm)
eprint("dwm: another window manager is already running\n");
XSync(dpy, False);
XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False);
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
@ -209,10 +223,25 @@ main(int argc, char *argv[])
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++) {
for (j = 0; j < modmap->max_keypermod; j++) {
if(modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock))
numlockmask = (1 << i);
}
}
XFree(modmap);
wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
grabkeys();
initrregs();
for(ntags = 0; tags[ntags]; ntags++);
seltag = emallocz(sizeof(Bool) * ntags);
seltag[DEFTAG] = True;
/* style */
dc.bg = getcolor(BGCOLOR);
@ -225,13 +254,12 @@ main(int argc, char *argv[])
sh = DisplayHeight(dpy, screen);
mw = (sw * MASTERW) / 100;
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ButtonPressMask | ExposureMask;
bx = by = 0;
bw = sw;
dc.h = bh = dc.font.height + 4;
wa.override_redirect = 1;
wa.background_pixmap = ParentRelative;
wa.event_mask = ButtonPressMask | ExposureMask;
barwin = XCreateWindow(dpy, root, bx, by, bw, bh, 0, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
@ -246,33 +274,22 @@ main(int argc, char *argv[])
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
wa.event_mask = SubstructureRedirectMask | EnterWindowMask | LeaveWindowMask;
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
scan();
/* main event loop, also reads status text from stdin */
XSync(dpy, False);
procevent();
while(running) {
FD_ZERO(&rd);
if(readin)
FD_SET(STDIN_FILENO, &rd);
FD_SET(ConnectionNumber(dpy), &rd);
i = select(ConnectionNumber(dpy) + 1, &rd, 0, 0, 0);
FD_SET(xfd, &rd);
i = select(xfd + 1, &rd, NULL, NULL, NULL);
if(i == -1 && errno == EINTR)
continue;
if(i < 0)
eprint("select failed\n");
else if(i > 0) {
if(FD_ISSET(ConnectionNumber(dpy), &rd)) {
while(XPending(dpy)) {
XNextEvent(dpy, &ev);
if(handler[ev.type])
(handler[ev.type])(&ev); /* call handler */
}
}
if(readin && FD_ISSET(STDIN_FILENO, &rd)) {
readin = NULL != fgets(stext, sizeof(stext), stdin);
if(readin)
@ -282,8 +299,8 @@ main(int argc, char *argv[])
drawstatus();
}
}
procevent();
}
cleanup();
XCloseDisplay(dpy);

174
tag.c
View File

@ -34,16 +34,6 @@ void (*arrange)(Arg *) = DEFMODE;
/* extern */
void
appendtag(Arg *arg)
{
if(!sel)
return;
sel->tags[arg->i] = True;
arrange(NULL);
}
void
dofloat(Arg *arg)
{
@ -51,30 +41,31 @@ dofloat(Arg *arg)
for(c = clients; c; c = c->next) {
c->ismax = False;
if(c->tags[tsel]) {
if(isvisible(c)) {
resize(c, True, TopLeft);
}
else
ban(c);
}
if((sel = getnext(clients))) {
higher(sel);
if(!sel || !isvisible(sel))
sel = getnext(clients);
if(sel) {
focus(sel);
restack();
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
drawall();
}
void
dotile(Arg *arg)
{
int n, i, w, h;
int h, i, n, w;
Client *c;
w = sw - mw;
for(n = 0, c = clients; c; c = c->next)
if(c->tags[tsel] && !c->isfloat)
if(isvisible(c) && !c->isfloat)
n++;
if(n > 1)
@ -84,9 +75,8 @@ dotile(Arg *arg)
for(i = 0, c = clients; c; c = c->next) {
c->ismax = False;
if(c->tags[tsel]) {
if(isvisible(c)) {
if(c->isfloat) {
higher(c);
resize(c, True, TopLeft);
continue;
}
@ -123,26 +113,26 @@ dotile(Arg *arg)
else
ban(c);
}
if((sel = getnext(clients))) {
higher(sel);
if(!sel || !isvisible(sel))
sel = getnext(clients);
if(sel)
focus(sel);
}
else
XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
drawall();
restack();
}
Client *
getnext(Client *c)
{
for(; c && !c->tags[tsel]; c = c->next);
for(; c && !isvisible(c); c = c->next);
return c;
}
Client *
getprev(Client *c)
{
for(; c && !c->tags[tsel]; c = c->prev);
for(; c && !isvisible(c); c = c->prev);
return c;
}
@ -175,17 +165,67 @@ initrregs()
}
}
void
replacetag(Arg *arg)
Bool
isvisible(Client *c)
{
int i;
if(!sel)
return;
unsigned int i;
for(i = 0; i < ntags; i++)
sel->tags[i] = False;
appendtag(arg);
if(c->tags[i] && seltag[i])
return True;
return False;
}
void
restack()
{
static unsigned int nwins = 0;
static Window *wins = NULL;
unsigned int f, fi, m, mi, n;
Client *c;
XEvent ev;
for(f = 0, m = 0, c = clients; c; c = c->next)
if(isvisible(c)) {
if(c->isfloat || arrange == dofloat)
f++;
else
m++;
}
if(!(n = 2 * (f + m))) {
drawstatus();
return;
}
if(nwins < n) {
nwins = n;
wins = erealloc(wins, nwins * sizeof(Window));
}
fi = 0;
mi = 2 * f;
if(sel->isfloat || arrange == dofloat) {
wins[fi++] = sel->title;
wins[fi++] = sel->win;
}
else {
wins[mi++] = sel->title;
wins[mi++] = sel->win;
}
for(c = clients; c; c = c->next)
if(isvisible(c) && c != sel) {
if(c->isfloat || arrange == dofloat) {
wins[fi++] = c->title;
wins[fi++] = c->win;
}
else {
wins[mi++] = c->title;
wins[mi++] = c->win;
}
}
XRestackWindows(dpy, wins, n);
drawall();
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
@ -217,7 +257,24 @@ settags(Client *c)
XFree(ch.res_name);
}
if(!matched)
c->tags[tsel] = True;
for(i = 0; i < ntags; i++)
c->tags[i] = seltag[i];
}
void
tag(Arg *arg)
{
unsigned int i;
if(!sel)
return;
for(i = 0; i < ntags; i++)
sel->tags[i] = False;
sel->tags[arg->i] = True;
settitle(sel);
if(!isvisible(sel))
arrange(NULL);
}
void
@ -227,24 +284,43 @@ togglemode(Arg *arg)
arrange(NULL);
}
void
toggletag(Arg *arg)
{
unsigned int i;
if(!sel)
return;
sel->tags[arg->i] = !sel->tags[arg->i];
for(i = 0; i < ntags && !sel->tags[i]; i++);
if(i == ntags)
sel->tags[arg->i] = True;
settitle(sel);
if(!isvisible(sel))
arrange(NULL);
}
void
toggleview(Arg *arg)
{
unsigned int i;
seltag[arg->i] = !seltag[arg->i];
for(i = 0; i < ntags && !seltag[i]; i++);
if(i == ntags)
seltag[arg->i] = True; /* cannot toggle last view */
arrange(NULL);
}
void
view(Arg *arg)
{
tsel = arg->i;
unsigned int i;
for(i = 0; i < ntags; i++)
seltag[i] = False;
seltag[arg->i] = True;
arrange(NULL);
drawall();
}
void
viewnext(Arg *arg)
{
arg->i = (tsel < ntags-1) ? tsel+1 : 0;
view(arg);
}
void
viewprev(Arg *arg)
{
arg->i = (tsel > 0) ? tsel-1 : ntags-1;
view(arg);
}

9
util.c
View File

@ -40,6 +40,15 @@ eprint(const char *errstr, ...)
exit(EXIT_FAILURE);
}
void *
erealloc(void *ptr, unsigned int size)
{
void *res = realloc(ptr, size);
if(!res)
bad_malloc(size);
return res;
}
void
spawn(Arg *arg)
{