Compare commits

...

70 Commits
1.7 ... 2.2

Author SHA1 Message Date
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
69408d384d simplified dotile(), removed misleading line 2006-10-05 13:47:30 +02:00
4aea423f06 final fix for man page 2006-10-05 13:44:48 +02:00
6fc8a63041 keep master ratio on resizecol -> arrange 2006-10-05 12:59:35 +02:00
2583a7c0d1 yet another simplification of dotile() 2006-10-05 12:18:04 +02:00
0ef6e3103c simplified dotile() 2006-10-05 12:13:24 +02:00
7c052b37c8 applied resizecol fix by Jukka 2006-10-05 11:00:55 +02:00
d9c475d7f4 Button3 click on mode label toggles stack position now 2006-10-05 09:37:11 +02:00
c8e57332d1 applied dave's highlight patch for big fonts 2006-09-29 19:06:27 +02:00
c045459917 using ff tiled again, seems to work perfectly with new bottom stack 2006-09-29 18:40:32 +02:00
e0f64e63db applied ality's hardcode-0 patches 2006-09-29 18:21:02 +02:00
dddd58a8cd added symbols for different modes 2006-09-29 18:08:20 +02:00
010fd21b20 removed useless updatemaster 2006-09-29 17:25:49 +02:00
1802fad2f9 documented the new behavior in man page 2006-09-29 17:20:05 +02:00
f833d109d1 fixed small offset issue 2006-09-29 17:15:05 +02:00
7225c99903 fixed the z-layer issue described on mailinglist 2006-09-29 17:12:57 +02:00
36178933ed removed the direction flipping 2006-09-29 17:02:56 +02:00
ad0da9a571 small fix of a corner case 2006-09-29 16:54:15 +02:00
6646468125 small change 2006-09-29 16:44:02 +02:00
fee8df6ccf added the new dotile as described on ml 2006-09-29 16:22:20 +02:00
8fa47ac679 prelim of dotile() 2006-09-29 14:39:03 +02:00
b427a2c6cb I changed sanders patch to fix the ff issue to be simplier, though it needs testing if this really fixes the issue 2006-09-29 12:56:01 +02:00
14d05e7c72 first step to a more flexible dotile() algorithm 2006-09-29 12:38:27 +02:00
a118a57fe3 renamed column into area 2006-09-28 21:29:20 +02:00
02cea3b47e small change to README 2006-09-28 16:14:48 +02:00
1c2d673ded applied Jukkas patch 2006-09-28 14:03:39 +02:00
c34df2c1b6 Added tag 1.7.1 for changeset d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 2006-09-27 17:21:25 +02:00
6092aa977e fixing the settags issue, preparing 1.7.1 2006-09-27 17:18:46 +02:00
c9cc2b385a removed an unused var 2006-09-26 17:42:14 +02:00
b39d0c521a Added tag 1.7 for changeset 4dbdb61c8b8ce21dee5c7050a6b103855964ed20 2006-09-26 17:39:30 +02:00
14 changed files with 187 additions and 232 deletions

View File

@ -14,3 +14,9 @@ f5f5cbf016a94b48a8fe9c47f0736e96d166d5d4 1.3
3cff9403766bf83a9fc2a0aef230115d68de2a8e 1.4
728c9089b079721b43c3347124639a29baa22a97 1.5
ad3fa2d185426c51fd5deceae809770363f8d33c 1.6
4dbdb61c8b8ce21dee5c7050a6b103855964ed20 1.7
d5ad819f2a66a40fa75dd2e44429f3bfc884d07b 1.7.1
c71952fa3c7ca848ec38a6923b5c6d0e18fff431 1.8
a5567a0d30112822db2627a04a2e7aa3b6c38148 1.9
12deea36603da407e3f32640048846a3bd74a9ec 2.0
a2c465098a3b972bbed00feda9804b6aae1e9531 2.1

2
README
View File

@ -37,7 +37,7 @@ like this in your .xinitrc:
while true
do
echo `date` `uptime | sed 's/.*://; s/,//g'`
echo `date` `uptime | sed 's/.*,//'`
sleep 1
done | dwm

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"
@ -54,19 +53,6 @@ grabbuttons(Client *c, Bool focused) {
GrabModeAsync, GrabModeSync, None, None);
}
static void
resizetitle(Client *c) {
c->tw = textw(c->name);
if(c->tw > c->w)
c->tw = c->w + 2;
c->tx = c->x + c->w - c->tw + 2;
c->ty = c->y;
if(isvisible(c))
XMoveResizeWindow(dpy, c->twin, c->tx, c->ty, c->tw, c->th);
else
XMoveResizeWindow(dpy, c->twin, c->tx + 2 * sw, c->ty, c->tw, c->th);
}
static int
xerrordummy(Display *dsply, XErrorEvent *ee) {
return 0;
@ -169,7 +155,6 @@ gravitate(Client *c, Bool invert) {
dy = -(c->h);
break;
}
switch (c->grav) {
default:
break;
@ -190,7 +175,6 @@ gravitate(Client *c, Bool invert) {
dx = -(c->w + c->border);
break;
}
if(invert) {
dx = -dx;
dy = -dy;
@ -218,24 +202,21 @@ 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 > sw)
c->x = sw - c->w - 2;
if(c->x < 0)
c->x = 0;
if(c->y + c->h + 2 > sh)
c->y = sh - c->h - 2;
if(c->x + c->w + 2 * BORDERPX > sw)
c->x = sw - c->w - 2 * BORDERPX;
if(c->x < sx)
c->x = sx;
if(c->y + c->h + 2 * BORDERPX > sh)
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);
@ -243,32 +224,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;
updatetitle(c);
ban(c);
XMapWindow(dpy, c->win);
XMapWindow(dpy, c->twin);
if(isvisible(c))
focus(c);
arrange(NULL);
arrange();
}
void
@ -295,17 +271,15 @@ 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 < 0)
c->x = 0;
if(c->x + c->w < sx)
c->x = sx;
if(c->y + c->h < bh)
c->y = bh;
if(c->x > sw)
c->x = sw - c->w;
if(c->y > sh)
c->y = sh - c->h;
resizetitle(c);
wc.x = c->x;
wc.y = c->y;
@ -314,12 +288,25 @@ resize(Client *c, Bool sizehints, Corner sticky) {
if(c->w == sw && c->h == sh)
wc.border_width = 0;
else
wc.border_width = 1;
wc.border_width = BORDERPX;
XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc);
configure(c);
XSync(dpy, False);
}
void
resizetitle(Client *c) {
c->tw = textw(c->name);
if(c->tw > c->w)
c->tw = c->w + 2 * BORDERPX;
c->tx = c->x + c->w - c->tw + 2 * BORDERPX;
c->ty = c->y;
if(isvisible(c))
XMoveResizeWindow(dpy, c->twin, c->tx, c->ty, c->tw, c->th);
else
XMoveResizeWindow(dpy, c->twin, c->tx + 2 * sw, c->ty, c->tw, c->th);
}
void
updatesize(Client *c) {
long msize;
@ -352,6 +339,8 @@ updatesize(Client *c) {
}
else
c->minw = c->minh = 0;
c->isfixed = (c->maxw && c->minw && c->maxh && c->minh &&
c->maxw == c->minw && c->maxh == c->minh);
if(c->flags & PWinGravity)
c->grav = size.win_gravity;
else
@ -382,7 +371,6 @@ updatetitle(Client *c) {
}
}
XFree(name.value);
resizetitle(c);
}
void
@ -392,22 +380,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,41 +1,40 @@
/*
* (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.
*/
#define TAGS \
const char *tags[] = { "dev", "work", "net", "fnord", NULL };
#define DEFMODE dotile /* dofloat */
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define TILESYMBOL "[]="
#define FONT "-*-terminus-medium-*-*-*-12-*-*-*-*-*-iso10646-*"
#define FONT "-*-terminus-medium-*-*-*-14-*-*-*-*-*-*-*"
#define NORMBGCOLOR "#333333"
#define NORMFGCOLOR "#dddddd"
#define SELBGCOLOR "#333366"
#define SELBGCOLOR "#336699"
#define SELFGCOLOR "#eeeeee"
#define STATUSBGCOLOR "#222222"
#define STATUSFGCOLOR "#9999cc"
#define STATUSFGCOLOR "#99ccff"
#define MASTERW 60 /* percent */
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define SNAP 40 /* pixel */
#define KEYS \
static Key key[] = { \
/* modifier key function arguments */ \
{ MODKEY|ShiftMask, XK_Return, spawn, \
{ .cmd = "exec uxterm -bg '#111111' -fg '#eeeeee' -cr '#eeeeee' +sb -fn '"FONT"'" } }, \
{ .cmd = "exec urxvtc -tr -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_g, resizecol, { .i = 20 } }, \
{ MODKEY, XK_s, resizecol, { .i = -20 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
@ -61,8 +60,8 @@ static Key key[] = { \
#define RULES \
static Rule rule[] = { \
/* class:instance:title regex tags regex isfloat */ \
{ "Firefox.*", "net", True}, \
{ "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.
*/
@ -18,8 +17,9 @@ const char *tags[] = { "1", "2", "3", "4", "5", NULL };
#define STATUSBGCOLOR "#dddddd"
#define STATUSFGCOLOR "#222222"
#define MASTERW 60 /* percent */
#define MASTER 600 /* per thousand */
#define MODKEY Mod1Mask
#define SNAP 20 /* pixel */
#define KEYS \
static Key key[] = { \
@ -28,8 +28,8 @@ static Key key[] = { \
{ MODKEY, XK_Tab, focusnext, { 0 } }, \
{ MODKEY|ShiftMask, XK_Tab, focusprev, { 0 } }, \
{ MODKEY, XK_Return, zoom, { 0 } }, \
{ MODKEY, XK_g, resizecol, { .i = 20 } }, \
{ MODKEY, XK_s, resizecol, { .i = -20 } }, \
{ MODKEY, XK_g, resizemaster, { .i = 15 } }, \
{ MODKEY, XK_s, resizemaster, { .i = -15 } }, \
{ MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \
{ MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \
{ MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \
@ -62,5 +62,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.7
VERSION = 2.2
# Customize below to fit your system

18
draw.c
View File

@ -1,5 +1,4 @@
/*
* (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"
@ -30,21 +29,17 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
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;
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 +51,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];
@ -72,7 +66,7 @@ drawtext(const char *text, unsigned long col[ColLast], Bool highlight) {
if(highlight) {
r.x = dc.x + 2;
r.y = dc.y + 2;
r.width = r.height = 3;
r.width = r.height = (h + 2) / 4;
XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1);
}
}
@ -93,7 +87,6 @@ drawstatus(void) {
int i, x;
dc.x = dc.y = 0;
for(i = 0; i < ntags; i++) {
dc.w = textw(tags[i]);
if(seltag[i])
@ -102,10 +95,8 @@ drawstatus(void) {
drawtext(tags[i], dc.norm, sel && sel->tags[i]);
dc.x += dc.w;
}
dc.w = bmw;
drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False);
drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False);
x = dc.x + dc.w;
dc.w = textw(stext);
dc.x = bx + bw - dc.w;
@ -114,7 +105,6 @@ drawstatus(void) {
dc.w = bw - x;
}
drawtext(stext, dc.status, False);
if((dc.w = dc.x - x) > bh) {
dc.x = x;
if(sel)
@ -134,7 +124,6 @@ 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;
@ -177,7 +166,6 @@ setfont(const char *fontstr) {
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);

18
dwm.1
View File

@ -9,9 +9,9 @@ dwm is a dynamic window manager for X. It manages windows in tiling and
floating 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 currently needs most attention, whereas the
stacking column contains all other windows. In floating mode windows can be
In tiling mode windows are managed in a master and stacking area. The master
area contains the window which currently needs most attention, whereas the
stacking area 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
@ -37,7 +37,7 @@ is read and displayed in the status text area.
.TP
.B Button1
click on a tag label to display all windows with that tag, click on the mode
label toggles between tiled and floating 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.
@ -60,13 +60,13 @@ Focus next window.
Focus previous window.
.TP
.B Mod1-Return
Zooms/cycles current window to/from master column (tiling mode), toggles maximization current window (floating mode).
Zooms/cycles current window to/from master area (tiling mode), toggles maximization current window (floating mode).
.TP
.B Mod1-g
Grow current column (tiling mode only).
Grow master area (tiling mode only).
.TP
.B Mod1-s
Shrink current column (tiling mode only).
Shrink master area (tiling mode only).
.TP
.B Mod1-Shift-[1..n]
Apply
@ -82,7 +82,7 @@ tag to/from current window.
Close focused window.
.TP
.B Mod1-space
Toggle between tiled and floating mode (affects all windows).
Toggle between tiling and floating mode (affects all windows).
.TP
.B Mod1-[1..n]
View all windows with
@ -105,7 +105,7 @@ Quit dwm.
Move current window while dragging (floating mode only).
.TP
.B Mod1-Button2
Zoom current window to the master column (tiling mode only).
Zoom current window to the master area (tiling mode only).
.TP
.B Mod1-Button3
Resize current window while dragging (floating mode only).

24
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,8 @@
/* 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
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
@ -83,7 +83,7 @@ struct Client {
int grav;
long flags;
unsigned int border, weight;
Bool isfloat, ismax;
Bool isfloat, isfixed, ismax;
Bool *tags;
Client *next;
Client *prev;
@ -95,10 +95,11 @@ struct Client {
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 mw, screen, sx, sy, sw, sh; /* screen geometry, master width */
extern unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */
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 */
@ -117,6 +118,7 @@ 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*/
extern void resizetitle(Client *c); /* resizes c->twin correctly */
extern void updatesize(Client *c); /* update the size structs of c */
extern void updatetitle(Client *c); /* update the name of c */
extern void unmanage(Client *c); /* destroy c */
@ -155,15 +157,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 width 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 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 column, arg is ignored */
extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */

38
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,10 +131,8 @@ buttonpress(XEvent *e) {
return;
}
}
if(ev->x < x + bmw) {
if(ev->button == Button1)
togglemode(NULL);
}
if((ev->x < x + bmw) && (ev->button == Button1))
togglemode(NULL);
}
else if((c = getclient(ev->window))) {
focus(c);
@ -138,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);
}
@ -150,7 +157,6 @@ configurerequest(XEvent *e) {
unsigned long newmask;
Client *c;
XConfigureRequestEvent *ev = &e->xconfigurerequest;
XEvent synev;
XWindowChanges wc;
if((c = getclient(ev->window))) {
@ -177,10 +183,13 @@ configurerequest(XEvent *e) {
else
configure(c);
XSync(dpy, False);
if(c->isfloat)
if(c->isfloat) {
resize(c, False, TopLeft);
if(!isvisible(c))
ban(c);
}
else
arrange(NULL);
arrange();
}
else {
wc.x = ev->x;
@ -211,7 +220,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) {
@ -279,13 +287,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);
}
@ -298,7 +304,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);
@ -309,7 +314,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);
@ -317,6 +322,7 @@ propertynotify(XEvent *e) {
}
if(ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) {
updatetitle(c);
resizetitle(c);
drawtitle(c);
}
}

43
main.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.
*/
@ -19,8 +18,8 @@
char stext[1024];
Bool *seltag;
int bx, by, bw, bh, bmw, mw, screen, sx, sy, sw, sh;
unsigned int ntags, numlockmask;
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;
Bool issel = True;
@ -93,12 +92,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++) {
@ -107,19 +105,16 @@ setup(void) {
}
}
XFree(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,13 +123,13 @@ setup(void) {
dc.status[ColBG] = getcolor(STATUSBGCOLOR);
dc.status[ColFG] = getcolor(STATUSFGCOLOR);
setfont(FONT);
bmw = textw(FLOATSYMBOL) > textw(TILESYMBOL) ? textw(FLOATSYMBOL) : textw(TILESYMBOL);
/* geometry */
bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL);
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
mw = (sw * MASTERW) / 100;
master = MASTER;
/* bar */
bx = by = 0;
bw = sw;
dc.h = bh = dc.font.height + 2;
@ -146,13 +141,18 @@ setup(void) {
CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
XDefineCursor(dpy, barwin, cursor[CurNormal]);
XMapRaised(dpy, barwin);
strcpy(stext, "dwm-"VERSION);
/* windowarea */
wax = sx;
way = 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);
}
/*
@ -204,8 +204,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.
*/
@ -236,21 +235,17 @@ main(int argc, char *argv[]) {
}
else if(argc != 1)
eprint("usage: dwm [-v]\n");
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");
@ -258,7 +253,6 @@ main(int argc, char *argv[]) {
XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False);
setup();
drawstatus();
scan();
@ -291,6 +285,5 @@ main(int argc, char *argv[]) {
}
cleanup();
XCloseDisplay(dpy);
return 0;
}

10
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"
@ -53,7 +52,6 @@ initrregs(void) {
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));
@ -115,12 +113,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);
arrange();
}
void
@ -129,11 +126,10 @@ 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

128
view.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"
@ -43,14 +42,17 @@ reorder(void) {
}
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;
c->rh = c->h; c->h = sh - bh - 2;
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,7 +66,7 @@ togglemax(Client *c)
/* extern */
void (*arrange)(Arg *) = DEFMODE;
void (*arrange)(void) = DEFMODE;
void
detach(Client *c) {
@ -78,7 +80,7 @@ detach(Client *c) {
}
void
dofloat(Arg *arg) {
dofloat(void) {
Client *c;
for(c = clients; c; c = c->next) {
@ -96,59 +98,49 @@ dofloat(Arg *arg) {
}
void
dotile(Arg *arg) {
int h, i, n, w;
dotile(void) {
unsigned int i, n, mpx, stackw, th;
Client *c;
w = sw - mw;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
n++;
mpx = (waw * master) / 1000;
stackw = waw - mpx;
if(n > 1)
h = (sh - bh) / (n - 1);
else
h = sh - bh;
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;
if(n == 1) {
c->x = sx;
c->y = sy + bh;
c->w = sw - 2;
c->h = sh - 2 - bh;
c->x = wax;
c->y = way;
if(n == 1) { /* only 1 window */
c->w = waw - 2 * BORDERPX;
c->h = wah - 2 * BORDERPX;
}
else if(i == 0) {
c->x = sx;
c->y = sy + bh;
c->w = mw - 2;
c->h = sh - 2 - bh;
else if(i == 0) { /* master window */
c->w = waw - stackw - 2 * BORDERPX;
c->h = wah - 2 * BORDERPX;
th = wah / (n - 1);
}
else if(h > bh) {
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 */
c->x = sx + mw;
c->y = sy + bh;
c->w = w - 2;
c->h = sh - 2 - bh;
else { /* tile window */
c->x += mpx;
c->w = stackw - 2 * BORDERPX;
if(th > bh) {
c->y = way + (i - 1) * th;
c->h = th - 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);
@ -162,7 +154,6 @@ focusnext(Arg *arg) {
if(!sel)
return;
if(!(c = getnext(sel->next)))
c = getnext(clients);
if(c) {
@ -177,7 +168,6 @@ focusprev(Arg *arg) {
if(!sel)
return;
if(!(c = getprev(sel->prev))) {
for(c = clients; c && c->next; c = c->next);
c = getprev(c);
@ -199,27 +189,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(mw + arg->i > sw - 100 || mw + arg->i < 100)
return;
mw += arg->i;
}
resizemaster(Arg *arg) {
if(arg->i == 0)
master = MASTER;
else {
if(mw - arg->i > sw - 100 || mw - arg->i < 100)
if(master + arg->i > 950 || master + arg->i < 50)
return;
mw -= arg->i;
master += arg->i;
}
arrange(NULL);
arrange();
}
void
@ -235,11 +213,18 @@ restack(void) {
XRaiseWindow(dpy, sel->win);
XRaiseWindow(dpy, sel->twin);
}
if(arrange != dofloat)
if(arrange != dofloat) {
if(!sel->isfloat) {
XLowerWindow(dpy, sel->twin);
XLowerWindow(dpy, sel->win);
}
for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
if(c == sel)
continue;
XLowerWindow(dpy, c->twin);
XLowerWindow(dpy, c->win);
}
}
drawall();
XSync(dpy, False);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
@ -249,7 +234,7 @@ void
togglemode(Arg *arg) {
arrange = (arrange == dofloat) ? dotile : dofloat;
if(sel)
arrange(NULL);
arrange();
else
drawstatus();
}
@ -263,7 +248,7 @@ toggleview(Arg *arg) {
if(i == ntags)
seltag[arg->i] = True; /* cannot toggle last view */
reorder();
arrange(NULL);
arrange();
}
void
@ -274,7 +259,7 @@ view(Arg *arg) {
seltag[i] = False;
seltag[arg->i] = True;
reorder();
arrange(NULL);
arrange();
}
void
@ -284,7 +269,7 @@ viewall(Arg *arg) {
for(i = 0; i < ntags; i++)
seltag[i] = True;
reorder();
arrange(NULL);
arrange();
}
void
@ -294,18 +279,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;
@ -315,5 +297,5 @@ zoom(Arg *arg) {
c->next = clients;
clients = c;
focus(c);
arrange(NULL);
arrange();
}