Compare commits

...

24 Commits
4.8 ... 4.9

Author SHA1 Message Date
0e21794e02 yet another cleanup 2008-04-03 14:39:19 +01:00
d477fb6927 some cleanup changes 2008-04-03 14:38:58 +01:00
3d6630b7d2 uncommented dual layout in preparation of dwm 4.9 2008-04-02 22:18:09 +01:00
c982bb1389 applied Peter Hartlich's simplification patch of setmfact and his revival of MFACT, appliead Janness Hofmann's simplification of grabbuttons() -- thanks guys! 2008-04-02 22:10:55 +01:00
6cf73e706a aspects hints seem broken for fullscreen apps 2008-04-01 15:46:00 +01:00
a520ba3c0b removed uneccessary line 2008-03-31 10:09:48 +01:00
0c71b16b92 bugfix 2008-03-25 09:41:14 +00:00
00c28a7ef2 setmfact should not have any effect if in floating layout 2008-03-24 14:31:02 +00:00
5a3a2d6b63 minor fix 2008-03-24 14:24:57 +00:00
a355782a77 revival of mfact and setmfact 2008-03-24 14:23:28 +00:00
20cd336087 setlayout and setgeom are now togglable again 2008-03-24 13:49:19 +00:00
a6a216f28c geom indicator and layout indicator is only displayed if there are several geoms/layouts 2008-03-24 13:33:32 +00:00
2c2063bc75 hotfix of idxoftag 2008-03-22 16:53:37 +00:00
e6ede461a9 blw/bgw calculation bugfix 2008-03-22 12:47:12 +00:00
6877205e9d updated configurenotify 2008-03-19 09:27:17 +00:00
fb5f99d935 minor bugfix in applyrules 2008-03-17 23:45:46 +00:00
7ebab7533a added sample of {grow,shrink}master to config.def.h 2008-03-17 17:33:25 +00:00
9fa5ca3538 renamed c->border into c->bw, fixed monocle to subtract c->bw from each h/w value 2008-03-17 16:29:50 +00:00
fe6b0c0fc1 geoms are now drawed in the status bar 2008-03-17 16:26:06 +00:00
aa2395b6a8 removed the string-based setgeom approach, introduced a new Geom type instead and a helper macro 2008-03-17 14:56:11 +00:00
dba22848c7 made the string-based setgeom working 2008-03-15 14:17:42 +00:00
33b1960220 some experimental state DO NOT USE THIS, I plan to have a nicer interface to change geometries 2008-03-14 17:17:08 +00:00
e237b2a76f some changes towards 4.9 2008-03-14 14:35:45 +00:00
dd9ee6d248 Added tag 4.8 for changeset 607015ddb091 2008-03-13 16:56:11 +00:00
7 changed files with 198 additions and 317 deletions

View File

@ -51,3 +51,4 @@ e0ec0d5d8b1ef3ee04a83c7c0fee5853aa2ac6a6 4.3
2acc60d6dfe28c101a8cd44a8aa710a38ae3607c 4.5
bcd7e18e196a00cc2e97ff3a4a58f3cdaba13856 4.6
d6d3085307d8d98b8b012b669e858fd787befeb1 4.7
607015ddb091d49cbd3457af41713691aa69f4d6 4.8

View File

@ -35,7 +35,7 @@ clean:
dist: clean
@echo creating dist tarball
@mkdir -p dwm-${VERSION}
@cp -R LICENSE Makefile README config.*.h config.mk \
@cp -R LICENSE Makefile README config.def.h config.mk \
dwm.1 ${SRC} dwm-${VERSION}
@tar -cf dwm-${VERSION}.tar dwm-${VERSION}
@gzip dwm-${VERSION}.tar

View File

@ -1,151 +0,0 @@
/* See LICENSE file for copyright and license details. */
/* appearance */
#define BORDERPX 1
#define FONT "-*-terminus-medium-r-normal-*-14-*-*-*-*-*-*-*"
#define NORMBORDERCOLOR "#cccccc"
#define NORMBGCOLOR "#cccccc"
#define NORMFGCOLOR "#000000"
#define SELBORDERCOLOR "#0066ff"
#define SELBGCOLOR "#0066ff"
#define SELFGCOLOR "#ffffff"
/* tagging */
const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
Rule rules[] = {
/* class:instance:title substr tags ref isfloating */
{ "Firefox", tags[8], False },
{ "Gimp", NULL, True },
{ "MPlayer", NULL, True },
{ "Acroread", NULL, True },
};
/* layout(s) */
#define RESIZEHINTS True /* False - respect size hints in tiled resizals */
#define SNAP 32 /* snap pixel */
Layout layouts[] = {
/* symbol function isfloating */
{ "[]|", tileh, False }, /* first entry is default */
{ "[]=", tilev, False },
{ "><>", floating, True },
{ "[M]", monocle, True },
};
void
setanselmgeoms(void) {
/* screen dimensions */
sx = 0;
sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
/* bar position */
bx = sx;
by = sy;
bw = 1280;
bh = dc.font.height + 2;
/* window area */
wx = sx;
wy = sy + bh;
ww = sw;
wh = sh - bh;
/* master area */
mx = wx;
my = wy;
mw = 1280;
mh = 800 - bh;
/* tile area */
tx = 1280;
ty = 0;
tw = sw - 1280;
th = sh;
/* monocle area */
mox = mx;
moy = my;
mow = mw;
moh = mh;
}
void
anselmgeoms(const char *arg) {
setgeoms = setanselmgeoms;
setgeoms();
updatebarpos();
setlayout("[]|");
}
void
defgeoms(const char *arg) {
setgeoms = setdefaultgeoms;
setgeoms();
updatebarpos();
setlayout("[]=");
}
/* key definitions */
#define MODKEY Mod1Mask
Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn,
"exec dmenu_run -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"' -x 0 -y 0 -w 1280" },
{ MODKEY|ShiftMask, XK_Return, spawn, "exec uxterm" },
{ MODKEY, XK_a, anselmgeoms, NULL },
{ MODKEY, XK_d, defgeoms, NULL },
{ MODKEY, XK_j, focusnext, NULL },
{ MODKEY, XK_k, focusprev, NULL },
{ MODKEY, XK_r, reapply, NULL },
{ MODKEY, XK_Return, zoom, NULL },
{ MODKEY, XK_Tab, viewprevtag, NULL },
{ MODKEY, XK_m, setlayout, "[M]" },
{ MODKEY, XK_f, setlayout, "><>" },
{ MODKEY, XK_v, setlayout, "[]=" },
{ MODKEY, XK_h, setlayout, "[]|" },
{ MODKEY|ShiftMask, XK_space, togglefloating, NULL },
{ MODKEY|ShiftMask, XK_c, killclient, NULL },
{ MODKEY, XK_0, view, NULL },
{ MODKEY, XK_1, view, tags[0] },
{ MODKEY, XK_2, view, tags[1] },
{ MODKEY, XK_3, view, tags[2] },
{ MODKEY, XK_4, view, tags[3] },
{ MODKEY, XK_5, view, tags[4] },
{ MODKEY, XK_6, view, tags[5] },
{ MODKEY, XK_7, view, tags[6] },
{ MODKEY, XK_8, view, tags[7] },
{ MODKEY, XK_9, view, tags[8] },
{ MODKEY|ControlMask, XK_1, toggleview, tags[0] },
{ MODKEY|ControlMask, XK_2, toggleview, tags[1] },
{ MODKEY|ControlMask, XK_3, toggleview, tags[2] },
{ MODKEY|ControlMask, XK_4, toggleview, tags[3] },
{ MODKEY|ControlMask, XK_5, toggleview, tags[4] },
{ MODKEY|ControlMask, XK_6, toggleview, tags[5] },
{ MODKEY|ControlMask, XK_7, toggleview, tags[6] },
{ MODKEY|ControlMask, XK_8, toggleview, tags[7] },
{ MODKEY|ControlMask, XK_9, toggleview, tags[8] },
{ MODKEY|ShiftMask, XK_0, tag, NULL },
{ MODKEY|ShiftMask, XK_1, tag, tags[0] },
{ MODKEY|ShiftMask, XK_2, tag, tags[1] },
{ MODKEY|ShiftMask, XK_3, tag, tags[2] },
{ MODKEY|ShiftMask, XK_4, tag, tags[3] },
{ MODKEY|ShiftMask, XK_5, tag, tags[4] },
{ MODKEY|ShiftMask, XK_6, tag, tags[5] },
{ MODKEY|ShiftMask, XK_7, tag, tags[6] },
{ MODKEY|ShiftMask, XK_8, tag, tags[7] },
{ MODKEY|ShiftMask, XK_9, tag, tags[8] },
{ MODKEY|ControlMask|ShiftMask, XK_1, toggletag, tags[0] },
{ MODKEY|ControlMask|ShiftMask, XK_2, toggletag, tags[1] },
{ MODKEY|ControlMask|ShiftMask, XK_3, toggletag, tags[2] },
{ MODKEY|ControlMask|ShiftMask, XK_4, toggletag, tags[3] },
{ MODKEY|ControlMask|ShiftMask, XK_5, toggletag, tags[4] },
{ MODKEY|ControlMask|ShiftMask, XK_6, toggletag, tags[5] },
{ MODKEY|ControlMask|ShiftMask, XK_7, toggletag, tags[6] },
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, tags[7] },
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, tags[8] },
{ MODKEY|ShiftMask, XK_q, quit, NULL },
};

View File

@ -14,11 +14,18 @@
const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
Rule rules[] = {
/* class:instance:title substr tags ref isfloating */
{ "Firefox", tags[8], False },
{ "Gimp", NULL, True },
{ "MPlayer", NULL, True },
{ "Acroread", NULL, True },
/* class instance title tags ref isfloating */
{ "Gimp", NULL, NULL, NULL, True },
};
/* geometries, s{x,y,w,h} and bh are already initualized here */
/* func name bx by bw wx wy ww wh mx my mw mh tx ty tw th mox moy mow moh */
#define MFACT 0.55 /* master width factor [0.1 .. 0.9] */
DEFGEOM(single, 0, 0, sw, 0, bh, sw, sh-bh, wx, wy, mfact*sw, wh, mx+mw, wy, ww-mw, wh, wx, wy, ww, wh)
Geom geoms[] = {
/* symbol function */
{ "[]", single }, /* first entry is default */
};
/* layout(s) */
@ -39,18 +46,18 @@ Key keys[] = {
/* modifier key function argument */
{ MODKEY, XK_p, spawn,
"exec dmenu_run -fn '"FONT"' -nb '"NORMBGCOLOR"' -nf '"NORMFGCOLOR"' -sb '"SELBGCOLOR"' -sf '"SELFGCOLOR"'" },
{ MODKEY|ShiftMask, XK_Return, spawn, "exec uxterm" },
{ MODKEY|ShiftMask, XK_Return, spawn, "exec uxterm" },
{ MODKEY, XK_j, focusnext, NULL },
{ MODKEY, XK_k, focusprev, NULL },
{ MODKEY, XK_r, reapply, NULL },
{ MODKEY, XK_h, setmfact, "-0.05" },
{ MODKEY, XK_l, setmfact, "+0.05" },
{ MODKEY, XK_Return, zoom, NULL },
{ MODKEY, XK_Tab, viewprevtag, NULL },
{ MODKEY, XK_m, setlayout, "[M]" },
{ MODKEY, XK_f, setlayout, "><>" },
{ MODKEY, XK_v, setlayout, "[]=" },
{ MODKEY, XK_h, setlayout, "[]|" },
{ MODKEY|ShiftMask, XK_space, togglefloating, NULL },
{ MODKEY|ShiftMask, XK_c, killclient, NULL },
{ MODKEY, XK_space, setlayout, NULL },
{ MODKEY|ShiftMask, XK_space, togglefloating, NULL },
{ MODKEY|ControlMask, XK_space, setgeom, NULL },
{ MODKEY, XK_0, view, NULL },
{ MODKEY, XK_1, view, tags[0] },
{ MODKEY, XK_2, view, tags[1] },

View File

@ -1,5 +1,5 @@
# dwm version
VERSION = 4.8
VERSION = 4.9
# Customize below to fit your system
@ -17,13 +17,12 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = -s ${LIBS}
#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -DWORK
#CFLAGS = -g -std=c99 -pedantic -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = ${LIBS}
#CFLAGS += -xtarget=ultra
# compiler and linker
CC = cc

20
dwm.1
View File

@ -57,17 +57,11 @@ click on a tag label adds/removes that tag to/from the focused window.
Start
.BR xterm.
.TP
.B Mod1\-f
Applies floating layout.
.B Mod1\-space
Toggles between layouts.
.TP
.B Mod1\-m
Applies monocle layout.
.TP
.B Mod1\-v
Applies vertical tiled layout.
.TP
.B Mod1\-h
Applies horizontal tiled layout.
.B Mod1\-Control\-space
Toggles between geometries.
.TP
.B Mod1\-j
Focus next window.
@ -75,6 +69,12 @@ Focus next window.
.B Mod1\-k
Focus previous window.
.TP
.B Mod1\-h
Decrease master area size.
.TP
.B Mod1\-l
Increase master area size.
.TP
.B Mod1\-Return
Zooms/cycles focused window to/from master area (tiled layouts only).
.TP

307
dwm.c
View File

@ -46,6 +46,14 @@
#define LENGTH(x) (sizeof x / sizeof x[0])
#define MAXTAGLEN 16
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define DEFGEOM(GEONAME,BX,BY,BW,WX,WY,WW,WH,MX,MY,MW,MH,TX,TY,TW,TH,MOX,MOY,MOW,MOH) \
void GEONAME(void) { \
bx = (BX); by = (BY); bw = (BW); \
wx = (WX); wy = (WY); ww = (WW); wh = (WH); \
mx = (MX); my = (MY); mw = (MW); mh = (MH); \
tx = (TX); ty = (TY); tw = (TW); th = (TH); \
mox = (MOX); moy = (MOY); mow = (MOW); moh = (MOH); \
}
/* enums */
enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
@ -61,7 +69,7 @@ struct Client {
int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int minax, maxax, minay, maxay;
long flags;
unsigned int border, oldborder;
unsigned int bw, oldbw;
Bool isbanned, isfixed, isfloating, isurgent;
Bool *tags;
Client *next;
@ -85,6 +93,11 @@ typedef struct {
} font;
} DC; /* draw context */
typedef struct {
const char *symbol;
void (*apply)(void);
} Geom;
typedef struct {
unsigned long mod;
KeySym keysym;
@ -99,7 +112,9 @@ typedef struct {
} Layout;
typedef struct {
const char *prop;
const char *class;
const char *instance;
const char *title;
const char *tag;
Bool isfloating;
} Rule;
@ -161,8 +176,9 @@ void restack(void);
void run(void);
void scan(void);
void setclientstate(Client *c, long state);
void setdefaultgeoms(void);
void setgeom(const char *arg);
void setlayout(const char *arg);
void setmfact(const char *arg);
void setup(void);
void spawn(const char *arg);
void tag(const char *arg);
@ -195,7 +211,8 @@ void zoom(const char *arg);
char stext[256], buf[256];
int screen, sx, sy, sw, sh;
int (*xerrorxlib)(Display *, XErrorEvent *);
int bx, by, bw, bh, blw, mx, my, mw, mh, mox, moy, mow, moh, tx, ty, tw, th, wx, wy, ww, wh;
int bx, by, bw, bh, blw, bgw, mx, my, mw, mh, mox, moy, mow, moh, tx, ty, tw, th, wx, wy, ww, wh;
double mfact;
unsigned int numlockmask = 0;
void (*handler[LASTEvent]) (XEvent *) = {
[ButtonPress] = buttonpress,
@ -222,9 +239,9 @@ Client *stack = NULL;
Cursor cursor[CurLast];
Display *dpy;
DC dc = {0};
Geom *geom = NULL;
Layout *lt = NULL;
Window root, barwin;
void (*setgeoms)(void) = setdefaultgeoms;
/* configuration, allows nested code to access above variables */
#include "config.h"
@ -244,9 +261,9 @@ applyrules(Client *c) {
XGetClassHint(dpy, c->win, &ch);
for(i = 0; i < LENGTH(rules); i++) {
r = &rules[i];
if(strstr(c->name, r->prop)
|| (ch.res_class && strstr(ch.res_class, r->prop))
|| (ch.res_name && strstr(ch.res_name, r->prop)))
if((r->title && strstr(c->name, r->title))
|| (ch.res_class && r->class && strstr(ch.res_class, r->class))
|| (ch.res_name && r->instance && strstr(ch.res_name, r->instance)))
{
c->isfloating = r->isfloating;
if(r->tag) {
@ -307,10 +324,14 @@ buttonpress(XEvent *e) {
XButtonPressedEvent *ev = &e->xbutton;
if(ev->window == barwin) {
x = 0;
if((ev->x < bgw) && ev->button == Button1) {
setgeom(NULL);
return;
}
x = bgw;
for(i = 0; i < LENGTH(tags); i++) {
x += textw(tags[i]);
if(ev->x < x) {
if(ev->x >= bgw && ev->x < x) {
if(ev->button == Button1) {
if(ev->state & MODKEY)
tag(tags[i]);
@ -326,6 +347,8 @@ buttonpress(XEvent *e) {
return;
}
}
if((ev->x < x + blw) && ev->button == Button1)
setlayout(NULL);
}
else if((c = getclient(ev->window))) {
focus(c);
@ -398,7 +421,7 @@ configure(Client *c) {
ce.y = c->y;
ce.width = c->w;
ce.height = c->h;
ce.border_width = c->border;
ce.border_width = c->bw;
ce.above = None;
ce.override_redirect = False;
XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce);
@ -409,9 +432,9 @@ configurenotify(XEvent *e) {
XConfigureEvent *ev = &e->xconfigure;
if(ev->window == root && (ev->width != sw || ev->height != sh)) {
setgeoms();
updatebarpos();
arrange();
sw = ev->width;
sh = ev->height;
setgeom(geom->symbol);
}
}
@ -423,7 +446,7 @@ configurerequest(XEvent *e) {
if((c = getclient(ev->window))) {
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
c->bw = ev->border_width;
if(c->isfixed || c->isfloating || lt->isfloating) {
if(ev->value_mask & CWX)
c->x = sx + ev->x;
@ -502,6 +525,11 @@ drawbar(void) {
Client *c;
dc.x = 0;
if(bgw > 0) {
dc.w = bgw;
drawtext(geom->symbol, dc.norm, False);
dc.x += bgw;
}
for(c = stack; c && !isvisible(c); c = c->snext);
for(i = 0; i < LENGTH(tags); i++) {
dc.w = textw(tags[i]);
@ -515,9 +543,13 @@ drawbar(void) {
}
dc.x += dc.w;
}
dc.w = blw;
drawtext(lt->symbol, dc.norm, False);
x = dc.x + dc.w;
if(blw > 0) {
dc.w = blw;
drawtext(lt->symbol, dc.norm, False);
x = dc.x + dc.w;
}
else
x = dc.x;
dc.w = textw(stext);
dc.x = bw - dc.w;
if(dc.x < x) {
@ -774,39 +806,20 @@ gettextprop(Window w, Atom atom, char *text, unsigned int size) {
void
grabbuttons(Client *c, Bool focused) {
int i, j;
unsigned int buttons[] = { Button1, Button2, Button3 };
unsigned int modifiers[] = { MODKEY, MODKEY|LockMask, MODKEY|numlockmask,
MODKEY|numlockmask|LockMask} ;
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused) {
XGrabButton(dpy, Button1, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY|numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button1, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY|numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button2, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY|numlockmask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, Button3, MODKEY|numlockmask|LockMask, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
}
if(focused)
for(i = 0; i < LENGTH(buttons); i++)
for(j = 0; j < LENGTH(modifiers); j++)
XGrabButton(dpy, buttons[i], modifiers[j], c->win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK,
GrabModeAsync, GrabModeSync, None, None);
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
}
void
@ -842,7 +855,7 @@ unsigned int
idxoftag(const char *t) {
unsigned int i;
for(i = 0; (i < LENGTH(tags)) && (tags[i] != t); i++);
for(i = 0; (i < LENGTH(tags)) && t && strcmp(tags[i], t); i++);
return (i < LENGTH(tags)) ? i : 0;
}
@ -985,25 +998,25 @@ manage(Window w, XWindowAttributes *wa) {
c->y = wa->y;
c->w = wa->width;
c->h = wa->height;
c->oldborder = wa->border_width;
c->oldbw = wa->border_width;
if(c->w == sw && c->h == sh) {
c->x = sx;
c->y = sy;
c->border = wa->border_width;
c->bw = wa->border_width;
}
else {
if(c->x + c->w + 2 * c->border > wx + ww)
c->x = wx + ww - c->w - 2 * c->border;
if(c->y + c->h + 2 * c->border > wy + wh)
c->y = wy + wh - c->h - 2 * c->border;
if(c->x + c->w + 2 * c->bw > wx + ww)
c->x = wx + ww - c->w - 2 * c->bw;
if(c->y + c->h + 2 * c->bw > wy + wh)
c->y = wy + wh - c->h - 2 * c->bw;
if(c->x < wx)
c->x = wx;
if(c->y < wy)
c->y = wy;
c->border = BORDERPX;
c->bw = BORDERPX;
}
wc.border_width = c->border;
wc.border_width = c->bw;
XConfigureWindow(dpy, w, CWBorderWidth, &wc);
XSetWindowBorder(dpy, w, dc.norm[ColBorder]);
configure(c); /* propagates border_width, if size doesn't change */
@ -1051,12 +1064,12 @@ maprequest(XEvent *e) {
}
void
monocle(void) {
monocle(void) {
Client *c;
for(c = clients; c; c = c->next)
if(isvisible(c))
resize(c, mox, moy, mow, moh, RESIZEHINTS);
resize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw, RESIZEHINTS);
}
void
@ -1089,12 +1102,12 @@ movemouse(Client *c) {
ny = ocy + (ev.xmotion.y - y1);
if(abs(wx - nx) < SNAP)
nx = wx;
else if(abs((wx + ww) - (nx + c->w + 2 * c->border)) < SNAP)
nx = wx + ww - c->w - 2 * c->border;
else if(abs((wx + ww) - (nx + c->w + 2 * c->bw)) < SNAP)
nx = wx + ww - c->w - 2 * c->bw;
if(abs(wy - ny) < SNAP)
ny = wy;
else if(abs((wy + wh) - (ny + c->h + 2 * c->border)) < SNAP)
ny = wy + wh - c->h - 2 * c->border;
else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < SNAP)
ny = wy + wh - c->h - 2 * c->bw;
if(!c->isfloating && !lt->isfloating && (abs(nx - c->x) > SNAP || abs(ny - c->y) > SNAP))
togglefloating(NULL);
if((lt->isfloating) || c->isfloating)
@ -1165,9 +1178,9 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
if(sizehints) {
/* set minimum possible */
if (w < 1)
if(w < 1)
w = 1;
if (h < 1)
if(h < 1)
h = 1;
/* temporarily remove base dimensions */
@ -1175,10 +1188,12 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
h -= c->baseh;
/* adjust for aspect limits */
if (c->minay > 0 && c->maxay > 0 && c->minax > 0 && c->maxax > 0) {
if (w * c->maxay > h * c->maxax)
if(c->minax != c->maxax && c->minay != c->maxay
&& c->minax > 0 && c->maxax > 0 && c->minay > 0 && c->maxay > 0)
{
if(w * c->maxay > h * c->maxax)
w = h * c->maxax / c->maxay;
else if (w * c->minay < h * c->minax)
else if(w * c->minay < h * c->minax)
h = w * c->minay / c->minax;
}
@ -1204,19 +1219,19 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
if(w <= 0 || h <= 0)
return;
if(x > sx + sw)
x = sw - w - 2 * c->border;
x = sw - w - 2 * c->bw;
if(y > sy + sh)
y = sh - h - 2 * c->border;
if(x + w + 2 * c->border < sx)
y = sh - h - 2 * c->bw;
if(x + w + 2 * c->bw < sx)
x = sx;
if(y + h + 2 * c->border < sy)
if(y + h + 2 * c->bw < sy)
y = sy;
if(c->x != x || c->y != y || c->w != w || c->h != h) {
c->x = wc.x = x;
c->y = wc.y = y;
c->w = wc.width = w;
c->h = wc.height = h;
wc.border_width = c->border;
wc.border_width = c->bw;
XConfigureWindow(dpy, c->win,
CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc);
configure(c);
@ -1235,13 +1250,13 @@ resizemouse(Client *c) {
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurResize], CurrentTime) != GrabSuccess)
return;
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->border - 1, c->h + c->border - 1);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1);
for(;;) {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask , &ev);
switch(ev.type) {
case ButtonRelease:
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0,
c->w + c->border - 1, c->h + c->border - 1);
c->w + c->bw - 1, c->h + c->bw - 1);
XUngrabPointer(dpy, CurrentTime);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
return;
@ -1252,9 +1267,9 @@ resizemouse(Client *c) {
break;
case MotionNotify:
XSync(dpy, False);
if((nw = ev.xmotion.x - ocx - 2 * c->border + 1) <= 0)
if((nw = ev.xmotion.x - ocx - 2 * c->bw + 1) <= 0)
nw = 1;
if((nh = ev.xmotion.y - ocy - 2 * c->border + 1) <= 0)
if((nh = ev.xmotion.y - ocy - 2 * c->bw + 1) <= 0)
nh = 1;
if(!c->isfloating && !lt->isfloating && (abs(nw - c->w) > SNAP || abs(nh - c->h) > SNAP))
togglefloating(NULL);
@ -1390,61 +1405,40 @@ setclientstate(Client *c, long state) {
}
void
setdefaultgeoms(void) {
setgeom(const char *arg) {
unsigned int i;
/* screen dimensions */
sx = 0;
sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
/* bar position */
bx = sx;
by = sy;
bw = sw;
bh = dc.font.height + 2;
/* window area */
wx = sx;
wy = sy + bh;
ww = sw;
wh = sh - bh;
/* master area */
mx = wx;
my = wy;
mw = ((float)sw) * 0.55;
mh = wh;
/* tile area */
tx = mx + mw;
ty = wy;
tw = ww - mw;
th = wh;
/* monocle area */
mox = wx;
moy = wy;
mow = ww;
moh = wh;
if(!arg) {
if(++geom == &geoms[LENGTH(geoms)])
geom = &geoms[0];
}
else {
for(i = 0; i < LENGTH(geoms); i++)
if(!strcmp(geoms[i].symbol, arg))
break;
if(i == LENGTH(geoms))
return;
geom = &geoms[i];
}
geom->apply();
updatebarpos();
arrange();
}
void
setlayout(const char *arg) {
static Layout *revert = 0;
unsigned int i;
if(!arg)
return;
for(i = 0; i < LENGTH(layouts); i++)
if(!strcmp(arg, layouts[i].symbol))
break;
if(i == LENGTH(layouts))
return;
if(revert && &layouts[i] == lt)
lt = revert;
if(!arg) {
if(++lt == &layouts[LENGTH(layouts)])
lt = &layouts[0];
}
else {
revert = lt;
for(i = 0; i < LENGTH(layouts); i++)
if(!strcmp(arg, layouts[i].symbol))
break;
if(i == LENGTH(layouts))
return;
lt = &layouts[i];
}
if(sel)
@ -1453,9 +1447,28 @@ setlayout(const char *arg) {
drawbar();
}
void
setmfact(const char *arg) {
double d;
if(lt->isfloating)
return;
if(!arg)
mfact = MFACT;
else {
d = strtod(arg, NULL);
if(arg[0] == '-' || arg[0] == '+')
d += mfact;
if(d < 0.1 || d > 0.9)
return;
mfact = d;
}
setgeom(geom->symbol);
}
void
setup(void) {
unsigned int i;
unsigned int i, w;
XSetWindowAttributes wa;
/* init screen */
@ -1463,8 +1476,15 @@ setup(void) {
root = RootWindow(dpy, screen);
initfont(FONT);
/* apply default geometries */
setgeoms();
/* apply default geometry */
sx = 0;
sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
bh = dc.font.height + 2;
mfact = MFACT;
geom = &geoms[0];
geom->apply();
/* init atoms */
wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False);
@ -1503,10 +1523,15 @@ setup(void) {
lt = &layouts[0];
/* init bar */
for(blw = i = 0; i < LENGTH(layouts); i++) {
i = textw(layouts[i].symbol);
if(i > blw)
blw = i;
for(blw = i = 0; LENGTH(layouts) > 1 && i < LENGTH(layouts); i++) {
w = textw(layouts[i].symbol);
if(w > blw)
blw = w;
}
for(bgw = i = 0; LENGTH(geoms) > 1 && i < LENGTH(geoms); i++) {
w = textw(geoms[i].symbol);
if(w > bgw)
bgw = w;
}
wa.override_redirect = 1;
@ -1607,11 +1632,11 @@ tileh(void) {
for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
if(i + 1 == n) /* remainder */
tileresize(c, x, ty, (tx + tw) - x - 2 * c->border, th - 2 * c->border);
tileresize(c, x, ty, (tx + tw) - x - 2 * c->bw, th - 2 * c->bw);
else
tileresize(c, x, ty, w - 2 * c->border, th - 2 * c->border);
tileresize(c, x, ty, w - 2 * c->bw, th - 2 * c->bw);
if(w != tw)
x = c->x + c->w + 2 * c->border;
x = c->x + c->w + 2 * c->bw;
}
}
@ -1620,9 +1645,9 @@ tilemaster(unsigned int n) {
Client *c = nexttiled(clients);
if(n == 1)
tileresize(c, mox, moy, mow - 2 * c->border, moh - 2 * c->border);
tileresize(c, mox, moy, mow - 2 * c->bw, moh - 2 * c->bw);
else
tileresize(c, mx, my, mw - 2 * c->border, mh - 2 * c->border);
tileresize(c, mx, my, mw - 2 * c->bw, mh - 2 * c->bw);
return c;
}
@ -1653,11 +1678,11 @@ tilev(void) {
for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) {
if(i + 1 == n) /* remainder */
tileresize(c, tx, y, tw - 2 * c->border, (ty + th) - y - 2 * c->border);
tileresize(c, tx, y, tw - 2 * c->bw, (ty + th) - y - 2 * c->bw);
else
tileresize(c, tx, y, tw - 2 * c->border, h - 2 * c->border);
tileresize(c, tx, y, tw - 2 * c->bw, h - 2 * c->bw);
if(h != th)
y = c->y + c->h + 2 * c->border;
y = c->y + c->h + 2 * c->bw;
}
}
@ -1709,7 +1734,7 @@ void
unmanage(Client *c) {
XWindowChanges wc;
wc.border_width = c->oldborder;
wc.border_width = c->oldbw;
/* The server grab construct avoids race conditions. */
XGrabServer(dpy);
XSetErrorHandler(xerrordummy);