Compare commits

...

108 Commits
1.8 ... 2.7

Author SHA1 Message Date
c7da124149 applied Sanders patch 2006-12-13 14:15:38 +01:00
21bd90d7d3 fixed man page, status bar displays EOF instead of "broken pipe" 2006-12-13 13:53:10 +01:00
c8f96b5b4c added the java odyssee to CAVEATS section 2006-12-13 13:42:17 +01:00
ded60365d4 removed Client->grav 2006-12-12 19:14:38 +01:00
629647dfee removed gravitate for the moment 2006-12-11 16:45:02 +01:00
4ca3d861f0 disabling configure() during resize 2006-12-11 09:42:16 +01:00
069e7a6e24 made gravitate effectless, waiting for complains ;) 2006-12-11 08:31:30 +01:00
ac6e34ea06 fixed diagnostic error message 2006-12-08 11:11:52 +01:00
a308b7507a removed the hardcoded fixed fallback, it is useless in non-Latin1 environments 2006-12-08 10:40:09 +01:00
630e7ff26f we don't use the term clients anymore, windows is the better term 2006-12-07 16:38:57 +01:00
3764ab471b Added tag 2.6 for changeset 5308dd22b6ee8e3218c81d9e7e4125f235bb5778 2006-12-07 14:55:29 +01:00
a3319c6f8e found compromise for fonts 2006-12-07 14:39:31 +01:00
66c699a701 nah, people should define 'fixed' to be compatible with their locale 2006-12-07 12:03:15 +01:00
aaf1e44da9 using a UTF-8 capable fixed font 2006-12-07 11:55:04 +01:00
1ef2307ec4 switching to uxterm again, I get kretze from this urxvt crap 2006-12-07 10:43:34 +01:00
d42c3ba2dc with this patch everything works fine for me 2006-12-07 10:02:46 +01:00
4b06155873 don't use Xlocale crap, let's use locale.h instead 2006-12-07 09:49:45 +01:00
857d825eeb using the portable Xmb+UTF-8 way of life, will see if this works well... 2006-12-07 09:47:55 +01:00
6b345353e3 improved the memory leak prevention 2006-12-06 11:19:06 +01:00
ab3b3a8f61 making terminus more explicit a regular font (otherwise olique font might be used in some setups like mine). 2006-12-05 14:21:18 +01:00
71b82fb1f6 also setting LC_CTYPE only 2006-12-05 13:31:29 +01:00
9bd9ea423e enforcing using fontsets even if they are incomplete for some encodings 2006-12-05 10:30:31 +01:00
99964398e7 Added tag 2.5.1 for changeset c7f84f23ec5aef29988dcdc4ec22a7352ee8f58e 2006-12-04 21:01:14 +01:00
7009ebfa69 hotfix of a serious crashing bug 2006-12-04 21:00:26 +01:00
760e23dd3a Added tag 2.5 for changeset dcbbfabc8ecc5f33a6cc950584de87da1a368045 2006-12-04 15:39:43 +01:00
c53d9d516a applied Manuel's regex patch 2006-12-03 11:21:25 +01:00
7739e6b466 made squares equally sized, and 1px bigger 2006-12-01 17:55:46 +01:00
4881857458 if client is focused, the emptysquare don't needs to be drawed 2006-12-01 17:51:05 +01:00
c73d5cb7b6 and the winner is 2006-12-01 17:45:27 +01:00
6458803d21 sander1 proposal 2006-12-01 17:36:37 +01:00
6e72d781f7 dood 2006-12-01 16:55:42 +01:00
4e926a9ef2 darkening the fg colors somewhat 2006-12-01 15:50:22 +01:00
4ba3cfaee9 less obtrusive indicator (only a top line) 2006-12-01 15:03:42 +01:00
e655e8a7d5 final2 indicator 2006-12-01 12:52:16 +01:00
c34e4e4b39 removing the -1 on final indicators, looks cleaner 2006-12-01 12:39:13 +01:00
a678ee6365 final indicators 2006-12-01 12:25:23 +01:00
49f0ee329d changed things like I described in last mail 2006-12-01 10:16:10 +01:00
0c9d9a3d94 improved tag indicator 2006-12-01 09:52:15 +01:00
89e1acb0bb removed viewall signature from dwm.h 2006-11-30 17:01:39 +01:00
c2ed26b711 next version will be 2.5 2006-11-30 15:51:26 +01:00
42fd392e05 removed viewall(), replaced with view(-1); added tag(-1) to tag a client with all tags (new key combo MODKEY-Shift-0) 2006-11-30 15:27:43 +01:00
e06447ee88 Added tag 2.4 for changeset 32b246925086910d63147483160281a91a47479f 2006-11-30 09:19:52 +01:00
683dabe5e6 extended dwm.1 with last change 2006-11-28 17:36:00 +01:00
3aff96177c togglefloat should only work in dotile mode (thanks to Sander for this hint) 2006-11-28 17:35:31 +01:00
0a915eba8f applied Alex Elide's tricky patch, thanks! 2006-11-27 17:51:50 +01:00
19dcbc5717 returning to old Key struct 2006-11-27 17:49:58 +01:00
d2a4952956 applied Szabolcs Nagy's patch (thank you!) 2006-11-27 17:46:02 +01:00
0c97b21b61 applied patch by Jukka 2006-11-27 17:30:06 +01:00
19390b1a91 changing Key.func into Key.func[NFUNCS], this allows sequences execution of functions per keypress (avoids implementing useless masterfunctions which call atomic ones) 2006-11-27 13:21:38 +01:00
8dc86051df added man page entry 2006-11-27 11:05:47 +01:00
46d5f9d1bf added togglefloat to hg tip (i consider this useful for some cases), using MODKEY-Shift-space as shortcut 2006-11-27 10:57:37 +01:00
35e96b8deb applied Jukka's patch preventing some cornercases and making the EOF error message correct 2006-11-27 10:29:47 +01:00
2210ea7e3b applied yet another proposal of Manuel 2006-11-26 15:43:16 +01:00
61a1910f91 applied Jukka's sizeof K&R compliance patch, applied Manuels' last-line printage proposal for stdin reading. 2006-11-26 14:26:53 +01:00
27ef73507b applied Jukka's stdinread patch 2006-11-26 13:31:36 +01:00
2b35fb643e next version will be 2.4 2006-11-25 19:26:31 +01:00
478f6f95f1 applied Manuels patch (thanks to Manuel!) 2006-11-25 19:26:16 +01:00
44411d2d48 small fix of man page 2006-11-24 17:02:41 +01:00
a2175cf71a Added tag 2.3 for changeset 719b37b37b0df829d7cf017ac70e353088fe5849 2006-11-24 15:46:32 +01:00
4606d218c3 using the term 'indicated' instead of 'higlighted' 2006-11-23 16:00:16 +01:00
d37d0f24e6 updated man page with the bottom right corner indicator 2006-11-23 15:59:16 +01:00
321e8d51ed fififif 2006-11-22 16:17:50 +01:00
78f4b51757 added a similiar patch to Daves solution to indicate if there are clients with a specific tag 2006-11-22 14:57:09 +01:00
7d168a2621 returning to old bar colorization behavior, like sander proposed for consistency reasons 2006-11-21 15:03:08 +01:00
931e712eac applied Gottox patches 2006-11-21 14:49:13 +01:00
4ec04209e0 using iso10646 explicitely in arg's config.h 2006-11-21 12:17:47 +01:00
82ddba88a2 Added tag 2.2 for changeset 7e92f58754ae6edb3225f26d754bd89c1ff458cf 2006-11-21 09:41:33 +01:00
52a8cc8d46 nah reverting to my prev style, that's really the best 2006-11-18 21:33:33 +01:00
d175df8aa3 applying aluminium style for arg's config.h 2006-11-18 21:26:53 +01:00
b003a35fde applied Gottox' windowarea patch 2006-11-16 14:40:57 +01:00
df1a0f9445 using a more blue-ish color... 2006-11-08 17:16:38 +01:00
5b07b85838 making the selected color more lightning 2006-11-08 17:10:51 +01:00
f320cd203b next release will be 2.2 2006-11-03 09:22:40 +01:00
f78c16f8c6 applied Jukkas patch 2006-11-03 08:29:39 +01:00
0c5f47e720 Added tag 2.1 for changeset a2c465098a3b972bbed00feda9804b6aae1e9531 2006-11-02 10:18:22 +01:00
4b5b3d90af renamed resizecol into resizemaster 2006-10-31 12:07:32 +01:00
2cce4b95cd applied Gottox patch to simplify the resizing of col, instead of resizing the current area, it only resizes the master area in the future (seems more predictable) 2006-10-31 12:06:38 +01:00
8e6eb52196 Added tag 2.0 for changeset 12deea36603da407e3f32640048846a3bd74a9ec 2006-10-31 09:02:42 +01:00
04b633ddf3 make sure that changing sx has no impact on snapping 2006-10-31 09:02:16 +01:00
b76561a212 in a 1920x1200 setup 40 pixels of snap value are much better than 20 2006-10-30 12:40:10 +01:00
51c7589c87 fixed stupid bug of snap-to-screen 2006-10-30 12:26:55 +01:00
99785382ae changing snap priority 2006-10-30 12:07:00 +01:00
dc1690ce0f removed useless abs() calls 2006-10-30 12:04:08 +01:00
b6614261ea added screen-border snapping in floating mode, feels quite well 2006-10-30 11:58:05 +01:00
91e569ca37 and another fix 2006-10-27 13:29:35 +02:00
0f395c1b11 applied sanders try2 patch 2006-10-27 13:28:26 +02:00
2b13e7466f applied sanders max size fix 2006-10-27 12:05:47 +02:00
0982e47408 stupid urxvt needs bg to highlight selections in a sane way, though that makes sense to some extend 2006-10-27 10:24:15 +02:00
b93ebcf42f reverting to original 2006-10-26 15:41:40 +02:00
a08d83ba62 applied sander's config.*h nitpick patch 2006-10-26 15:29:20 +02:00
2b7c275ce8 some other change 2006-10-26 15:26:17 +02:00
040d0f48a0 apply small fix to prevent apps like mplayer wandering when toggling fullscreen 2006-10-26 15:05:45 +02:00
724f35a664 forgot to use -tr, which actually prevents the ugly flicker (using xsetroot -solid black as root window pixmap to make this work nicely) 2006-10-26 12:22:26 +02:00
6f3872edbd using MASTER 600 again, it is definately better, and using urxvtc for the moment (it doesn't flickers on refreshes, but this is not because of Marc Lehmann, it is because of the original rxvt code) 2006-10-26 12:13:41 +02:00
87324e680c changing MASTER in config.arg.h from 600 to 550 per thousand 2006-10-26 11:21:45 +02:00
c2b908f603 my new 1920x1200 Z61p arrived, now I can use terminus in a sane way... 2006-10-26 10:21:27 +02:00
d7734f996f moved MOUSEMASK into event.c (not used in other places) 2006-10-16 16:50:03 +02:00
8b68890650 now being at v2.0 2006-10-14 18:21:39 +02:00
b60406cb9b using lsx instead of Jukka's shell construct 2006-10-13 18:47:24 +02:00
ce9a9934ec hotfix 2006-10-06 14:01:53 +02:00
720b2abe17 Added tag 1.9 for changeset a5567a0d30112822db2627a04a2e7aa3b6c38148 2006-10-06 13:43:59 +02:00
5983c00b95 do* has no Arg arument anymore (never called directly) 2006-10-06 13:06:37 +02:00
6651dd7fd9 code polishing, removed unnecessary newlines 2006-10-06 11:50:15 +02:00
acdea31916 yet another small fix and simplification of dotile 2006-10-06 11:37:12 +02:00
10885d349a removed the stack position stuff 2006-10-05 19:27:28 +02:00
1c1d09f3e9 small boundary check fix 2006-10-05 18:23:28 +02:00
0384faeee5 changing MASTER value from percent into per mill 2006-10-05 18:18:47 +02:00
6cca3999c8 Added tag 1.8 for changeset c71952fa3c7ca848ec38a6923b5c6d0e18fff431 2006-10-05 19:00:58 +02:00
13 changed files with 264 additions and 438 deletions

10
.hgtags
View File

@ -16,3 +16,13 @@ f5f5cbf016a94b48a8fe9c47f0736e96d166d5d4 1.3
ad3fa2d185426c51fd5deceae809770363f8d33c 1.6
4dbdb61c8b8ce21dee5c7050a6b103855964ed20 1.7
d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 1.7.1
c71952fa3c7ca848ec38a6923b5c6d0e18fff431 1.8
a5567a0d30112822db2627a04a2e7aa3b6c38148 1.9
12deea36603da407e3f32640048846a3bd74a9ec 2.0
a2c465098a3b972bbed00feda9804b6aae1e9531 2.1
7e92f58754ae6edb3225f26d754bd89c1ff458cf 2.2
719b37b37b0df829d7cf017ac70e353088fe5849 2.3
32b246925086910d63147483160281a91a47479f 2.4
dcbbfabc8ecc5f33a6cc950584de87da1a368045 2.5
c7f84f23ec5aef29988dcdc4ec22a7352ee8f58e 2.5.1
5308dd22b6ee8e3218c81d9e7e4125f235bb5778 2.6

View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@ -132,60 +131,6 @@ getctitle(Window w) {
return NULL;
}
void
gravitate(Client *c, Bool invert) {
int dx = 0, dy = 0;
switch(c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case NorthGravity:
case NorthEastGravity:
dy = c->border;
break;
case EastGravity:
case CenterGravity:
case WestGravity:
dy = -(c->h / 2) + c->border;
break;
case SouthEastGravity:
case SouthGravity:
case SouthWestGravity:
dy = -(c->h);
break;
}
switch (c->grav) {
default:
break;
case StaticGravity:
case NorthWestGravity:
case WestGravity:
case SouthWestGravity:
dx = c->border;
break;
case NorthGravity:
case CenterGravity:
case SouthGravity:
dx = -(c->w / 2) + c->border;
break;
case NorthEastGravity:
case EastGravity:
case SouthEastGravity:
dx = -(c->w + c->border);
break;
}
if(invert) {
dx = -dx;
dy = -dy;
}
c->x += dx;
c->y += dy;
}
void
killclient(Arg *arg) {
if(!sel)
@ -205,15 +150,13 @@ manage(Window w, XWindowAttributes *wa) {
c = emallocz(sizeof(Client));
c->tags = emallocz(ntags * sizeof(Bool));
c->win = w;
c->border = 0;
c->x = c->tx = wa->x;
c->y = c->ty = wa->y;
c->w = c->tw = wa->width;
c->h = wa->height;
c->th = bh;
c->border = 0;
updatesize(c);
if(c->x + c->w + 2 * BORDERPX > sw)
c->x = sw - c->w - 2 * BORDERPX;
if(c->x < sx)
@ -222,7 +165,6 @@ manage(Window w, XWindowAttributes *wa) {
c->y = sh - c->h - 2 * BORDERPX;
if(c->h != sh && c->y < bh)
c->y = bh;
c->proto = getproto(c->win);
XSelectInput(dpy, c->win,
StructureNotifyMask | PropertyChangeMask | EnterWindowMask);
@ -230,33 +172,27 @@ manage(Window w, XWindowAttributes *wa) {
twa.override_redirect = 1;
twa.background_pixmap = ParentRelative;
twa.event_mask = ExposureMask | EnterWindowMask;
c->twin = XCreateWindow(dpy, root, c->tx, c->ty, c->tw, c->th,
0, DefaultDepth(dpy, screen), CopyFromParent,
DefaultVisual(dpy, screen),
CWOverrideRedirect | CWBackPixmap | CWEventMask, &twa);
grabbuttons(c, False);
updatetitle(c);
settags(c, getclient(trans));
if(!c->isfloat)
c->isfloat = trans
|| (c->maxw && c->minw &&
c->maxw == c->minw && c->maxh == c->minh);
c->isfloat = trans || c->isfixed;
resizetitle(c);
if(clients)
clients->prev = c;
c->next = clients;
c->snext = stack;
stack = clients = c;
ban(c);
XMapWindow(dpy, c->win);
XMapWindow(dpy, c->twin);
if(isvisible(c))
focus(c);
arrange(NULL);
arrange();
}
void
@ -283,7 +219,6 @@ resize(Client *c, Bool sizehints, Corner sticky) {
c->x = right - c->w;
if(sticky == BotLeft || sticky == BotRight)
c->y = bottom - c->h;
/* offscreen appearance fixes */
if(c->x + c->w < sx)
c->x = sx;
@ -293,7 +228,6 @@ resize(Client *c, Bool sizehints, Corner sticky) {
c->x = sw - c->w;
if(c->y > sh)
c->y = sh - c->h;
resizetitle(c);
wc.x = c->x;
wc.y = c->y;
@ -353,10 +287,8 @@ updatesize(Client *c) {
}
else
c->minw = c->minh = 0;
if(c->flags & PWinGravity)
c->grav = size.win_gravity;
else
c->grav = NorthWestGravity;
c->isfixed = (c->maxw && c->minw && c->maxh && c->minh &&
c->maxw == c->minw && c->maxh == c->minh);
}
void
@ -373,12 +305,12 @@ updatetitle(Client *c) {
if(!name.nitems)
return;
if(name.encoding == XA_STRING)
strncpy(c->name, (char *)name.value, sizeof(c->name));
strncpy(c->name, (char *)name.value, sizeof c->name);
else {
if(XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success
&& n > 0 && *list)
{
strncpy(c->name, *list, sizeof(c->name));
strncpy(c->name, *list, sizeof c->name);
XFreeStringList(list);
}
}
@ -392,22 +324,18 @@ unmanage(Client *c) {
/* The server grab construct avoids race conditions. */
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);
detach(c);
detachstack(c);
if(sel == c) {
for(nc = stack; nc && !isvisible(nc); nc = nc->snext);
focus(nc);
}
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
XDestroyWindow(dpy, c->twin);
free(c->tags);
free(c);
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
arrange(NULL);
arrange();
}

View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
@ -8,37 +7,35 @@ const char *tags[] = { "dev", "work", "net", "fnord", NULL };
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define STACKPOS StackRight /* StackLeft */
#define BSTACKSYMBOL "==="
#define VSTACKSYMBOL "[]="
#define TILESYMBOL "[]="
#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
#define FONT "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*"
#define NORMBGCOLOR "#333333"
#define NORMFGCOLOR "#dddddd"
#define SELBGCOLOR "#333366"
#define SELFGCOLOR "#eeeeee"
#define NORMFGCOLOR "#cccccc"
#define SELBGCOLOR "#336699"
#define SELFGCOLOR "#dddddd"
#define STATUSBGCOLOR "#222222"
#define STATUSFGCOLOR "#9999cc"
#define STATUSFGCOLOR "#99ccff"
#define MASTER 60 /* percent */
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define SNAP 40 /* pixel */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
/* modifier key function argument */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec uxterm -bg '#111111' -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
{ .cmd = "exec uxterm -bg black -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
{ MODKEY, XK_p, spawn, \
{ .cmd = "exe=\"$(IFS=:; for dir in $PATH; do " \
"for file in \"$dir\"/*; do [ -x \"$file\" ] && echo \"${file##*/}\"; done; done " \
"| sort -u | dmenu -font '"FONT"' -normbg '"NORMBGCOLOR"' -normfg '"NORMFGCOLOR"' " \
"-selbg '"SELBGCOLOR"' -selfg '"SELFGCOLOR"')\" && exec $exe" } }, \
{ .cmd = "exe=\"$(lsx `echo $PATH | sed 's/:/ /g'` | sort -u " \
" | dmenu -font '"FONT"' -normbg '"NORMBGCOLOR"' -normfg '"NORMFGCOLOR"' " \
"-selbg '"SELBGCOLOR"' -selfg '"SELFGCOLOR"')\" && exec $exe" } }, \
{ MODKEY, XK_j, focusnext, { 0 } }, \
{ MODKEY, XK_k, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_b, togglestackpos, { 0 } }, \
{ MODKEY, XK_g, resizecol, { .i = 1 } }, \
{ MODKEY, XK_s, resizecol, { .i = -1 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
@ -49,7 +46,8 @@ static Key key[] = { \
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_0, viewall, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \
@ -64,8 +62,8 @@ static Key key[] = { \
#define RULES \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "net", False}, \
{ "Gimp.*", NULL, True}, \
{ "MPlayer.*", NULL, True}, \
{ "Acroread.*", NULL, True}, \
{ "Firefox.*", "net", False }, \
{ "Gimp.*", NULL, True }, \
{ "MPlayer.*", NULL, True }, \
{ "Acroread.*", NULL, True }, \
};

View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
@ -8,11 +7,9 @@ const char *tags[] = { "1", "2", "3", "4", "5", NULL };
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define STACKPOS StackRight /* StackLeft */
#define BSTACKSYMBOL "==="
#define VSTACKSYMBOL "[]="
#define TILESYMBOL "[]="
#define FONT "fixed"
#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
#define NORMBGCOLOR "#333366"
#define NORMFGCOLOR "#cccccc"
#define SELBGCOLOR "#666699"
@ -20,19 +17,20 @@ const char *tags[] = { "1", "2", "3", "4", "5", NULL };
#define STATUSBGCOLOR "#dddddd"
#define STATUSFGCOLOR "#222222"
#define MASTER 60 /* percent */
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define SNAP 20 /* pixel */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
/* modifier key function argument */ \
{ 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_b, togglestackpos, { 0 } }, \
{ MODKEY, XK_g, resizecol, { .i = 1 } }, \
{ MODKEY, XK_s, resizecol, { .i = -1 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY|ShiftMask, XK_0, tag, { .i = -1 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
@ -45,7 +43,8 @@ static Key key[] = { \
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_0, viewall, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \
{ MODKEY, XK_2, view, { .i = 1 } }, \
{ MODKEY, XK_3, view, { .i = 2 } }, \
@ -65,5 +64,5 @@ static Key key[] = { \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "2", False }, \
{ "Gimp.*", NULL, True}, \
{ "Gimp.*", NULL, True }, \
};

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 1.8
VERSION = 2.7
# Customize below to fit your system

87
draw.c
View File

@ -1,14 +1,22 @@
/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <stdio.h>
#include <string.h>
#include <X11/Xlocale.h>
/* static */
static Bool
isoccupied(unsigned int t)
{
Client *c;
for(c = clients; c; c = c->next)
if(c->tags[t])
return True;
return False;
}
static unsigned int
textnw(const char *text, unsigned int len) {
XRectangle r;
@ -21,30 +29,27 @@ textnw(const char *text, unsigned int len) {
}
static void
drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
drawtext(const char *text, unsigned long col[ColLast], Bool filledsquare, Bool emptysquare) {
int x, y, w, h;
static char buf[256];
unsigned int len, olen;
XGCValues gcv;
XRectangle r = { dc.x, dc.y, dc.w, dc.h };
XPoint pt[5];
XSetForeground(dpy, dc.gc, col[ColBG]);
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
if(!text)
return;
w = 0;
olen = len = strlen(text);
if(len >= sizeof(buf))
len = sizeof(buf) - 1;
if(len >= sizeof buf)
len = sizeof buf - 1;
memcpy(buf, text, len);
buf[len] = 0;
h = dc.font.ascent + dc.font.descent;
y = dc.y + (dc.h / 2) - (h / 2) + dc.font.ascent;
x = dc.x + (h / 2);
/* shorten text if necessary */
while(len && (w = textnw(buf, len)) > dc.w - h)
buf[--len] = 0;
@ -56,7 +61,6 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
if(len > 3)
buf[len - 3] = '.';
}
if(w > dc.w)
return; /* too long */
gcv.foreground = col[ColFG];
@ -69,12 +73,26 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
XChangeGC(dpy, dc.gc, GCForeground | GCFont, &gcv);
XDrawString(dpy, dc.drawable, dc.gc, x, y, buf, len);
}
if(highlight) {
r.x = dc.x + 2;
r.y = dc.y + 2;
r.width = r.height = (h + 2) / 4;
x = (h + 2) / 4;
if(filledsquare) {
r.x = dc.x + 1;
r.y = dc.y + 1;
r.width = r.height = x + 1;
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
}
else if(emptysquare) {
pt[0].x = dc.x + 1;
pt[0].y = dc.y + 1;
pt[1].x = x;
pt[1].y = 0;
pt[2].x = 0;
pt[2].y = x;
pt[3].x = -x;
pt[3].y = 0;
pt[4].x = 0;
pt[4].y = -x;
XDrawLines(dpy, dc.drawable, dc.gc, pt, 5, CoordModePrevious);
}
}
/* extern */
@ -93,36 +111,27 @@ drawstatus(void) {
int i, x;
dc.x = dc.y = 0;
for(i = 0; i < ntags; i++) {
dc.w = textw(tags[i]);
if(seltag[i])
drawtext(tags[i], dc.sel, sel && sel->tags[i]);
drawtext(tags[i], dc.sel, sel && sel->tags[i], isoccupied(i));
else
drawtext(tags[i], dc.norm, sel && sel->tags[i]);
drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i));
dc.x += dc.w;
}
dc.w = bmw;
drawtext(arrange == dofloat ?
FLOATSYMBOL : stackpos == StackBottom ?
BSTACKSYMBOL : VSTACKSYMBOL, dc.status, False);
drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False, False);
x = dc.x + dc.w;
dc.w = textw(stext);
dc.x = bx + bw - dc.w;
dc.x = bw - dc.w;
if(dc.x < x) {
dc.x = x;
dc.w = bw - x;
}
drawtext(stext, dc.status, False);
drawtext(stext, dc.status, False, False);
if((dc.w = dc.x - x) > bh) {
dc.x = x;
if(sel)
drawtext(sel->name, dc.sel, False);
else
drawtext(NULL, dc.norm, False);
drawtext(sel ? sel->name : NULL, sel ? dc.sel : dc.norm, False, False);
}
XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0);
XSync(dpy, False);
@ -136,12 +145,11 @@ drawtitle(Client *c) {
XSetWindowBorder(dpy, c->win, dc.sel[ColBG]);
return;
}
XSetWindowBorder(dpy, c->win, dc.norm[ColBG]);
XMapWindow(dpy, c->twin);
dc.x = dc.y = 0;
dc.w = c->tw;
drawtext(c->name, dc.norm, False);
drawtext(c->name, dc.norm, False,False);
XCopyArea(dpy, dc.drawable, c->twin, dc.gc, 0, 0, c->tw, c->th, 0, 0);
XSync(dpy, False);
}
@ -158,11 +166,10 @@ getcolor(const char *colstr) {
void
setfont(const char *fontstr) {
char **missing, *def;
char *def, **missing;
int i, n;
missing = NULL;
setlocale(LC_ALL, "");
if(dc.font.set)
XFreeFontSet(dpy, dc.font.set);
dc.font.set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
@ -170,16 +177,11 @@ setfont(const char *fontstr) {
while(n--)
fprintf(stderr, "missing fontset: %s\n", missing[n]);
XFreeStringList(missing);
if(dc.font.set) {
XFreeFontSet(dpy, dc.font.set);
dc.font.set = NULL;
}
}
if(dc.font.set) {
XFontSetExtents *font_extents;
XFontStruct **xfonts;
char **font_names;
dc.font.ascent = dc.font.descent = 0;
font_extents = XExtentsOfFontSet(dc.font.set);
n = XFontsOfFontSet(dc.font.set, &xfonts, &font_names);
@ -195,11 +197,8 @@ setfont(const char *fontstr) {
if(dc.font.xfont)
XFreeFont(dpy, dc.font.xfont);
dc.font.xfont = NULL;
dc.font.xfont = XLoadQueryFont(dpy, fontstr);
if (!dc.font.xfont)
dc.font.xfont = XLoadQueryFont(dpy, "fixed");
if (!dc.font.xfont)
eprint("error, cannot init 'fixed' font\n");
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)))
eprint("error, cannot load font: '%s'\n", fontstr);
dc.font.ascent = dc.font.xfont->ascent;
dc.font.descent = dc.font.xfont->descent;
}

36
dwm.1
View File

@ -20,8 +20,10 @@ tags. Selecting certain tags displays all windows with these tags.
.P
dwm contains a small status bar which displays all available tags, the mode,
the title of the focused window, and the text read from standard input. The
selected tags are highlighted with a different color, the tags of the focused
window are highlighted with a small point.
selected tags are indicated with a different color. The tags of the focused
window are indicated with a filled square in the top left corner. The tags
which are applied to one or more windows are indicated with an empty square in
the top left corner.
.P
dwm draws a 1-pixel border around windows to indicate the focus state.
Unfocused windows contain a small bar in front of them displaying their title.
@ -40,8 +42,7 @@ click on a tag label to display all windows with that tag, click on the mode
label toggles between tiling and floating mode.
.TP
.B Button3
click on a tag label adds/removes all windows with that tag to/from the view,
click on the mode label toggles the stack position (tiling mode).
click on a tag label adds/removes all windows with that tag to/from the view.
.TP
.B Mod1-Button1
click on a tag label applies that tag to the focused window.
@ -63,20 +64,20 @@ Focus previous window.
.B Mod1-Return
Zooms/cycles current window to/from master area (tiling mode), toggles maximization current window (floating mode).
.TP
.B Mod1-b
Toggle stack position (tiling mode only).
.TP
.B Mod1-g
Grow current area (tiling mode only).
Grow master area (tiling mode only).
.TP
.B Mod1-s
Shrink current area (tiling mode only).
Shrink master area (tiling mode only).
.TP
.B Mod1-Shift-[1..n]
Apply
.RB nth
tag to current window.
.TP
.B Mod1-Shift-0
Apply all tags to current window.
.TP
.B Mod1-Control-Shift-[1..n]
Add/remove
.B nth
@ -88,6 +89,9 @@ Close focused window.
.B Mod1-space
Toggle between tiling and floating mode (affects all windows).
.TP
.B Mod1-Shift-space
Toggle focused window between floating and non-floating state (tiling mode only).
.TP
.B Mod1-[1..n]
View all windows with
.BR nth
@ -118,9 +122,17 @@ 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 may display
.BR "broken pipe"
when dwm has been started by
.BR "EOF"
when dwm has been started by an X session manager like
.BR xdm (1),
because it closes standard output before executing dwm.
because those close standard output before executing dwm.
.P
Java applications which use the XToolkit/XAWT backend may draw grey windows
only. The XToolkit/XAWT backend breaks ICCCM-compliance in recent JDK 1.5 and early
JDK 1.6 versions, because it assumes a reparenting window manager. As a workaround
you can use JDK 1.4 (which doesn't contain the XToolkit/XAWT backend) or you
can set the following environment variable (to use the older Motif
backend instead):
.BR AWT_TOOLKIT=MToolkit .
.SH SEE ALSO
.BR dmenu (1)

27
dwm.h
View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*
* dynamic window manager is designed like any other X client as well. It is
@ -37,7 +36,6 @@
/* mask shorthands, used in event.c and client.c */
#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask)
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
/* other stuff used in different places */
#define BORDERPX 1
#define PROTODELWIN 1
@ -47,10 +45,6 @@ enum { WMProtocols, WMDelete, WMLast }; /* default atoms */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColFG, ColBG, ColLast }; /* color */
typedef enum {
StackLeft, StackBottom, StackRight
} StackPos; /* stack position*/
typedef enum {
TopLeft, TopRight, BotLeft, BotRight
} Corner; /* window corners */
@ -86,10 +80,9 @@ struct Client {
int rx, ry, rw, rh; /* revert geometry */
int tx, ty, tw, th; /* title window geometry */
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int grav;
long flags;
unsigned int border, weight;
Bool isfloat, ismax;
unsigned int border;
Bool isfloat, isfixed, ismax;
Bool *tags;
Client *next;
Client *prev;
@ -102,16 +95,16 @@ extern const char *tags[]; /* all tags */
extern char stext[1024]; /* status text */
extern int bx, by, bw, bh, bmw; /* bar geometry, bar mode label width */
extern int screen, sx, sy, sw, sh; /* screen geometry */
extern int wax, way, wah, waw; /* windowarea geometry */
extern unsigned int master, ntags, numlockmask; /* master percent, number of tags, dynamic lock mask */
extern void (*handler[LASTEvent])(XEvent *); /* event handler */
extern void (*arrange)(Arg *); /* arrange function, indicates mode */
extern void (*arrange)(void); /* arrange function, indicates mode */
extern Atom wmatom[WMLast], netatom[NetLast];
extern Bool running, issel, *seltag; /* seltag is array of Bool */
extern Client *clients, *sel, *stack; /* global client list and stack */
extern Cursor cursor[CurLast];
extern DC dc; /* global draw context */
extern Display *dpy;
extern StackPos stackpos;
extern Window root, barwin;
/* client.c */
@ -120,7 +113,6 @@ extern void configure(Client *c); /* send synthetic configure event */
extern void focus(Client *c); /* focus c, c may be NULL */
extern Client *getclient(Window w); /* return client of w */
extern Client *getctitle(Window w); /* return client of title window */
extern void gravitate(Client *c, Bool invert); /* gravitate c */
extern void killclient(Arg *arg); /* kill c nicely */
extern void manage(Window w, XWindowAttributes *wa); /* manage new client */
extern void resize(Client *c, Bool sizehints, Corner sticky); /* resize c*/
@ -163,16 +155,15 @@ extern void spawn(Arg *arg); /* forks a new subprocess with to arg's cmd */
/* view.c */
extern void detach(Client *c); /* detaches c from global client list */
extern void dofloat(Arg *arg); /* arranges all windows floating, arg is ignored */
extern void dotile(Arg *arg); /* arranges all windows, arg is ignored */
extern void dofloat(void); /* arranges all windows floating */
extern void dotile(void); /* arranges all windows tiled */
extern void focusnext(Arg *arg); /* focuses next visible client, arg is ignored */
extern void focusprev(Arg *arg); /* focuses previous visible client, arg is ignored */
extern Bool isvisible(Client *c); /* returns True if client is visible */
extern void resizecol(Arg *arg); /* resizes the master percent with arg's index value */
extern void resizemaster(Arg *arg); /* resizes the master percent with arg's index value */
extern void restack(void); /* restores z layers of all clients */
extern void togglestackpos(Arg *arg); /* toggles stack position */
extern void togglefloat(Arg *arg); /* toggles focusesd client between floating/non-floating state */
extern void togglemode(Arg *arg); /* toggles global arrange function (dotile/dofloat) */
extern void toggleview(Arg *arg); /* toggles the tag with arg's index (in)visible */
extern void view(Arg *arg); /* views the tag with arg's index */
extern void viewall(Arg *arg); /* views all tags, arg is ignored */
extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */

40
event.c
View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@ -19,6 +18,7 @@ typedef struct {
KEYS
#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask))
#define MOUSEMASK (BUTTONMASK | PointerMotionMask)
static void
movemouse(Client *c) {
@ -48,6 +48,14 @@ movemouse(Client *c) {
XSync(dpy, False);
c->x = ocx + (ev.xmotion.x - x1);
c->y = ocy + (ev.xmotion.y - y1);
if(abs(wax + c->x) < SNAP)
c->x = wax;
else if(abs((wax + waw) - (c->x + c->w)) < SNAP)
c->x = wax + waw - c->w - 2 * BORDERPX;
if(abs(way - c->y) < SNAP)
c->y = way;
else if(abs((way + wah) - (c->y + c->h)) < SNAP)
c->y = way + wah - c->h - 2 * BORDERPX;
resize(c, False, TopLeft);
break;
}
@ -64,7 +72,7 @@ resizemouse(Client *c) {
ocx = c->x;
ocy = c->y;
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
c->ismax = False;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w, c->h);
@ -123,12 +131,8 @@ buttonpress(XEvent *e) {
return;
}
}
if(ev->x < x + bmw) {
if(ev->button == Button1)
togglemode(NULL);
else if(ev->button == Button3)
togglestackpos(NULL);
}
if((ev->x < x + bmw) && (ev->button == Button1))
togglemode(NULL);
}
else if((c = getclient(ev->window))) {
focus(c);
@ -140,7 +144,8 @@ buttonpress(XEvent *e) {
}
else if(ev->button == Button2)
zoom(NULL);
else if(ev->button == Button3 && (arrange == dofloat || c->isfloat)) {
else if(ev->button == Button3 && (arrange == dofloat || c->isfloat) &&
!c->isfixed) {
restack();
resizemouse(c);
}
@ -156,7 +161,6 @@ configurerequest(XEvent *e) {
if((c = getclient(ev->window))) {
c->ismax = False;
gravitate(c, True);
if(ev->value_mask & CWX)
c->x = ev->x;
if(ev->value_mask & CWY)
@ -167,7 +171,6 @@ configurerequest(XEvent *e) {
c->h = ev->height;
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
gravitate(c, False);
wc.x = c->x;
wc.y = c->y;
wc.width = c->w;
@ -184,7 +187,7 @@ configurerequest(XEvent *e) {
ban(c);
}
else
arrange(NULL);
arrange();
}
else {
wc.x = ev->x;
@ -215,7 +218,6 @@ enternotify(XEvent *e) {
if(ev->mode != NotifyNormal || ev->detail == NotifyInferior)
return;
if(((c = getclient(ev->window)) || (c = getctitle(ev->window))) && isvisible(c))
focus(c);
else if(ev->window == root) {
@ -240,7 +242,7 @@ expose(XEvent *e) {
static void
keypress(XEvent *e) {
static unsigned int len = sizeof(key) / sizeof(key[0]);
static unsigned int len = sizeof key / sizeof key[0];
unsigned int i;
KeySym keysym;
XKeyEvent *ev = &e->xkey;
@ -252,7 +254,6 @@ keypress(XEvent *e) {
{
if(key[i].func)
key[i].func(&key[i].arg);
return;
}
}
}
@ -283,13 +284,11 @@ maprequest(XEvent *e) {
if(!XGetWindowAttributes(dpy, ev->window, &wa))
return;
if(wa.override_redirect) {
XSelectInput(dpy, ev->window,
(StructureNotifyMask | PropertyChangeMask));
return;
}
if(!getclient(ev->window))
manage(ev->window, &wa);
}
@ -302,7 +301,6 @@ propertynotify(XEvent *e) {
if(ev->state == PropertyDelete)
return; /* ignore */
if((c = getclient(ev->window))) {
if(ev->atom == wmatom[WMProtocols]) {
c->proto = getproto(c->win);
@ -313,7 +311,7 @@ propertynotify(XEvent *e) {
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
if(!c->isfloat && (c->isfloat = (trans != 0)))
arrange(NULL);
arrange();
break;
case XA_WM_NORMAL_HINTS:
updatesize(c);
@ -354,7 +352,7 @@ void (*handler[LASTEvent]) (XEvent *) = {
void
grabkeys(void) {
static unsigned int len = sizeof(key) / sizeof(key[0]);
static unsigned int len = sizeof key / sizeof key[0];
unsigned int i;
KeyCode code;

93
main.c
View File

@ -1,10 +1,10 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -19,7 +19,7 @@
char stext[1024];
Bool *seltag;
int bx, by, bw, bh, bmw, masterd, screen, sx, sy, sw, sh;
int bx, by, bw, bh, bmw, masterd, screen, sx, sy, sw, sh, wax, way, waw, wah;
unsigned int master, ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
@ -52,6 +52,9 @@ cleanup(void) {
XFreePixmap(dpy, dc.drawable);
XFreeGC(dpy, dc.gc);
XDestroyWindow(dpy, barwin);
XFreeCursor(dpy, cursor[CurNormal]);
XFreeCursor(dpy, cursor[CurResize]);
XFreeCursor(dpy, cursor[CurMove]);
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
XSync(dpy, False);
free(seltag);
@ -93,12 +96,11 @@ setup(void) {
netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False);
XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32,
PropModeReplace, (unsigned char *) netatom, NetLast);
/* init cursors */
cursor[CurNormal] = XCreateFontCursor(dpy, XC_left_ptr);
cursor[CurResize] = XCreateFontCursor(dpy, XC_sizing);
cursor[CurMove] = XCreateFontCursor(dpy, XC_fleur);
/* init modifier map */
modmap = XGetModifierMapping(dpy);
for (i = 0; i < 8; i++) {
for (j = 0; j < modmap->max_keypermod; j++) {
@ -106,20 +108,17 @@ setup(void) {
numlockmask = (1 << i);
}
}
XFree(modmap);
XFreeModifiermap(modmap);
/* select for events */
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[0] = True;
/* style */
dc.norm[ColBG] = getcolor(NORMBGCOLOR);
dc.norm[ColFG] = getcolor(NORMFGCOLOR);
@ -128,17 +127,15 @@ setup(void) {
dc.status[ColBG] = getcolor(STATUSBGCOLOR);
dc.status[ColFG] = getcolor(STATUSFGCOLOR);
setfont(FONT);
bmw = textw(VSTACKSYMBOL) > textw(BSTACKSYMBOL) ?
textw(VSTACKSYMBOL) : textw(BSTACKSYMBOL);
bmw = bmw > textw(FLOATSYMBOL) ?
bmw : textw(FLOATSYMBOL);
/* geometry */
bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL);
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
master = MASTER;
bx = by = 0;
/* bar */
bx = sx;
by = sy;
bw = sw;
dc.h = bh = dc.font.height + 2;
wa.override_redirect = 1;
@ -149,13 +146,18 @@ setup(void) {
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
strcpy(stext, "dwm-"VERSION);
/* windowarea */
wax = sx;
way = sy + bh;
wah = sh - bh;
waw = sw;
/* pixmap for everything */
dc.drawable = XCreatePixmap(dpy, root, sw, bh, DefaultDepth(dpy, screen));
dc.gc = XCreateGC(dpy, root, 0, 0);
XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter);
/* multihead support */
issel = XQueryPointer(dpy, root, &w, &w, &i, &i, &i, &i, &mask);
strcpy(stext, "dwm-"VERSION);
}
/*
@ -207,8 +209,7 @@ quit(Arg *arg) {
readin = running = False;
}
/*
* There's no way to check accesses to destroyed windows, thus those cases are
/* There's no way to check accesses to destroyed windows, thus those cases are
* ignored (especially on UnmapNotify's). Other types of errors call Xlibs
* default error handler, which may call exit.
*/
@ -230,6 +231,7 @@ xerror(Display *dpy, XErrorEvent *ee) {
int
main(int argc, char *argv[]) {
char *p;
int r, xfd;
fd_set rd;
@ -239,21 +241,18 @@ main(int argc, char *argv[]) {
}
else if(argc != 1)
eprint("usage: dwm [-v]\n");
setlocale(LC_CTYPE, "");
dpy = XOpenDisplay(0);
if(!dpy)
eprint("dwm: cannot open display\n");
xfd = ConnectionNumber(dpy);
screen = DefaultScreen(dpy);
root = RootWindow(dpy, screen);
otherwm = False;
XSetErrorHandler(xerrorstart);
/* this causes an error if some other window manager is running */
XSelectInput(dpy, root, SubstructureRedirectMask);
XSync(dpy, False);
if(otherwm)
eprint("dwm: another window manager is already running\n");
@ -261,7 +260,6 @@ main(int argc, char *argv[]) {
XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False);
setup();
drawstatus();
scan();
@ -275,25 +273,34 @@ main(int argc, char *argv[]) {
if(readin)
FD_SET(STDIN_FILENO, &rd);
FD_SET(xfd, &rd);
r = select(xfd + 1, &rd, NULL, NULL, NULL);
if((r == -1) && (errno == EINTR))
continue;
if(r > 0) {
if(readin && FD_ISSET(STDIN_FILENO, &rd)) {
readin = NULL != fgets(stext, sizeof(stext), stdin);
if(readin)
stext[strlen(stext) - 1] = 0;
else
strcpy(stext, "broken pipe");
drawstatus();
}
}
else if(r < 0)
if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
if(errno == EINTR)
continue;
eprint("select failed\n");
procevent();
}
if(FD_ISSET(STDIN_FILENO, &rd)) {
switch(r = read(STDIN_FILENO, stext, sizeof stext - 1)) {
case -1:
strncpy(stext, strerror(errno), sizeof stext - 1);
stext[sizeof stext - 1] = '\0';
readin = False;
break;
case 0:
strncpy(stext, "EOF", 4);
readin = False;
break;
default:
for(stext[r] = '\0', p = stext + strlen(stext) - 1; p >= stext && *p == '\n'; *p-- = '\0');
for(p = stext + strlen(stext) - 1; p >= stext && *p != '\n'; --p);
if(p > stext)
strncpy(stext, p + 1, sizeof stext);
}
drawstatus();
}
if(FD_ISSET(xfd, &rd))
procevent();
}
cleanup();
XCloseDisplay(dpy);
return 0;
}

28
tag.c
View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@ -51,20 +50,19 @@ initrregs(void) {
if(rreg)
return;
len = sizeof(rule) / sizeof(rule[0]);
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))
if(regcomp(reg, rule[i].clpattern, REG_EXTENDED))
free(reg);
else
rreg[i].clregex = reg;
}
if(rule[i].tpattern) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].tpattern, 0))
if(regcomp(reg, rule[i].tpattern, REG_EXTENDED))
free(reg);
else
rreg[i].tregex = reg;
@ -85,10 +83,10 @@ settags(Client *c, Client *trans) {
c->tags[i] = trans->tags[i];
}
else if(XGetClassHint(dpy, c->win, &ch)) {
snprintf(prop, sizeof(prop), "%s:%s:%s",
snprintf(prop, sizeof prop, "%s:%s:%s",
ch.res_class ? ch.res_class : "",
ch.res_name ? ch.res_name : "", c->name);
for(i = 0; !matched && i < len; i++)
for(i = 0; i < len; i++)
if(rreg[i].clregex && !regexec(rreg[i].clregex, prop, 1, &tmp, 0)) {
c->isfloat = rule[i].isfloat;
for(j = 0; rreg[i].tregex && j < ntags; j++) {
@ -106,7 +104,6 @@ settags(Client *c, Client *trans) {
if(!matched)
for(i = 0; i < ntags; i++)
c->tags[i] = seltag[i];
for(c->weight = 0; c->weight < ntags && !c->tags[c->weight]; c->weight++);
}
void
@ -115,12 +112,11 @@ tag(Arg *arg) {
if(!sel)
return;
for(i = 0; i < ntags; i++)
sel->tags[i] = False;
sel->tags[arg->i] = True;
sel->weight = arg->i;
arrange(NULL);
sel->tags[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
sel->tags[arg->i] = True;
arrange();
}
void
@ -129,11 +125,9 @@ toggletag(Arg *arg) {
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;
sel->weight = (i == ntags) ? arg->i : i;
arrange(NULL);
arrange();
}

5
util.c
View File

@ -1,5 +1,4 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
@ -33,6 +32,7 @@ eprint(const char *errstr, ...) {
void *
erealloc(void *ptr, unsigned int size) {
void *res = realloc(ptr, size);
if(!res)
eprint("fatal: could not malloc() %u bytes\n", size);
return res;
@ -44,7 +44,6 @@ spawn(Arg *arg) {
if(!shell && !(shell = getenv("SHELL")))
shell = "/bin/sh";
if(!arg->cmd)
return;
/* The double-fork construct avoids zombie processes and keeps the code

211
view.c
View File

@ -1,23 +1,10 @@
/*
* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
/* (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include "dwm.h"
/* static */
static Client *
minclient(void) {
Client *c, *min;
if((clients && clients->isfloat) || arrange == dofloat)
return clients; /* don't touch floating order */
for(min = c = clients; c; c = c->next)
if(c->weight < min->weight)
min = c;
return min;
}
static Client *
nexttiled(Client *c) {
for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
@ -25,32 +12,17 @@ nexttiled(Client *c) {
}
static void
reorder(void) {
Client *c, *newclients, *tail;
newclients = tail = NULL;
while((c = minclient())) {
detach(c);
if(tail) {
c->prev = tail;
tail->next = c;
tail = c;
}
else
tail = newclients = c;
}
clients = newclients;
}
static void
togglemax(Client *c)
{
togglemax(Client *c) {
XEvent ev;
if(c->isfixed)
return;
if((c->ismax = !c->ismax)) {
c->rx = c->x; c->x = sx;
c->ry = c->y; c->y = bh;
c->rw = c->w; c->w = sw - 2 * BORDERPX;
c->rh = c->h; c->h = sh - bh - 2 * BORDERPX;
c->rx = c->x; c->x = wax;
c->ry = c->y; c->y = way;
c->rw = c->w; c->w = waw - 2 * BORDERPX;
c->rh = c->h; c->h = wah - 2 * BORDERPX;
}
else {
c->x = c->rx;
@ -64,8 +36,7 @@ togglemax(Client *c)
/* extern */
void (*arrange)(Arg *) = DEFMODE;
StackPos stackpos = STACKPOS;
void (*arrange)(void) = DEFMODE;
void
detach(Client *c) {
@ -79,7 +50,7 @@ detach(Client *c) {
}
void
dofloat(Arg *arg) {
dofloat(void) {
Client *c;
for(c = clients; c; c = c->next) {
@ -96,97 +67,50 @@ dofloat(Arg *arg) {
restack();
}
/* This algorithm is based on a (M)aster area and a (S)tacking area.
* It supports following arrangements:
* SSMMM MMMMM MMMSS
* SSMMM SSSSS MMMSS
*/
void
dotile(Arg *arg) {
unsigned int i, n, md, stackw, stackh, tw, th;
dotile(void) {
unsigned int i, n, mpx, stackw, th;
Client *c;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
mpx = (waw * master) / 1000;
stackw = waw - mpx;
if(stackpos == StackBottom) {
md = ((sh - bh) * master) / 100;
stackw = sw;
stackh = sh - bh - md;
}
else {
md = (sw * master) / 100;
stackw = sw - md;
stackh = sh - bh;
}
tw = stackw;
if(n > 1)
th = stackh / (n - 1);
else
th = stackh;
for(i = 0, c = clients; c; c = c->next) {
for(i = 0, c = clients; c; c = c->next)
if(isvisible(c)) {
if(c->isfloat) {
resize(c, True, TopLeft);
continue;
}
c->ismax = False;
c->x = sx;
c->y = sy + bh;
c->x = wax;
c->y = way;
if(n == 1) { /* only 1 window */
c->w = sw - 2 * BORDERPX;
c->h = sh - 2 * BORDERPX - bh;
c->w = waw - 2 * BORDERPX;
c->h = wah - 2 * BORDERPX;
}
else if(i == 0) { /* master window */
if(stackpos == StackLeft)
c->x += stackw;
switch(stackpos) {
case StackLeft:
case StackRight:
c->w = md - 2 * BORDERPX;
c->h = sh - bh - 2 * BORDERPX;
break;
case StackBottom:
c->w = sw - 2 * BORDERPX;
c->h = md - 2 * BORDERPX;
break;
}
c->w = mpx - 2 * BORDERPX;
c->h = wah - 2 * BORDERPX;
th = wah / (n - 1);
}
else { /* tile window */
if(stackpos == StackRight)
c->x += md;
c->x += mpx;
c->w = stackw - 2 * BORDERPX;
if(th > bh) {
switch(stackpos) {
case StackLeft:
case StackRight:
c->y = sy + (i - 1) * th + bh;
if(i + 1 == n)
c->h = sh - c->y - 2 * BORDERPX;
break;
case StackBottom:
c->y = sy + md + (i - 1) * th + bh;
if(i + 1 == n)
c->h = sh - c->y - 2 * BORDERPX;
break;
}
c->w = tw - 2 * BORDERPX;
c->y += (i - 1) * th;
c->h = th - 2 * BORDERPX;
}
else { /* fallback if th < bh */
if(stackpos == StackBottom)
c->y += md;
c->w = stackw - 2 * BORDERPX;
c->h = stackh - 2 * BORDERPX;
}
else /* fallback if th < bh */
c->h = wah - 2 * BORDERPX;
}
resize(c, False, TopLeft);
i++;
}
else
ban(c);
}
if(!sel || !isvisible(sel)) {
for(c = stack; c && !isvisible(c); c = c->snext);
focus(c);
@ -200,7 +124,6 @@ focusnext(Arg *arg) {
if(!sel)
return;
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
@ -215,7 +138,6 @@ focusprev(Arg *arg) {
if(!sel)
return;
if(!(c = getprev(sel->prev))) {
for(c = clients; c && c->next; c = c->next);
c = getprev(c);
@ -237,27 +159,15 @@ isvisible(Client *c) {
}
void
resizecol(Arg *arg) {
unsigned int n;
Client *c;
for(n = 0, c = clients; c; c = c->next)
if(isvisible(c) && !c->isfloat)
n++;
if(!sel || sel->isfloat || n < 2 || (arrange == dofloat))
return;
if(sel == getnext(clients)) {
if(master + arg->i > 95 || master + arg->i < 5)
resizemaster(Arg *arg) {
if(arg->i == 0)
master = MASTER;
else {
if(master + arg->i > 950 || master + arg->i < 50)
return;
master += arg->i;
}
else {
if(master - arg->i > 95 || master - arg->i < 5)
return;
master -= arg->i;
}
arrange(NULL);
arrange();
}
void
@ -290,11 +200,19 @@ restack(void) {
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
togglefloat(Arg *arg) {
if (!sel || arrange == dofloat)
return;
sel->isfloat = !sel->isfloat;
arrange();
}
void
togglemode(Arg *arg) {
arrange = (arrange == dofloat) ? dotile : dofloat;
if(sel)
arrange(NULL);
arrange();
else
drawstatus();
}
@ -307,19 +225,7 @@ toggleview(Arg *arg) {
for(i = 0; i < ntags && !seltag[i]; i++);
if(i == ntags)
seltag[arg->i] = True; /* cannot toggle last view */
reorder();
arrange(NULL);
}
void
togglestackpos(Arg *arg) {
if(arrange == dofloat)
return;
if(stackpos == StackBottom)
stackpos = STACKPOS;
else
stackpos = StackBottom;
arrange(NULL);
arrange();
}
void
@ -327,24 +233,12 @@ view(Arg *arg) {
unsigned int i;
for(i = 0; i < ntags; i++)
seltag[i] = False;
seltag[arg->i] = True;
reorder();
arrange(NULL);
seltag[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
seltag[arg->i] = True;
arrange();
}
void
viewall(Arg *arg) {
unsigned int i;
for(i = 0; i < ntags; i++)
seltag[i] = True;
reorder();
arrange(NULL);
}
void
zoom(Arg *arg) {
unsigned int n;
@ -352,18 +246,15 @@ zoom(Arg *arg) {
if(!sel)
return;
if(sel->isfloat || (arrange == dofloat)) {
togglemax(sel);
return;
}
for(n = 0, c = clients; c; c = c->next)
if(isvisible(c) && !c->isfloat)
n++;
if(n < 2 || (arrange == dofloat))
return;
if((c = sel) == nexttiled(clients))
if(!(c = nexttiled(c->next)))
return;
@ -373,5 +264,5 @@ zoom(Arg *arg) {
c->next = clients;
clients = c;
focus(c);
arrange(NULL);
arrange();
}