introduced Layout struct

This commit is contained in:
Anselm R. Garbe 2007-02-19 16:40:36 +01:00
parent b2f895166a
commit cdbc84b9a8
9 changed files with 115 additions and 82 deletions

View file

@ -263,7 +263,7 @@ manage(Window w, XWindowAttributes *wa) {
setclientstate(c, NormalState);
if(isvisible(c))
focus(c);
arrange();
lt->arrange();
}
Client *
@ -430,7 +430,7 @@ unmanage(Client *c) {
XSync(dpy, False);
XSetErrorHandler(xerror);
XUngrabServer(dpy);
arrange();
lt->arrange();
}
void
@ -440,7 +440,7 @@ zoom(Arg *arg) {
if(!sel)
return;
if(sel->isfloat || (arrange == dofloat)) {
if(sel->isfloat || (lt->arrange == dofloat)) {
togglemax(sel);
return;
}
@ -452,5 +452,5 @@ zoom(Arg *arg) {
detach(c);
attach(c);
focus(c);
arrange();
lt->arrange();
}

View file

@ -5,9 +5,12 @@
#define TAGS \
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define TILESYMBOL "[]="
#define LAYOUTS \
static Layout layout[] = { \
/* symbol function */ \
{ "[]=", dotile }, /* first entry is default */ \
{ "><>", dofloat }, \
};
#define BORDERPX 1
#define FONT "-*-terminus-medium-r-*-*-14-*-*-*-*-*-*-*"
@ -60,7 +63,7 @@ static Key key[] = { \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_space, togglelayout, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \

View file

@ -5,9 +5,12 @@
#define TAGS \
const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
#define DEFMODE dotile /* dofloat */
#define FLOATSYMBOL "><>"
#define TILESYMBOL "[]="
#define LAYOUTS \
Layout layout[] = { \
/* symbol function */ \
{ "[]=", dotile }, /* first entry is default */ \
{ "><>", dofloat }, \
};
#define BORDERPX 1
#define FONT "-*-fixed-medium-r-normal-*-13-*-*-*-*-*-*-*"
@ -55,7 +58,7 @@ static Key key[] = { \
{ MODKEY|ControlMask|ShiftMask, XK_8, toggletag, { .i = 7 } }, \
{ MODKEY|ControlMask|ShiftMask, XK_9, toggletag, { .i = 8 } }, \
{ MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \
{ MODKEY, XK_space, togglemode, { 0 } }, \
{ MODKEY, XK_space, togglelayout, { 0 } }, \
{ MODKEY|ShiftMask, XK_space, togglefloat, { 0 } }, \
{ MODKEY, XK_0, view, { .i = -1 } }, \
{ MODKEY, XK_1, view, { .i = 0 } }, \

View file

@ -17,8 +17,8 @@ LIBS = -L/usr/lib -lc -L${X11LIB} -lX11
# flags
CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = ${LIBS}
#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
#LDFLAGS = -g ${LIBS}
CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\"
LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"

38
dwm.1
View file

@ -6,19 +6,19 @@ dwm \- dynamic window manager
.RB [ \-v ]
.SH DESCRIPTION
dwm is a dynamic window manager for X. It manages windows in tiling and
floating modes. Either mode can be applied dynamically, optimizing the
floating layouts. Either layout 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 area. The master
In tiling layout windows are managed in a master and stacking area. The master
area contains the windows which currently need most attention, whereas the
stacking area contains all other windows. In floating mode windows can be
stacking area contains all other windows. In floating layout windows can be
resized and moved freely. Dialog windows are always managed floating,
regardless of the mode applied.
regardless of the layout applied.
.P
Windows are grouped by tags. Each window can be tagged with one or multiple
tags. Selecting certain tags displays all windows with these tags.
.P
dwm contains a small status bar which displays all available tags, the mode,
dwm contains a small status bar which displays all available tags, the layout,
the title of the focused window, and the text read from standard input. The
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
@ -37,17 +37,17 @@ prints version information to standard output, then exits.
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 tiling and floating mode.
click on a tag label to display all windows with that tag, click on the layout
label toggles between tiling and floating layout.
.TP
.B Button3
click on a tag label adds/removes all windows with that tag to/from the view.
.TP
.B Button4
click on the mode label increases the number of windows in the master area (tiling mode only).
click on the layout label increases the number of windows in the master area (tiling layout only).
.TP
.B Button5
click on the mode label decreases the number of windows in the master area (tiling mode only).
click on the layout label decreases the number of windows in the master area (tiling layout only).
.TP
.B Mod1-Button1
click on a tag label applies that tag to the focused window.
@ -67,19 +67,19 @@ Focus next window.
Focus previous window.
.TP
.B Mod1-Return
Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (floating layout).
.TP
.B Mod1-g
Grow master area (tiling mode only).
Grow master area (tiling layout only).
.TP
.B Mod1-s
Shrink master area (tiling mode only).
Shrink master area (tiling layout only).
.TP
.B Mod1-i
Increase the number of windows in the master area (tiling mode only).
Increase the number of windows in the master area (tiling layout only).
.TP
.B Mod1-d
Decrease the number of windows in the master area (tiling mode only).
Decrease the number of windows in the master area (tiling layout only).
.TP
.B Mod1-Shift-[1..n]
Apply
@ -98,10 +98,10 @@ tag to/from current window.
Close focused window.
.TP
.B Mod1-space
Toggle between tiling and floating mode (affects all windows).
Toggle between tiling and floating layout (affects all windows).
.TP
.B Mod1-Shift-space
Toggle focused window between floating and non-floating state (tiling mode only).
Toggle focused window between floating and non-floating state (tiling layout only).
.TP
.B Mod1-[1..n]
View all windows with
@ -121,13 +121,13 @@ Quit dwm.
.SS Mouse commands
.TP
.B Mod1-Button1
Move current window while dragging (floating mode only).
Move current window while dragging (floating layout only).
.TP
.B Mod1-Button2
Zooms/cycles current window to/from master area (tiling mode), toggles maximization of current window (floating mode).
Zooms/cycles current window to/from master area (tiling layout), toggles maximization of current window (floating layout).
.TP
.B Mod1-Button3
Resize current window while dragging (floating mode only).
Resize current window while dragging (floating layout only).
.SH CUSTOMIZATION
dwm is customized by creating a custom config.h and (re)compiling the source
code. This keeps it fast, secure and simple.

19
dwm.h
View file

@ -24,9 +24,8 @@
*
* Keys and tagging rules are organized as arrays and defined in the config.h
* file. These arrays are kept static in event.o and tag.o respectively,
* because no other part of dwm needs access to them. The current mode is
* represented by the arrange() function pointer, which wether points to
* dofloat() or dotile().
* because no other part of dwm needs access to them. The current layout is
* represented by the lt pointer.
*
* To understand everything else, start reading main.c:main().
*/
@ -81,21 +80,26 @@ struct Client {
Window win;
};
typedef struct {
const char *symbol;
void (*arrange)(void);
} Layout;
extern const char *tags[]; /* all tags */
extern char stext[256]; /* status text */
extern int bh, bmw; /* bar height, bar mode label width */
extern int screen, sx, sy, sw, sh; /* screen geometry */
extern int wax, way, wah, waw; /* windowarea geometry */
extern unsigned int bh, blw; /* bar height, bar layout label width */
extern unsigned int master, nmaster; /* master percent, number of master clients */
extern unsigned int ntags, numlockmask; /* number of tags, dynamic lock mask */
extern void (*handler[LASTEvent])(XEvent *); /* event handler */
extern void (*arrange)(void); /* arrange function, indicates mode */
extern Atom wmatom[WMLast], netatom[NetLast];
extern Bool running, selscreen, *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 Layout *lt;
extern Window root, barwin;
/* client.c */
@ -124,17 +128,18 @@ extern void sendevent(Window w, Atom a, long value); /* send synthetic event to
extern int xerror(Display *dsply, XErrorEvent *ee); /* dwm's X error handler */
/* screen.c */
extern void compileregexps(void); /* initialize regexps of rules defined in config.h */
extern void compileregs(void); /* initialize regexps of rules defined in config.h */
extern void dofloat(void); /* arranges all windows floating */
extern void dotile(void); /* arranges all windows tiled */
extern void incnmaster(Arg *arg); /* increments nmaster with arg's index value */
extern void initlayouts(void); /* initialize layout array */
extern Bool isvisible(Client *c); /* returns True if client is visible */
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 settags(Client *c, Client *trans); /* sets tags of c */
extern void tag(Arg *arg); /* tags c with arg's index */
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 togglelayout(Arg *arg); /* toggles layout */
extern void toggletag(Arg *arg); /* toggles c tags with arg's index */
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 */

12
event.c
View file

@ -137,10 +137,10 @@ buttonpress(XEvent *e) {
return;
}
}
if(ev->x < x + bmw)
if(ev->x < x + blw)
switch(ev->button) {
case Button1:
togglemode(NULL);
togglelayout(NULL);
break;
case Button4:
a.i = 1;
@ -156,14 +156,14 @@ buttonpress(XEvent *e) {
focus(c);
if(CLEANMASK(ev->state) != MODKEY)
return;
if(ev->button == Button1 && (arrange == dofloat || c->isfloat)) {
if(ev->button == Button1 && (lt->arrange == dofloat || c->isfloat)) {
restack();
movemouse(c);
}
else if(ev->button == Button2)
zoom(NULL);
else if(ev->button == Button3
&& (arrange == dofloat || c->isfloat) && !c->isfixed)
&& (lt->arrange == dofloat || c->isfloat) && !c->isfixed)
{
restack();
resizemouse(c);
@ -181,7 +181,7 @@ configurerequest(XEvent *e) {
c->ismax = False;
if(ev->value_mask & CWBorderWidth)
c->border = ev->border_width;
if(c->isfixed || c->isfloat || (arrange == dofloat)) {
if(c->isfixed || c->isfloat || (lt->arrange == dofloat)) {
if(ev->value_mask & CWX)
c->x = ev->x;
if(ev->value_mask & CWY)
@ -310,7 +310,7 @@ propertynotify(XEvent *e) {
case XA_WM_TRANSIENT_FOR:
XGetTransientForHint(dpy, c->win, &trans);
if(!c->isfloat && (c->isfloat = (trans != 0)))
arrange();
lt->arrange();
break;
case XA_WM_NORMAL_HINTS:
updatesizehints(c);

12
main.c
View file

@ -18,8 +18,8 @@
/* extern */
char stext[256];
int bh, bmw, screen, sx, sy, sw, sh, wax, way, waw, wah;
unsigned int ntags, numlockmask;
int screen, sx, sy, sw, sh, wax, way, waw, wah;
unsigned int bh, ntags, numlockmask;
Atom wmatom[WMLast], netatom[NetLast];
Bool running = True;
Bool *seltag;
@ -246,7 +246,7 @@ setup(void) {
wa.cursor = cursor[CurNormal];
XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa);
grabkeys();
compileregexps();
compileregs();
for(ntags = 0; tags[ntags]; ntags++);
seltag = emallocz(sizeof(Bool) * ntags);
seltag[0] = True;
@ -262,7 +262,7 @@ setup(void) {
sx = sy = 0;
sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen);
bmw = textw(TILESYMBOL) > textw(FLOATSYMBOL) ? textw(TILESYMBOL) : textw(FLOATSYMBOL);
initlayouts();
/* bar */
dc.h = bh = dc.font.height + 2;
wa.override_redirect = 1;
@ -312,8 +312,8 @@ drawstatus(void) {
drawtext(tags[i], dc.norm, sel && sel->tags[i], isoccupied(i));
dc.x += dc.w;
}
dc.w = bmw;
drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.norm, False, False);
dc.w = blw;
drawtext(lt->symbol, dc.norm, False, False);
x = dc.x + dc.w;
dc.w = textw(stext);
dc.x = sw - dc.w;

View file

@ -9,9 +9,10 @@
#include <sys/types.h>
#include <X11/Xutil.h>
void (*arrange)(void) = DEFMODE;
unsigned int master = MASTER;
unsigned int nmaster = NMASTER;
unsigned int blw = 0;
Layout *lt = NULL;
/* static */
@ -24,39 +25,41 @@ typedef struct {
typedef struct {
regex_t *propregex;
regex_t *tagregex;
} Regexps;
} Regs;
LAYOUTS
TAGS
RULES
static Regexps *regexps = NULL;
static unsigned int len = 0;
static Regs *regs = NULL;
static unsigned int nrules = 0;
static unsigned int nlayouts = 0;
/* extern */
void
compileregexps(void) {
compileregs(void) {
unsigned int i;
regex_t *reg;
if(regexps)
if(regs)
return;
len = sizeof rule / sizeof rule[0];
regexps = emallocz(len * sizeof(Regexps));
for(i = 0; i < len; i++) {
nrules = sizeof rule / sizeof rule[0];
regs = emallocz(nrules * sizeof(Regs));
for(i = 0; i < nrules; i++) {
if(rule[i].prop) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].prop, REG_EXTENDED))
free(reg);
else
regexps[i].propregex = reg;
regs[i].propregex = reg;
}
if(rule[i].tags) {
reg = emallocz(sizeof(regex_t));
if(regcomp(reg, rule[i].tags, REG_EXTENDED))
free(reg);
else
regexps[i].tagregex = reg;
regs[i].tagregex = reg;
}
}
}
@ -138,16 +141,29 @@ dotile(void) {
void
incnmaster(Arg *arg) {
if((arrange == dofloat) || (nmaster + arg->i < 1)
if((lt->arrange == dofloat) || (nmaster + arg->i < 1)
|| (wah / (nmaster + arg->i) <= 2 * BORDERPX))
return;
nmaster += arg->i;
if(sel)
arrange();
lt->arrange();
else
drawstatus();
}
void
initlayouts(void) {
unsigned int i, w;
lt = &layout[0];
nlayouts = sizeof layout / sizeof layout[0];
for(blw = i = 0; i < nlayouts; i++) {
w = textw(layout[i].symbol);
if(w > blw)
blw = w;
}
}
Bool
isvisible(Client *c) {
unsigned int i;
@ -160,7 +176,7 @@ isvisible(Client *c) {
void
resizemaster(Arg *arg) {
if(arrange != dotile)
if(lt->arrange != dotile)
return;
if(arg->i == 0)
master = MASTER;
@ -170,7 +186,7 @@ resizemaster(Arg *arg) {
return;
master += arg->i;
}
arrange();
lt->arrange();
}
void
@ -181,9 +197,9 @@ restack(void) {
drawstatus();
if(!sel)
return;
if(sel->isfloat || arrange == dofloat)
if(sel->isfloat || lt->arrange == dofloat)
XRaiseWindow(dpy, sel->win);
if(arrange != dofloat) {
if(lt->arrange != dofloat) {
if(!sel->isfloat)
XLowerWindow(dpy, sel->win);
for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
@ -212,11 +228,11 @@ settags(Client *c, Client *trans) {
snprintf(prop, sizeof prop, "%s:%s:%s",
ch.res_class ? ch.res_class : "",
ch.res_name ? ch.res_name : "", c->name);
for(i = 0; i < len; i++)
if(regexps[i].propregex && !regexec(regexps[i].propregex, prop, 1, &tmp, 0)) {
for(i = 0; i < nrules; i++)
if(regs[i].propregex && !regexec(regs[i].propregex, prop, 1, &tmp, 0)) {
c->isfloat = rule[i].isfloat;
for(j = 0; regexps[i].tagregex && j < ntags; j++) {
if(!regexec(regexps[i].tagregex, tags[j], 1, &tmp, 0)) {
for(j = 0; regs[i].tagregex && j < ntags; j++) {
if(!regexec(regs[i].tagregex, tags[j], 1, &tmp, 0)) {
matched = True;
c->tags[j] = True;
}
@ -242,15 +258,15 @@ tag(Arg *arg) {
sel->tags[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
sel->tags[arg->i] = True;
arrange();
lt->arrange();
}
void
togglefloat(Arg *arg) {
if(!sel || arrange == dofloat)
if(!sel || lt->arrange == dofloat)
return;
sel->isfloat = !sel->isfloat;
arrange();
lt->arrange();
}
void
@ -263,14 +279,20 @@ toggletag(Arg *arg) {
for(i = 0; i < ntags && !sel->tags[i]; i++);
if(i == ntags)
sel->tags[arg->i] = True;
arrange();
lt->arrange();
}
void
togglemode(Arg *arg) {
arrange = (arrange == dofloat) ? dotile : dofloat;
togglelayout(Arg *arg) {
unsigned int i;
for(i = 0; i < nlayouts && lt != &layout[i]; i++);
if(i == nlayouts - 1)
lt = &layout[0];
else
lt = &layout[++i];
if(sel)
arrange();
lt->arrange();
else
drawstatus();
}
@ -283,7 +305,7 @@ toggleview(Arg *arg) {
for(i = 0; i < ntags && !seltag[i]; i++);
if(i == ntags)
seltag[arg->i] = True; /* cannot toggle last view */
arrange();
lt->arrange();
}
void
@ -294,5 +316,5 @@ view(Arg *arg) {
seltag[i] = (arg->i == -1) ? True : False;
if(arg->i >= 0 && arg->i < ntags)
seltag[arg->i] = True;
arrange();
lt->arrange();
}