Compare commits

...

29 Commits
5.0 ... 5.1

Author SHA1 Message Date
4a2902efe4 forcing fullscreen windows to bw=0, though most fullscreen apps are broken anyways 2008-07-29 11:32:22 +01:00
6fad4c49f1 potential crash fix if xinerama behaves broken, though I doubt it 2008-07-18 20:18:45 +01:00
78f0f8595f make hg tip compilable with default config 2008-07-18 10:57:32 +02:00
7ecadcee39 local use of xidx is useless, got rid of it, falling back to screen 0 if pointer query fails for whatever reason 2008-07-16 18:39:48 +01:00
c86ed46a1b got rid of compile time xidx configuration, querying mouse pointer instead 2008-07-16 18:33:51 +01:00
9086f98068 reverted uint redefinition 2008-07-16 18:17:42 +01:00
9aa4a9043d applied anydot's urgency hint patch, thanks! 2008-07-13 18:08:55 +01:00
d5893f55be renamed eprint die 2008-07-03 17:05:56 +01:00
f529d41ca1 simplified detach() 2008-07-03 10:58:35 +01:00
45768ee04b removed aux* stuff from Client 2008-07-02 11:54:36 +01:00
a6d23fb61c removed useless comment 2008-07-02 11:19:02 +01:00
bf76cefe47 minor fix to view() 2008-07-02 11:06:46 +01:00
9bb0f20515 applied Frederik Ternerot's grabbuttons patch with slight modifications 2008-07-01 19:26:17 +01:00
2431ae7df7 locale update 2008-06-30 09:57:45 +01:00
829b6b57e7 removed useless characters 2008-06-24 12:40:48 +01:00
7b4c512e62 applied James Turner's dwm.1 patch, thanks James! 2008-06-23 08:59:19 +01:00
7f7c3140a9 fix of monocle 2008-06-22 09:33:49 +01:00
277155cf77 another merge 2008-06-22 09:29:35 +01:00
0c38ec7cd6 does this fix anything? 2008-06-22 09:29:06 +01:00
deef4c9bfd fixed Gottox' buttonpress/ClkTagBar code 2008-06-21 13:49:43 +01:00
b86c818599 applied Gottox' ClkTagBar patch 2008-06-20 16:52:07 +01:00
c2a916bf30 made arrange again like it was once 2008-06-19 14:58:19 +01:00
2bd46d1ce6 fix 2008-06-19 14:13:07 +01:00
6e0ce46365 use sel instead of seeking the list 2008-06-19 14:07:55 +01:00
c853d5e9bb resize should apply if !banned 2008-06-19 14:01:40 +01:00
31da0b7525 applied Gottox patch 2008-06-19 12:28:56 +01:00
12ea925076 untested monocle 2008-06-19 11:38:53 +01:00
79ecbeca7e non-zero 2008-06-19 09:11:11 +01:00
cf98ea2a9c Added tag 5.0 for changeset 06eb9644e2da 2008-06-18 18:22:54 +01:00
5 changed files with 234 additions and 213 deletions

View File

@ -53,3 +53,4 @@ bcd7e18e196a00cc2e97ff3a4a58f3cdaba13856 4.6
d6d3085307d8d98b8b012b669e858fd787befeb1 4.7 d6d3085307d8d98b8b012b669e858fd787befeb1 4.7
607015ddb091d49cbd3457af41713691aa69f4d6 4.8 607015ddb091d49cbd3457af41713691aa69f4d6 4.8
22c669b2dd3673785c3476b9976da21e8783f745 4.9 22c669b2dd3673785c3476b9976da21e8783f745 4.9
06eb9644e2dad7667d97495eb7d7bc62aa0429e8 5.0

View File

@ -8,15 +8,11 @@ static const char normfgcolor[] = "#000000";
static const char selbordercolor[] = "#0066ff"; static const char selbordercolor[] = "#0066ff";
static const char selbgcolor[] = "#0066ff"; static const char selbgcolor[] = "#0066ff";
static const char selfgcolor[] = "#ffffff"; static const char selfgcolor[] = "#ffffff";
static uint borderpx = 1; /* border pixel of windows */ static unsigned int borderpx = 1; /* border pixel of windows */
static uint snap = 32; /* snap pixel */ static unsigned int snap = 32; /* snap pixel */
static Bool showbar = True; /* False means no bar */ static Bool showbar = True; /* False means no bar */
static Bool topbar = True; /* False means bottom bar */ static Bool topbar = True; /* False means bottom bar */
#ifdef XINERAMA
static uint xidx = 0; /* Xinerama screen index to use */
#endif
/* tagging */ /* tagging */
static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; static const char tags[][MAXTAGLEN] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
@ -34,6 +30,7 @@ static Layout layouts[] = {
/* symbol arrange function */ /* symbol arrange function */
{ "[]=", tile }, /* first entry is default */ { "[]=", tile }, /* first entry is default */
{ "><>", NULL }, /* no layout function means floating behavior */ { "><>", NULL }, /* no layout function means floating behavior */
{ "[M]", monocle },
}; };
/* key definitions */ /* key definitions */
@ -60,11 +57,13 @@ static Key keys[] = {
{ MODKEY, XK_k, focusstack, {.i = -1 } }, { MODKEY, XK_k, focusstack, {.i = -1 } },
{ MODKEY, XK_h, setmfact, {.f = -0.05} }, { MODKEY, XK_h, setmfact, {.f = -0.05} },
{ MODKEY, XK_l, setmfact, {.f = +0.05} }, { MODKEY, XK_l, setmfact, {.f = +0.05} },
{ MODKEY, XK_m, togglemax, {0} },
{ MODKEY, XK_Return, zoom, {0} }, { MODKEY, XK_Return, zoom, {0} },
{ MODKEY, XK_Tab, view, {0} }, { MODKEY, XK_Tab, view, {0} },
{ MODKEY|ShiftMask, XK_c, killclient, {0} }, { MODKEY|ShiftMask, XK_c, killclient, {0} },
{ MODKEY, XK_space, togglelayout, {0} }, { MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
{ MODKEY, XK_space, setlayout, {0} },
{ MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} },
{ MODKEY, XK_0, view, {.ui = ~0 } }, { MODKEY, XK_0, view, {.ui = ~0 } },
{ MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } },
@ -81,31 +80,20 @@ static Key keys[] = {
}; };
/* button definitions */ /* button definitions */
#define TAGBUTTONS(TAG) \
{ TAG, 0, Button1, view, {.ui = 1 << TAG} }, \
{ TAG, 0, Button3, toggleview, {.ui = 1 << TAG} }, \
{ TAG, MODKEY, Button1, tag, {.ui = 1 << TAG} }, \
{ TAG, MODKEY, Button3, toggletag, {.ui = 1 << TAG} },
/* click can be a tag number (starting at 0), /* click can be a tag number (starting at 0),
* ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ * ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */
static Button buttons[] = { static Button buttons[] = {
/* click event mask button function argument */ /* click event mask button function argument */
{ ClkLtSymbol, 0, Button1, togglelayout, {0} }, { ClkLtSymbol, 0, Button1, setlayout, {0} },
{ ClkLtSymbol, 0, Button3, togglemax, {0} }, { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} },
{ ClkWinTitle, 0, Button2, zoom, {0} }, { ClkWinTitle, 0, Button2, zoom, {0} },
{ ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } },
{ ClkClientWin, MODKEY, Button1, movemouse, {0} }, { ClkClientWin, MODKEY, Button1, movemouse, {0} },
{ ClkClientWin, MODKEY, Button2, togglefloating, {0} }, { ClkClientWin, MODKEY, Button2, togglefloating, {0} },
{ ClkClientWin, MODKEY, Button3, resizemouse, {0} }, { ClkClientWin, MODKEY, Button3, resizemouse, {0} },
TAGBUTTONS(0) { ClkTagBar, 0, Button1, view, {0} },
TAGBUTTONS(1) { ClkTagBar, 0, Button3, toggleview, {0} },
TAGBUTTONS(2) { ClkTagBar, MODKEY, Button1, tag, {0} },
TAGBUTTONS(3) { ClkTagBar, MODKEY, Button3, toggletag, {0} },
TAGBUTTONS(4)
TAGBUTTONS(5)
TAGBUTTONS(6)
TAGBUTTONS(7)
TAGBUTTONS(8)
}; };

View File

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

14
dwm.1
View File

@ -60,8 +60,17 @@ Start
.B Mod1\-b .B Mod1\-b
Toggles bar on and off. Toggles bar on and off.
.TP .TP
.B Mod1\-t
Sets tiled layout.
.TP
.B Mod1\-f
Sets floating layout.
.TP
.B Mod1\-m
Sets monocle layout.
.TP
.B Mod1\-space .B Mod1\-space
Toggles between layouts. Toggles between current and previous layout.
.TP .TP
.B Mod1\-j .B Mod1\-j
Focus next window. Focus next window.
@ -75,9 +84,6 @@ Decrease master area size.
.B Mod1\-l .B Mod1\-l
Increase master area size. Increase master area size.
.TP .TP
.B Mod1\-m
Toggle between maximisation meta-layout and active layout.
.TP
.B Mod1\-Return .B Mod1\-Return
Zooms/cycles focused window to/from master area (tiled layouts only). Zooms/cycles focused window to/from master area (tiled layouts only).
.TP .TP

370
dwm.c
View File

@ -44,11 +44,13 @@
#endif #endif
/* macros */ /* macros */
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask)
#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask)) #define CLEANMASK(mask) (mask & ~(numlockmask|LockMask))
#define INRECT(X,Y,RX,RY,RW,RH) ((X) >= (RX) && (X) < (RX) + (RW) && (Y) >= (RY) && (Y) < (RY) + (RH))
#define ISVISIBLE(x) (x->tags & tagset[seltags])
#define LENGTH(x) (sizeof x / sizeof x[0]) #define LENGTH(x) (sizeof x / sizeof x[0])
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAXTAGLEN 16 #define MAXTAGLEN 16
#define MOUSEMASK (BUTTONMASK|PointerMotionMask) #define MOUSEMASK (BUTTONMASK|PointerMotionMask)
#define TAGMASK ((int)((1LL << LENGTH(tags)) - 1)) #define TAGMASK ((int)((1LL << LENGTH(tags)) - 1))
@ -59,24 +61,20 @@ enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
enum { ColBorder, ColFG, ColBG, ColLast }; /* color */ enum { ColBorder, ColFG, ColBG, ColLast }; /* color */
enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */
enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */ enum { WMProtocols, WMDelete, WMName, WMState, WMLast };/* default atoms */
enum { ClkLtSymbol = 64, ClkStatusText, ClkWinTitle, enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle,
ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ ClkClientWin, ClkRootWin, ClkLast }; /* clicks */
/* typedefs */
typedef unsigned int uint;
typedef unsigned long ulong;
typedef union { typedef union {
int i; int i;
uint ui; unsigned int ui;
float f; float f;
void *v; void *v;
} Arg; } Arg;
typedef struct { typedef struct {
uint click; unsigned int click;
uint mask; unsigned int mask;
uint button; unsigned int button;
void (*func)(const Arg *arg); void (*func)(const Arg *arg);
const Arg arg; const Arg arg;
} Button; } Button;
@ -88,8 +86,8 @@ struct Client {
int x, y, w, h; int x, y, w, h;
int basew, baseh, incw, inch, maxw, maxh, minw, minh; int basew, baseh, incw, inch, maxw, maxh, minw, minh;
int bw, oldbw; int bw, oldbw;
uint tags; unsigned int tags;
Bool isbanned, isfixed, isfloating, ismoved, isurgent; Bool isfixed, isfloating, isurgent;
Client *next; Client *next;
Client *snext; Client *snext;
Window win; Window win;
@ -97,8 +95,8 @@ struct Client {
typedef struct { typedef struct {
int x, y, w, h; int x, y, w, h;
ulong norm[ColLast]; unsigned long norm[ColLast];
ulong sel[ColLast]; unsigned long sel[ColLast];
Drawable drawable; Drawable drawable;
GC gc; GC gc;
struct { struct {
@ -111,7 +109,7 @@ typedef struct {
} DC; /* draw context */ } DC; /* draw context */
typedef struct { typedef struct {
uint mod; unsigned int mod;
KeySym keysym; KeySym keysym;
void (*func)(const Arg *); void (*func)(const Arg *);
const Arg arg; const Arg arg;
@ -126,7 +124,7 @@ typedef struct {
const char *class; const char *class;
const char *instance; const char *instance;
const char *title; const char *title;
uint tags; unsigned int tags;
Bool isfloating; Bool isfloating;
} Rule; } Rule;
@ -138,36 +136,38 @@ static void attachstack(Client *c);
static void buttonpress(XEvent *e); static void buttonpress(XEvent *e);
static void checkotherwm(void); static void checkotherwm(void);
static void cleanup(void); static void cleanup(void);
static void clearurgent(void);
static void configure(Client *c); static void configure(Client *c);
static void configurenotify(XEvent *e); static void configurenotify(XEvent *e);
static void configurerequest(XEvent *e); static void configurerequest(XEvent *e);
static void destroynotify(XEvent *e); static void destroynotify(XEvent *e);
static void detach(Client *c); static void detach(Client *c);
static void detachstack(Client *c); static void detachstack(Client *c);
static void die(const char *errstr, ...);
static void drawbar(void); static void drawbar(void);
static void drawsquare(Bool filled, Bool empty, Bool invert, ulong col[ColLast]); static void drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]);
static void drawtext(const char *text, ulong col[ColLast], Bool invert); static void drawtext(const char *text, unsigned long col[ColLast], Bool invert);
static void enternotify(XEvent *e); static void enternotify(XEvent *e);
static void eprint(const char *errstr, ...);
static void expose(XEvent *e); static void expose(XEvent *e);
static void focus(Client *c); static void focus(Client *c);
static void focusin(XEvent *e); static void focusin(XEvent *e);
static void focusstack(const Arg *arg); static void focusstack(const Arg *arg);
static Client *getclient(Window w); static Client *getclient(Window w);
static ulong getcolor(const char *colstr); static unsigned long getcolor(const char *colstr);
static long getstate(Window w); static long getstate(Window w);
static Bool gettextprop(Window w, Atom atom, char *text, uint size); static Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
static void grabbuttons(Client *c, Bool focused); static void grabbuttons(Client *c, Bool focused);
static void grabkeys(void); static void grabkeys(void);
static void initfont(const char *fontstr); static void initfont(const char *fontstr);
static Bool isoccupied(uint t); static Bool isoccupied(unsigned int t);
static Bool isprotodel(Client *c); static Bool isprotodel(Client *c);
static Bool isurgent(uint t); static Bool isurgent(unsigned int t);
static void keypress(XEvent *e); static void keypress(XEvent *e);
static void killclient(const Arg *arg); static void killclient(const Arg *arg);
static void manage(Window w, XWindowAttributes *wa); static void manage(Window w, XWindowAttributes *wa);
static void mappingnotify(XEvent *e); static void mappingnotify(XEvent *e);
static void maprequest(XEvent *e); static void maprequest(XEvent *e);
static void monocle(void);
static void movemouse(const Arg *arg); static void movemouse(const Arg *arg);
static Client *nexttiled(Client *c); static Client *nexttiled(Client *c);
static void propertynotify(XEvent *e); static void propertynotify(XEvent *e);
@ -178,16 +178,15 @@ static void restack(void);
static void run(void); static void run(void);
static void scan(void); static void scan(void);
static void setclientstate(Client *c, long state); static void setclientstate(Client *c, long state);
static void setlayout(const Arg *arg);
static void setmfact(const Arg *arg); static void setmfact(const Arg *arg);
static void setup(void); static void setup(void);
static void spawn(const Arg *arg); static void spawn(const Arg *arg);
static void tag(const Arg *arg); static void tag(const Arg *arg);
static int textnw(const char *text, uint len); static int textnw(const char *text, unsigned int len);
static void tile(void); static void tile(void);
static void togglebar(const Arg *arg); static void togglebar(const Arg *arg);
static void togglefloating(const Arg *arg); static void togglefloating(const Arg *arg);
static void togglelayout(const Arg *arg);
static void togglemax(const Arg *arg);
static void toggletag(const Arg *arg); static void toggletag(const Arg *arg);
static void toggleview(const Arg *arg); static void toggleview(const Arg *arg);
static void unmanage(Client *c); static void unmanage(Client *c);
@ -207,9 +206,9 @@ static void zoom(const Arg *arg);
static char stext[256]; static char stext[256];
static int screen, sx, sy, sw, sh; static int screen, sx, sy, sw, sh;
static int by, bh, blw, wx, wy, ww, wh; static int by, bh, blw, wx, wy, ww, wh;
static uint seltags = 0; static unsigned int seltags = 0, sellt = 0;
static int (*xerrorxlib)(Display *, XErrorEvent *); static int (*xerrorxlib)(Display *, XErrorEvent *);
static uint numlockmask = 0; static unsigned int numlockmask = 0;
static void (*handler[LASTEvent]) (XEvent *) = { static void (*handler[LASTEvent]) (XEvent *) = {
[ButtonPress] = buttonpress, [ButtonPress] = buttonpress,
[ConfigureRequest] = configurerequest, [ConfigureRequest] = configurerequest,
@ -225,28 +224,27 @@ static void (*handler[LASTEvent]) (XEvent *) = {
[UnmapNotify] = unmapnotify [UnmapNotify] = unmapnotify
}; };
static Atom wmatom[WMLast], netatom[NetLast]; static Atom wmatom[WMLast], netatom[NetLast];
static Bool ismax = False;
static Bool otherwm, readin; static Bool otherwm, readin;
static Bool running = True; static Bool running = True;
static uint tagset[] = {1, 1}; /* after start, first tag is selected */ static unsigned int tagset[] = {1, 1}; /* after start, first tag is selected */
static Client *clients = NULL; static Client *clients = NULL;
static Client *sel = NULL; static Client *sel = NULL;
static Client *stack = NULL; static Client *stack = NULL;
static Cursor cursor[CurLast]; static Cursor cursor[CurLast];
static Display *dpy; static Display *dpy;
static DC dc = {0}; static DC dc = {0};
static Layout *lt = NULL; static Layout *lt[] = { NULL, NULL };
static Window root, barwin; static Window root, barwin;
/* configuration, allows nested code to access above variables */ /* configuration, allows nested code to access above variables */
#include "config.h" #include "config.h"
/* compile-time check if all tags fit into an uint bit array. */ /* compile-time check if all tags fit into an unsigned int bit array. */
struct NumTags { char limitexceeded[sizeof(uint) * 8 < LENGTH(tags) ? -1 : 1]; }; struct NumTags { char limitexceeded[sizeof(unsigned int) * 8 < LENGTH(tags) ? -1 : 1]; };
/* function implementations */ /* function implementations */
void void
applyrules(Client *c) { applyrules(Client *c) {
uint i; unsigned int i;
Rule *r; Rule *r;
XClassHint ch = { 0 }; XClassHint ch = { 0 };
@ -274,23 +272,18 @@ arrange(void) {
Client *c; Client *c;
for(c = clients; c; c = c->next) for(c = clients; c; c = c->next)
if(c->tags & tagset[seltags]) { /* is visible */ if(ISVISIBLE(c)) {
if(ismax && !c->isfixed) { XMoveWindow(dpy, c->win, c->x, c->y);
XMoveResizeWindow(dpy, c->win, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw); if(!lt[sellt]->arrange || c->isfloating)
c->ismoved = True;
}
else if(!lt->arrange || c->isfloating)
resize(c, c->x, c->y, c->w, c->h, True); resize(c, c->x, c->y, c->w, c->h, True);
c->isbanned = False;
} }
else if(!c->isbanned) { else {
XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y); XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
c->isbanned = c->ismoved = True;
} }
focus(NULL); focus(NULL);
if(lt->arrange && !ismax) if(lt[sellt]->arrange)
lt->arrange(); lt[sellt]->arrange();
restack(); restack();
} }
@ -308,18 +301,19 @@ attachstack(Client *c) {
void void
buttonpress(XEvent *e) { buttonpress(XEvent *e) {
uint i, x, click; unsigned int i, x, click;
Arg arg = {0};
Client *c; Client *c;
XButtonPressedEvent *ev = &e->xbutton; XButtonPressedEvent *ev = &e->xbutton;
click = ClkRootWin; click = ClkRootWin;
if(ev->window == barwin) { if(ev->window == barwin) {
i = x = 0; i = x = 0;
do do x += TEXTW(tags[i]); while(ev->x >= x && ++i < LENGTH(tags));
x += TEXTW(tags[i]); if(i < LENGTH(tags)) {
while(ev->x >= x && ++i < LENGTH(tags)); click = ClkTagBar;
if(i < LENGTH(tags)) arg.ui = 1 << i;
click = i; }
else if(ev->x < x + blw) else if(ev->x < x + blw)
click = ClkLtSymbol; click = ClkLtSymbol;
else if(ev->x > wx + ww - TEXTW(stext)) else if(ev->x > wx + ww - TEXTW(stext))
@ -335,7 +329,7 @@ buttonpress(XEvent *e) {
for(i = 0; i < LENGTH(buttons); i++) for(i = 0; i < LENGTH(buttons); i++)
if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button if(click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button
&& CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state))
buttons[i].func(&buttons[i].arg); buttons[i].func(click == ClkTagBar ? &arg : &buttons[i].arg);
} }
void void
@ -347,7 +341,7 @@ checkotherwm(void) {
XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask);
XSync(dpy, False); XSync(dpy, False);
if(otherwm) if(otherwm)
eprint("dwm: another window manager is already running\n"); die("dwm: another window manager is already running\n");
XSetErrorHandler(NULL); XSetErrorHandler(NULL);
xerrorxlib = XSetErrorHandler(xerror); xerrorxlib = XSetErrorHandler(xerror);
XSync(dpy, False); XSync(dpy, False);
@ -360,7 +354,7 @@ cleanup(void) {
close(STDIN_FILENO); close(STDIN_FILENO);
view(&a); view(&a);
lt = &foo; lt[sellt] = &foo;
while(stack) while(stack)
unmanage(stack); unmanage(stack);
if(dc.font.set) if(dc.font.set)
@ -378,6 +372,23 @@ cleanup(void) {
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
} }
void
clearurgent(void) {
XWMHints *wmh;
Client *c;
for(c = clients; c; c = c->next)
if(ISVISIBLE(c) && c->isurgent) {
c->isurgent = False;
if (!(wmh = XGetWMHints(dpy, c->win)))
continue;
wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
XFree(wmh);
}
}
void void
configure(Client *c) { configure(Client *c) {
XConfigureEvent ce; XConfigureEvent ce;
@ -418,9 +429,7 @@ configurerequest(XEvent *e) {
if((c = getclient(ev->window))) { if((c = getclient(ev->window))) {
if(ev->value_mask & CWBorderWidth) if(ev->value_mask & CWBorderWidth)
c->bw = ev->border_width; c->bw = ev->border_width;
if(ismax && !c->isbanned && !c->isfixed) else if(c->isfloating || !lt[sellt]->arrange) {
XMoveResizeWindow(dpy, c->win, wx, wy, ww - 2 * c->bw, wh + 2 * c->bw);
else if(c->isfloating || !lt->arrange) {
if(ev->value_mask & CWX) if(ev->value_mask & CWX)
c->x = sx + ev->x; c->x = sx + ev->x;
if(ev->value_mask & CWY) if(ev->value_mask & CWY)
@ -433,10 +442,9 @@ configurerequest(XEvent *e) {
c->x = sx + (sw / 2 - c->w / 2); /* center in x direction */ c->x = sx + (sw / 2 - c->w / 2); /* center in x direction */
if((c->y - sy + c->h) > sh && c->isfloating) if((c->y - sy + c->h) > sh && c->isfloating)
c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */ c->y = sy + (sh / 2 - c->h / 2); /* center in y direction */
if((ev->value_mask & (CWX|CWY)) if((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight)))
&& !(ev->value_mask & (CWWidth|CWHeight)))
configure(c); configure(c);
if(!c->isbanned) if(ISVISIBLE(c))
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
} }
else else
@ -466,16 +474,10 @@ destroynotify(XEvent *e) {
void void
detach(Client *c) { detach(Client *c) {
Client *i; Client **tc;
if (c != clients) { for(tc = &clients; *tc && *tc != c; tc = &(*tc)->next);
for(i = clients; i->next != c; i = i->next); *tc = c->next;
i->next = c->next;
}
else {
clients = c->next;
}
c->next = NULL;
} }
void void
@ -486,28 +488,36 @@ detachstack(Client *c) {
*tc = c->snext; *tc = c->snext;
} }
void
die(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void void
drawbar(void) { drawbar(void) {
int i, x; int i, x;
Client *c;
dc.x = 0; dc.x = 0;
for(c = stack; c && c->isbanned; c = c->snext);
for(i = 0; i < LENGTH(tags); i++) { for(i = 0; i < LENGTH(tags); i++) {
dc.w = TEXTW(tags[i]); dc.w = TEXTW(tags[i]);
if(tagset[seltags] & 1 << i) { if(tagset[seltags] & 1 << i) {
drawtext(tags[i], dc.sel, isurgent(i)); drawtext(tags[i], dc.sel, isurgent(i));
drawsquare(c && c->tags & 1 << i, isoccupied(i), isurgent(i), dc.sel); drawsquare(sel && sel->tags & 1 << i, isoccupied(i), isurgent(i), dc.sel);
} }
else { else {
drawtext(tags[i], dc.norm, isurgent(i)); drawtext(tags[i], dc.norm, isurgent(i));
drawsquare(c && c->tags & 1 << i, isoccupied(i), isurgent(i), dc.norm); drawsquare(sel && sel->tags & 1 << i, isoccupied(i), isurgent(i), dc.norm);
} }
dc.x += dc.w; dc.x += dc.w;
} }
if(blw > 0) { if(blw > 0) {
dc.w = blw; dc.w = blw;
drawtext(lt->symbol, dc.norm, ismax); drawtext(lt[sellt]->symbol, dc.norm, False);
x = dc.x + dc.w; x = dc.x + dc.w;
} }
else else
@ -521,9 +531,9 @@ drawbar(void) {
drawtext(stext, dc.norm, False); drawtext(stext, dc.norm, False);
if((dc.w = dc.x - x) > bh) { if((dc.w = dc.x - x) > bh) {
dc.x = x; dc.x = x;
if(c) { if(sel) {
drawtext(c->name, dc.sel, False); drawtext(sel->name, dc.sel, False);
drawsquare(c->isfixed, c->isfloating, False, dc.sel); drawsquare(sel->isfixed, sel->isfloating, False, dc.sel);
} }
else else
drawtext(NULL, dc.norm, False); drawtext(NULL, dc.norm, False);
@ -533,7 +543,7 @@ drawbar(void) {
} }
void void
drawsquare(Bool filled, Bool empty, Bool invert, ulong col[ColLast]) { drawsquare(Bool filled, Bool empty, Bool invert, unsigned long col[ColLast]) {
int x; int x;
XGCValues gcv; XGCValues gcv;
XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XRectangle r = { dc.x, dc.y, dc.w, dc.h };
@ -554,7 +564,7 @@ drawsquare(Bool filled, Bool empty, Bool invert, ulong col[ColLast]) {
} }
void void
drawtext(const char *text, ulong col[ColLast], Bool invert) { drawtext(const char *text, unsigned long col[ColLast], Bool invert) {
int i, x, y, h, len, olen; int i, x, y, h, len, olen;
XRectangle r = { dc.x, dc.y, dc.w, dc.h }; XRectangle r = { dc.x, dc.y, dc.w, dc.h };
char buf[256]; char buf[256];
@ -595,16 +605,6 @@ enternotify(XEvent *e) {
focus(NULL); focus(NULL);
} }
void
eprint(const char *errstr, ...) {
va_list ap;
va_start(ap, errstr);
vfprintf(stderr, errstr, ap);
va_end(ap);
exit(EXIT_FAILURE);
}
void void
expose(XEvent *e) { expose(XEvent *e) {
XExposeEvent *ev = &e->xexpose; XExposeEvent *ev = &e->xexpose;
@ -615,8 +615,8 @@ expose(XEvent *e) {
void void
focus(Client *c) { focus(Client *c) {
if(!c || c->isbanned) if(!c || !ISVISIBLE(c))
for(c = stack; c && c->isbanned; c = c->snext); for(c = stack; c && !ISVISIBLE(c); c = c->snext);
if(sel && sel != c) { if(sel && sel != c) {
grabbuttons(sel, False); grabbuttons(sel, False);
XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]); XSetWindowBorder(dpy, sel->win, dc.norm[ColBorder]);
@ -649,17 +649,17 @@ focusstack(const Arg *arg) {
if(!sel) if(!sel)
return; return;
if (arg->i > 0) { if (arg->i > 0) {
for(c = sel->next; c && c->isbanned; c = c->next); for(c = sel->next; c && !ISVISIBLE(c); c = c->next);
if(!c) if(!c)
for(c = clients; c && c->isbanned; c = c->next); for(c = clients; c && !ISVISIBLE(c); c = c->next);
} }
else { else {
for(i = clients; i != sel; i = i->next) for(i = clients; i != sel; i = i->next)
if (!i->isbanned) if(ISVISIBLE(i))
c = i; c = i;
if(!c) if(!c)
for(; i; i = i->next) for(; i; i = i->next)
if (!i->isbanned) if(ISVISIBLE(i))
c = i; c = i;
} }
if(c) { if(c) {
@ -676,13 +676,13 @@ getclient(Window w) {
return c; return c;
} }
ulong unsigned long
getcolor(const char *colstr) { getcolor(const char *colstr) {
Colormap cmap = DefaultColormap(dpy, screen); Colormap cmap = DefaultColormap(dpy, screen);
XColor color; XColor color;
if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color)) if(!XAllocNamedColor(dpy, cmap, colstr, &color, &color))
eprint("error, cannot allocate color '%s'\n", colstr); die("error, cannot allocate color '%s'\n", colstr);
return color.pixel; return color.pixel;
} }
@ -691,7 +691,7 @@ getstate(Window w) {
int format, status; int format, status;
long result = -1; long result = -1;
unsigned char *p = NULL; unsigned char *p = NULL;
ulong n, extra; unsigned long n, extra;
Atom real; Atom real;
status = XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], status = XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState],
@ -705,7 +705,7 @@ getstate(Window w) {
} }
Bool Bool
gettextprop(Window w, Atom atom, char *text, uint size) { gettextprop(Window w, Atom atom, char *text, unsigned int size) {
char **list = NULL; char **list = NULL;
int n; int n;
XTextProperty name; XTextProperty name;
@ -732,24 +732,23 @@ gettextprop(Window w, Atom atom, char *text, uint size) {
void void
grabbuttons(Client *c, Bool focused) { grabbuttons(Client *c, Bool focused) {
int i, j; unsigned int i, j;
uint buttons[] = { Button1, Button2, Button3 }; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask };
uint modifiers[] = { MODKEY, MODKEY|LockMask, MODKEY|numlockmask, MODKEY|numlockmask|LockMask };
XUngrabButton(dpy, AnyButton, AnyModifier, c->win); XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
if(focused) if(focused) {
for(i = 0; i < LENGTH(buttons); i++) for(i = 0; i < LENGTH(buttons); i++)
if(buttons[i].click == ClkClientWin)
for(j = 0; j < LENGTH(modifiers); j++) for(j = 0; j < LENGTH(modifiers); j++)
XGrabButton(dpy, buttons[i], modifiers[j], c->win, False, XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); } else
else
XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, XGrabButton(dpy, AnyButton, AnyModifier, c->win, False,
BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); BUTTONMASK, GrabModeAsync, GrabModeSync, None, None);
} }
void void
grabkeys(void) { grabkeys(void) {
uint i, j; unsigned int i, j;
KeyCode code; KeyCode code;
XModifierKeymap *modmap; XModifierKeymap *modmap;
@ -809,7 +808,7 @@ initfont(const char *fontstr) {
dc.font.xfont = NULL; dc.font.xfont = NULL;
if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr)) if(!(dc.font.xfont = XLoadQueryFont(dpy, fontstr))
&& !(dc.font.xfont = XLoadQueryFont(dpy, "fixed"))) && !(dc.font.xfont = XLoadQueryFont(dpy, "fixed")))
eprint("error, cannot load font: '%s'\n", fontstr); die("error, cannot load font: '%s'\n", fontstr);
dc.font.ascent = dc.font.xfont->ascent; dc.font.ascent = dc.font.xfont->ascent;
dc.font.descent = dc.font.xfont->descent; dc.font.descent = dc.font.xfont->descent;
} }
@ -817,7 +816,7 @@ initfont(const char *fontstr) {
} }
Bool Bool
isoccupied(uint t) { isoccupied(unsigned int t) {
Client *c; Client *c;
for(c = clients; c; c = c->next) for(c = clients; c; c = c->next)
@ -842,7 +841,7 @@ isprotodel(Client *c) {
} }
Bool Bool
isurgent(uint t) { isurgent(unsigned int t) {
Client *c; Client *c;
for(c = clients; c; c = c->next) for(c = clients; c; c = c->next)
@ -853,7 +852,7 @@ isurgent(uint t) {
void void
keypress(XEvent *e) { keypress(XEvent *e) {
uint i; unsigned int i;
KeySym keysym; KeySym keysym;
XKeyEvent *ev; XKeyEvent *ev;
@ -893,7 +892,7 @@ manage(Window w, XWindowAttributes *wa) {
XWindowChanges wc; XWindowChanges wc;
if(!(c = calloc(1, sizeof(Client)))) if(!(c = calloc(1, sizeof(Client))))
eprint("fatal: could not calloc() %u bytes\n", sizeof(Client)); die("fatal: could not calloc() %u bytes\n", sizeof(Client));
c->win = w; c->win = w;
/* geometry */ /* geometry */
@ -905,7 +904,7 @@ manage(Window w, XWindowAttributes *wa) {
if(c->w == sw && c->h == sh) { if(c->w == sw && c->h == sh) {
c->x = sx; c->x = sx;
c->y = sy; c->y = sy;
c->bw = wa->border_width; c->bw = 0;
} }
else { else {
if(c->x + c->w + 2 * c->bw > sx + sw) if(c->x + c->w + 2 * c->bw > sx + sw)
@ -938,7 +937,7 @@ manage(Window w, XWindowAttributes *wa) {
XRaiseWindow(dpy, c->win); XRaiseWindow(dpy, c->win);
attach(c); attach(c);
attachstack(c); attachstack(c);
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); /* some windows require this */ XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
XMapWindow(dpy, c->win); XMapWindow(dpy, c->win);
setclientstate(c, NormalState); setclientstate(c, NormalState);
arrange(); arrange();
@ -966,10 +965,18 @@ maprequest(XEvent *e) {
manage(ev->window, &wa); manage(ev->window, &wa);
} }
void
monocle(void) {
Client *c;
for(c = nexttiled(clients); c; c = nexttiled(c->next))
resize(c, wx, wy, ww - 2 * c->bw, wh - 2 * c->bw, resizehints);
}
void void
movemouse(const Arg *arg) { movemouse(const Arg *arg) {
int x1, y1, ocx, ocy, di, nx, ny; int x, y, ocx, ocy, di, nx, ny;
uint dui; unsigned int dui;
Client *c; Client *c;
Window dummy; Window dummy;
XEvent ev; XEvent ev;
@ -982,7 +989,7 @@ movemouse(const Arg *arg) {
if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, if(XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurMove], CurrentTime) != GrabSuccess) None, cursor[CurMove], CurrentTime) != GrabSuccess)
return; return;
XQueryPointer(dpy, root, &dummy, &dummy, &x1, &y1, &di, &di, &dui); XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui);
for(;;) { for(;;) {
XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev);
switch (ev.type) { switch (ev.type) {
@ -996,8 +1003,8 @@ movemouse(const Arg *arg) {
break; break;
case MotionNotify: case MotionNotify:
XSync(dpy, False); XSync(dpy, False);
nx = ocx + (ev.xmotion.x - x1); nx = ocx + (ev.xmotion.x - x);
ny = ocy + (ev.xmotion.y - y1); ny = ocy + (ev.xmotion.y - y);
if(snap && nx >= wx && nx <= wx + ww if(snap && nx >= wx && nx <= wx + ww
&& ny >= wy && ny <= wy + wh) { && ny >= wy && ny <= wy + wh) {
if(abs(wx - nx) < snap) if(abs(wx - nx) < snap)
@ -1008,10 +1015,10 @@ movemouse(const Arg *arg) {
ny = wy; ny = wy;
else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < snap) else if(abs((wy + wh) - (ny + c->h + 2 * c->bw)) < snap)
ny = wy + wh - c->h - 2 * c->bw; ny = wy + wh - c->h - 2 * c->bw;
if(!c->isfloating && lt->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) if(!c->isfloating && lt[sellt]->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap))
togglefloating(NULL); togglefloating(NULL);
} }
if(!lt->arrange || c->isfloating) if(!lt[sellt]->arrange || c->isfloating)
resize(c, nx, ny, c->w, c->h, False); resize(c, nx, ny, c->w, c->h, False);
break; break;
} }
@ -1020,7 +1027,7 @@ movemouse(const Arg *arg) {
Client * Client *
nexttiled(Client *c) { nexttiled(Client *c) {
for(; c && (c->isfloating || c->isbanned); c = c->next); for(; c && (c->isfloating || !ISVISIBLE(c)); c = c->next);
return c; return c;
} }
@ -1115,8 +1122,7 @@ resize(Client *c, int x, int y, int w, int h, Bool sizehints) {
h = bh; h = bh;
if(w < bh) if(w < bh)
w = bh; w = bh;
if(c->x != x || c->y != y || c->w != w || c->h != h || c->ismoved) { if(c->x != x || c->y != y || c->w != w || c->h != h) {
c->ismoved = False;
c->x = wc.x = x; c->x = wc.x = x;
c->y = wc.y = y; c->y = wc.y = y;
c->w = wc.width = w; c->w = wc.width = w;
@ -1166,11 +1172,11 @@ resizemouse(const Arg *arg) {
if(snap && nw >= wx && nw <= wx + ww if(snap && nw >= wx && nw <= wx + ww
&& nh >= wy && nh <= wy + wh) { && nh >= wy && nh <= wy + wh) {
if(!c->isfloating && lt->arrange if(!c->isfloating && lt[sellt]->arrange
&& (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) && (abs(nw - c->w) > snap || abs(nh - c->h) > snap))
togglefloating(NULL); togglefloating(NULL);
} }
if(!lt->arrange || c->isfloating) if(!lt[sellt]->arrange || c->isfloating)
resize(c, c->x, c->y, nw, nh, True); resize(c, c->x, c->y, nw, nh, True);
break; break;
} }
@ -1186,13 +1192,13 @@ restack(void) {
drawbar(); drawbar();
if(!sel) if(!sel)
return; return;
if(ismax || sel->isfloating || !lt->arrange) if(sel->isfloating || !lt[sellt]->arrange)
XRaiseWindow(dpy, sel->win); XRaiseWindow(dpy, sel->win);
if(!ismax && lt->arrange) { if(lt[sellt]->arrange) {
wc.stack_mode = Below; wc.stack_mode = Below;
wc.sibling = barwin; wc.sibling = barwin;
for(c = stack; c; c = c->snext) for(c = stack; c; c = c->snext)
if(!c->isfloating && !c->isbanned) { if(!c->isfloating && ISVISIBLE(c)) {
XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc);
wc.sibling = c->win; wc.sibling = c->win;
} }
@ -1207,7 +1213,7 @@ run(void) {
char sbuf[sizeof stext]; char sbuf[sizeof stext];
fd_set rd; fd_set rd;
int r, xfd; int r, xfd;
uint len, offset; unsigned int len, offset;
XEvent ev; XEvent ev;
/* main event loop, also reads status text from stdin */ /* main event loop, also reads status text from stdin */
@ -1225,7 +1231,7 @@ run(void) {
if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) { if(select(xfd + 1, &rd, NULL, NULL, NULL) == -1) {
if(errno == EINTR) if(errno == EINTR)
continue; continue;
eprint("select failed\n"); die("select failed\n");
} }
if(FD_ISSET(STDIN_FILENO, &rd)) { if(FD_ISSET(STDIN_FILENO, &rd)) {
switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) { switch((r = read(STDIN_FILENO, sbuf + offset, len - offset))) {
@ -1263,7 +1269,7 @@ run(void) {
void void
scan(void) { scan(void) {
uint i, num; unsigned int i, num;
Window *wins, d1, d2; Window *wins, d1, d2;
XWindowAttributes wa; XWindowAttributes wa;
@ -1296,12 +1302,24 @@ setclientstate(Client *c, long state) {
PropModeReplace, (unsigned char *)data, 2); PropModeReplace, (unsigned char *)data, 2);
} }
void
setlayout(const Arg *arg) {
if(!arg || !arg->v || arg->v != lt[sellt])
sellt ^= 1;
if(arg && arg->v)
lt[sellt] = (Layout *)arg->v;
if(sel)
arrange();
else
drawbar();
}
/* arg > 1.0 will set mfact absolutly */ /* arg > 1.0 will set mfact absolutly */
void void
setmfact(const Arg *arg) { setmfact(const Arg *arg) {
float f; float f;
if(!arg || !lt->arrange) if(!arg || !lt[sellt]->arrange)
return; return;
f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0; f = arg->f < 1.0 ? arg->f + mfact : arg->f - 1.0;
if(f < 0.1 || f > 0.9) if(f < 0.1 || f > 0.9)
@ -1312,7 +1330,7 @@ setmfact(const Arg *arg) {
void void
setup(void) { setup(void) {
uint i; unsigned int i;
int w; int w;
XSetWindowAttributes wa; XSetWindowAttributes wa;
@ -1325,7 +1343,8 @@ setup(void) {
sw = DisplayWidth(dpy, screen); sw = DisplayWidth(dpy, screen);
sh = DisplayHeight(dpy, screen); sh = DisplayHeight(dpy, screen);
bh = dc.h = dc.font.height + 2; bh = dc.h = dc.font.height + 2;
lt = layouts; lt[0] = &layouts[0];
lt[1] = &layouts[1 % LENGTH(layouts)];
updategeom(); updategeom();
/* init atoms */ /* init atoms */
@ -1414,7 +1433,7 @@ tag(const Arg *arg) {
} }
int int
textnw(const char *text, uint len) { textnw(const char *text, unsigned int len) {
XRectangle r; XRectangle r;
if(dc.font.set) { if(dc.font.set) {
@ -1427,7 +1446,7 @@ textnw(const char *text, uint len) {
void void
tile(void) { tile(void) {
int x, y, h, w, mw; int x, y, h, w, mw;
uint i, n; unsigned int i, n;
Client *c; Client *c;
for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++); for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next), n++);
@ -1476,34 +1495,25 @@ togglefloating(const Arg *arg) {
arrange(); arrange();
} }
void
togglelayout(const Arg *arg) {
if(arg && arg->v)
lt = (Layout *)arg->v;
else if(++lt == &layouts[LENGTH(layouts)])
lt = &layouts[0];
if(sel)
arrange();
else
drawbar();
}
void
togglemax(const Arg *arg) {
ismax = !ismax;
arrange();
}
void void
toggletag(const Arg *arg) { toggletag(const Arg *arg) {
if(sel && (sel->tags ^= (arg->ui & TAGMASK))) unsigned int mask = sel->tags ^ (arg->ui & TAGMASK);
if(sel && mask) {
sel->tags = mask;
arrange(); arrange();
}
} }
void void
toggleview(const Arg *arg) { toggleview(const Arg *arg) {
if((tagset[seltags] ^= (arg->ui & TAGMASK))) unsigned int mask = tagset[seltags] ^ (arg->ui & TAGMASK);
if(mask) {
tagset[seltags] = mask;
clearurgent();
arrange(); arrange();
}
} }
void void
@ -1548,16 +1558,24 @@ updatebar(void) {
void void
updategeom(void) { updategeom(void) {
#ifdef XINERAMA #ifdef XINERAMA
int i; int n, i = 0;
XineramaScreenInfo *info = NULL; XineramaScreenInfo *info = NULL;
/* window area geometry */ /* window area geometry */
if(XineramaIsActive(dpy)) { if(XineramaIsActive(dpy) && (info = XineramaQueryScreens(dpy, &n))) {
info = XineramaQueryScreens(dpy, &i); if(n > 1) {
wx = info[xidx].x_org; int di, x, y;
wy = showbar && topbar ? info[xidx].y_org + bh : info[xidx].y_org; unsigned int dui;
ww = info[xidx].width; Window dummy;
wh = showbar ? info[xidx].height - bh : info[xidx].height; if(XQueryPointer(dpy, root, &dummy, &dummy, &x, &y, &di, &di, &dui))
for(i = 0; i < n; i++)
if(INRECT(x, y, info[i].x_org, info[i].y_org, info[i].width, info[i].height))
break;
}
wx = info[i].x_org;
wy = showbar && topbar ? info[i].y_org + bh : info[i].y_org;
ww = info[i].width;
wh = showbar ? info[i].height - bh : info[i].height;
XFree(info); XFree(info);
} }
else else
@ -1632,19 +1650,25 @@ updatewmhints(Client *c) {
XWMHints *wmh; XWMHints *wmh;
if((wmh = XGetWMHints(dpy, c->win))) { if((wmh = XGetWMHints(dpy, c->win))) {
if(c == sel) if(ISVISIBLE(c) && wmh->flags & XUrgencyHint) {
sel->isurgent = False; wmh->flags &= ~XUrgencyHint;
XSetWMHints(dpy, c->win, wmh);
}
else else
c->isurgent = (wmh->flags & XUrgencyHint) ? True : False; c->isurgent = (wmh->flags & XUrgencyHint) ? True : False;
XFree(wmh); XFree(wmh);
} }
} }
void void
view(const Arg *arg) { view(const Arg *arg) {
if(arg && (arg->i & TAGMASK) == tagset[seltags])
return;
seltags ^= 1; /* toggle sel tagset */ seltags ^= 1; /* toggle sel tagset */
if(arg && (arg->ui & TAGMASK)) if(arg && (arg->ui & TAGMASK))
tagset[seltags] = arg->i & TAGMASK; tagset[seltags] = arg->i & TAGMASK;
clearurgent();
arrange(); arrange();
} }
@ -1685,7 +1709,7 @@ void
zoom(const Arg *arg) { zoom(const Arg *arg) {
Client *c = sel; Client *c = sel;
if(ismax || !lt->arrange || (sel && sel->isfloating)) if(!lt[sellt]->arrange || lt[sellt]->arrange == monocle || (sel && sel->isfloating))
return; return;
if(c == nexttiled(clients)) if(c == nexttiled(clients))
if(!c || !(c = nexttiled(c->next))) if(!c || !(c = nexttiled(c->next)))
@ -1699,13 +1723,15 @@ zoom(const Arg *arg) {
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
if(argc == 2 && !strcmp("-v", argv[1])) if(argc == 2 && !strcmp("-v", argv[1]))
eprint("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n"); die("dwm-"VERSION", © 2006-2008 dwm engineers, see LICENSE for details\n");
else if(argc != 1) else if(argc != 1)
eprint("usage: dwm [-v]\n"); die("usage: dwm [-v]\n");
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fprintf(stderr, "warning: no locale support\n");
setlocale(LC_CTYPE, "");
if(!(dpy = XOpenDisplay(0))) if(!(dpy = XOpenDisplay(0)))
eprint("dwm: cannot open display\n"); die("dwm: cannot open display\n");
checkotherwm(); checkotherwm();
setup(); setup();