From 224ebc63328a850b3c2a76e0dc54b2b10c7c3902 Mon Sep 17 00:00:00 2001 From: lucy Date: Wed, 18 Mar 2026 10:41:32 +0100 Subject: [PATCH] add preserveonrestart patch --- dwm | Bin 89240 -> 89280 bytes dwm.c | 4196 +++++++++++++++++++++++++++++---------------------------- dwm.o | Bin 83568 -> 84528 bytes 3 files changed, 2145 insertions(+), 2051 deletions(-) diff --git a/dwm b/dwm index 643653a33a03a42559b85f47347bba6f30924c88..7505fc973beb9b8c780273863d65d530564b9b15 100755 GIT binary patch delta 27795 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 T{odZ4J5=qc7PwapRh#`E2hIpp diff --git a/dwm.c b/dwm.c index 743a4b7..884f614 100644 --- a/dwm.c +++ b/dwm.c @@ -20,6 +20,12 @@ * * To understand everything else, start reading main(). */ +#include +#include +#include +#include +#include +#include #include #include #include @@ -27,16 +33,10 @@ #include #include #include -#include -#include #include +#include #include -#include -#include -#include -#include -#include -#include +#include #ifdef XINERAMA #include #endif /* XINERAMA */ @@ -46,126 +46,178 @@ #include "util.h" /* macros */ -#define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) -#define CLEANMASK(mask) (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)) -#define INTERSECT(x,y,w,h,m) (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \ - * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy))) -#define ISVISIBLEONTAG(C, T) ((C->tags & T)) -#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) -#define MOUSEMASK (BUTTONMASK|PointerMotionMask) -#define WIDTH(X) ((X)->w + 2 * (X)->bw) -#define HEIGHT(X) ((X)->h + 2 * (X)->bw) -#define TAGMASK ((1 << LENGTH(tags)) - 1) -#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) +#define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) +#define CLEANMASK(mask) (mask & ~(numlockmask | LockMask) & (ShiftMask | ControlMask | Mod1Mask | Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)) +#define INTERSECT(x, y, w, h, m) (MAX(0, MIN((x) + (w), (m)->wx + (m)->ww) - MAX((x), (m)->wx)) * MAX(0, MIN((y) + (h), (m)->wy + (m)->wh) - MAX((y), (m)->wy))) +#define ISVISIBLEONTAG(C, T) ((C->tags & T)) +#define ISVISIBLE(C) ISVISIBLEONTAG(C, C->mon->tagset[C->mon->seltags]) +#define MOUSEMASK (BUTTONMASK | PointerMotionMask) +#define WIDTH(X) ((X)->w + 2 * (X)->bw) +#define HEIGHT(X) ((X)->h + 2 * (X)->bw) +#define TAGMASK ((1 << LENGTH(tags)) - 1) +#define TEXTW(X) (drw_fontset_getwidth(drw, (X)) + lrpad) -#define SYSTEM_TRAY_REQUEST_DOCK 0 +#define SYSTEM_TRAY_REQUEST_DOCK 0 /* XEMBED messages */ -#define XEMBED_EMBEDDED_NOTIFY 0 -#define XEMBED_WINDOW_ACTIVATE 1 -#define XEMBED_FOCUS_IN 4 -#define XEMBED_MODALITY_ON 10 -#define XEMBED_MAPPED (1 << 0) -#define XEMBED_WINDOW_ACTIVATE 1 -#define XEMBED_WINDOW_DEACTIVATE 2 -#define VERSION_MAJOR 0 -#define VERSION_MINOR 0 +#define XEMBED_EMBEDDED_NOTIFY 0 +#define XEMBED_WINDOW_ACTIVATE 1 +#define XEMBED_FOCUS_IN 4 +#define XEMBED_MODALITY_ON 10 +#define XEMBED_MAPPED (1 << 0) +#define XEMBED_WINDOW_ACTIVATE 1 +#define XEMBED_WINDOW_DEACTIVATE 2 +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 #define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR /* enums */ -enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ -enum { SchemeNorm, SchemeSel }; /* color schemes */ -enum { NetSupported, NetWMName, NetWMState, NetWMCheck, - NetSystemTray, NetSystemTrayOP, NetSystemTrayOrientation, NetSystemTrayOrientationHorz, - NetWMFullscreen, NetActiveWindow, NetWMWindowType, - NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */ -enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */ -enum { WMProtocols, WMDelete, WMState, WMTakeFocus, WMLast }; /* default atoms */ -enum { ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, - ClkClientWin, ClkRootWin, ClkLast }; /* clicks */ +enum +{ + CurNormal, + CurResize, + CurMove, + CurLast +}; /* cursor */ +enum +{ + SchemeNorm, + SchemeSel +}; /* color schemes */ +enum +{ + NetSupported, + NetWMName, + NetWMState, + NetWMCheck, + NetSystemTray, + NetSystemTrayOP, + NetSystemTrayOrientation, + NetSystemTrayOrientationHorz, + NetWMFullscreen, + NetActiveWindow, + NetWMWindowType, + NetWMWindowTypeDialog, + NetClientList, + NetClientInfo, + NetLast +}; /* EWMH atoms */ +enum +{ + Manager, + Xembed, + XembedInfo, + XLast +}; /* Xembed atoms */ +enum +{ + WMProtocols, + WMDelete, + WMState, + WMTakeFocus, + WMLast +}; /* default atoms */ +enum +{ + ClkTagBar, + ClkLtSymbol, + ClkStatusText, + ClkWinTitle, + ClkClientWin, + ClkRootWin, + ClkLast +}; /* clicks */ -typedef union { - int i; - unsigned int ui; - float f; - const void *v; +typedef union +{ + int i; + unsigned int ui; + float f; + const void *v; } Arg; -typedef struct { - unsigned int click; - unsigned int mask; - unsigned int button; - void (*func)(const Arg *arg); - const Arg arg; +typedef struct +{ + unsigned int click; + unsigned int mask; + unsigned int button; + void (*func)(const Arg *arg); + const Arg arg; } Button; typedef struct Monitor Monitor; typedef struct Client Client; -struct Client { - char name[256]; - float mina, maxa; - float cfact; - int x, y, w, h; - int oldx, oldy, oldw, oldh; - int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; - int bw, oldbw; - unsigned int tags; - int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; - Client *next; - Client *snext; - Monitor *mon; - Window win; +struct Client +{ + char name[256]; + float mina, maxa; + float cfact; + int x, y, w, h; + int oldx, oldy, oldw, oldh; + int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + Client *next; + Client *snext; + Monitor *mon; + Window win; }; -typedef struct { - unsigned int mod; - KeySym keysym; - void (*func)(const Arg *); - const Arg arg; +typedef struct +{ + unsigned int mod; + KeySym keysym; + void (*func)(const Arg *); + const Arg arg; } Key; -typedef struct { - const char *symbol; - void (*arrange)(Monitor *); +typedef struct +{ + const char *symbol; + void (*arrange)(Monitor *); } Layout; -struct Monitor { - char ltsymbol[16]; - float mfact; - int nmaster; - int num; - int by; /* bar geometry */ - int mx, my, mw, mh; /* screen size */ - int wx, wy, ww, wh; /* window area */ - int gappih; /* horizontal gap between windows */ - int gappiv; /* vertical gap between windows */ - int gappoh; /* horizontal outer gaps */ - int gappov; /* vertical outer gaps */ - unsigned int seltags; - unsigned int sellt; - unsigned int tagset[2]; - int showbar; - int topbar; - Client *clients; - Client *sel; - Client *stack; - Monitor *next; - Window barwin; - const Layout *lt[2]; +struct Monitor +{ + char ltsymbol[16]; + float mfact; + int nmaster; + int num; + int by; /* bar geometry */ + int mx, my, mw, mh; /* screen size */ + int wx, wy, ww, wh; /* window area */ + int gappih; /* horizontal gap between windows */ + int gappiv; /* vertical gap between windows */ + int gappoh; /* horizontal outer gaps */ + int gappov; /* vertical outer gaps */ + unsigned int seltags; + unsigned int sellt; + unsigned int tagset[2]; + int showbar; + int topbar; + Client *clients; + Client *sel; + Client *stack; + Monitor *next; + Window barwin; + const Layout *lt[2]; }; -typedef struct { - const char *class; - const char *instance; - const char *title; - unsigned int tags; - int isfloating; - int monitor; +typedef struct +{ + const char *class; + const char *instance; + const char *title; + unsigned int tags; + int isfloating; + int monitor; } Rule; -typedef struct Systray Systray; -struct Systray { - Window win; - Client *icons; +typedef struct Systray Systray; +struct Systray +{ + Window win; + Client *icons; }; /* function declarations */ @@ -232,6 +284,7 @@ static void scan(void); static int sendevent(Window w, Atom proto, int m, long d0, long d1, long d2, long d3, long d4); static void sendmon(Client *c, Monitor *m); static void setclientstate(Client *c, long state); +static void setclienttagprop(Client *c); static void setfocus(Client *c); static void setfullscreen(Client *c, int fullscreen); static void setlayout(const Arg *arg); @@ -282,28 +335,14 @@ static const char dwmdir[] = "dwm"; static const char localshare[] = ".local/share"; static char stext[256]; static int screen; -static int sw, sh; /* X display screen geometry width, height */ -static int bh; /* bar height */ -static int lrpad; /* sum of left and right padding for text */ +static int sw, sh; /* X display screen geometry width, height */ +static int bh; /* bar height */ +static int lrpad; /* sum of left and right padding for text */ static int (*xerrorxlib)(Display *, XErrorEvent *); static unsigned int numlockmask = 0; -static void (*handler[LASTEvent]) (XEvent *) = { - [ButtonPress] = buttonpress, - [ClientMessage] = clientmessage, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [Expose] = expose, - [FocusIn] = focusin, - [KeyPress] = keypress, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [MotionNotify] = motionnotify, - [PropertyNotify] = propertynotify, - [ResizeRequest] = resizerequest, - [UnmapNotify] = unmapnotify -}; +static void (*handler[LASTEvent])(XEvent *) = {[ButtonPress] = buttonpress, [ClientMessage] = clientmessage, [ConfigureRequest] = configurerequest, [ConfigureNotify] = configurenotify, [DestroyNotify] = destroynotify, [EnterNotify] = enternotify, [Expose] = expose, + [FocusIn] = focusin, [KeyPress] = keypress, [MappingNotify] = mappingnotify, [MapRequest] = maprequest, [MotionNotify] = motionnotify, [PropertyNotify] = propertynotify, [ResizeRequest] = resizerequest, + [UnmapNotify] = unmapnotify}; static Atom wmatom[WMLast], netatom[NetLast], xatom[XLast]; static int running = 1; static Cur *cursor[CurLast]; @@ -317,2324 +356,2379 @@ static Window root, wmcheckwin; #include "config.h" /* compile-time check if all tags fit into an unsigned int bit array. */ -struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; +struct NumTags +{ + char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; +}; /* function implementations */ -void -applyrules(Client *c) +void applyrules(Client *c) { - const char *class, *instance; - unsigned int i; - const Rule *r; - Monitor *m; - XClassHint ch = { NULL, NULL }; + const char *class, *instance; + unsigned int i; + const Rule *r; + Monitor *m; + XClassHint ch = {NULL, NULL}; - /* rule matching */ - c->isfloating = 0; - c->tags = 0; - XGetClassHint(dpy, c->win, &ch); - class = ch.res_class ? ch.res_class : broken; - instance = ch.res_name ? ch.res_name : broken; + /* rule matching */ + c->isfloating = 0; + c->tags = 0; + XGetClassHint(dpy, c->win, &ch); + class = ch.res_class ? ch.res_class : broken; + instance = ch.res_name ? ch.res_name : broken; - for (i = 0; i < LENGTH(rules); i++) { - r = &rules[i]; - if ((!r->title || strstr(c->name, r->title)) - && (!r->class || strstr(class, r->class)) - && (!r->instance || strstr(instance, r->instance))) - { - c->isfloating = r->isfloating; - c->tags |= r->tags; - for (m = mons; m && m->num != r->monitor; m = m->next); - if (m) - c->mon = m; - } - } - if (ch.res_class) - XFree(ch.res_class); - if (ch.res_name) - XFree(ch.res_name); - c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; + for (i = 0; i < LENGTH(rules); i++) + { + r = &rules[i]; + if ((!r->title || strstr(c->name, r->title)) && (!r->class || strstr(class, r->class)) && (!r->instance || strstr(instance, r->instance))) + { + c->isfloating = r->isfloating; + c->tags |= r->tags; + for (m = mons; m && m->num != r->monitor; m = m->next) + ; + if (m) + c->mon = m; + } + } + if (ch.res_class) + XFree(ch.res_class); + if (ch.res_name) + XFree(ch.res_name); + c->tags = c->tags & TAGMASK ? c->tags & TAGMASK : c->mon->tagset[c->mon->seltags]; } -int -applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) +int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact) { - int baseismin; - Monitor *m = c->mon; + int baseismin; + Monitor *m = c->mon; - /* set minimum possible */ - *w = MAX(1, *w); - *h = MAX(1, *h); - if (interact) { - if (*x > sw) - *x = sw - WIDTH(c); - if (*y > sh) - *y = sh - HEIGHT(c); - if (*x + *w + 2 * c->bw < 0) - *x = 0; - if (*y + *h + 2 * c->bw < 0) - *y = 0; - } else { - if (*x >= m->wx + m->ww) - *x = m->wx + m->ww - WIDTH(c); - if (*y >= m->wy + m->wh) - *y = m->wy + m->wh - HEIGHT(c); - if (*x + *w + 2 * c->bw <= m->wx) - *x = m->wx; - if (*y + *h + 2 * c->bw <= m->wy) - *y = m->wy; - } - if (*h < bh) - *h = bh; - if (*w < bh) - *w = bh; - if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) { - if (!c->hintsvalid) - updatesizehints(c); - /* see last two sentences in ICCCM 4.1.2.3 */ - baseismin = c->basew == c->minw && c->baseh == c->minh; - if (!baseismin) { /* temporarily remove base dimensions */ - *w -= c->basew; - *h -= c->baseh; - } - /* adjust for aspect limits */ - if (c->mina > 0 && c->maxa > 0) { - if (c->maxa < (float)*w / *h) - *w = *h * c->maxa + 0.5; - else if (c->mina < (float)*h / *w) - *h = *w * c->mina + 0.5; - } - if (baseismin) { /* increment calculation requires this */ - *w -= c->basew; - *h -= c->baseh; - } - /* adjust for increment value */ - if (c->incw) - *w -= *w % c->incw; - if (c->inch) - *h -= *h % c->inch; - /* restore base dimensions */ - *w = MAX(*w + c->basew, c->minw); - *h = MAX(*h + c->baseh, c->minh); - if (c->maxw) - *w = MIN(*w, c->maxw); - if (c->maxh) - *h = MIN(*h, c->maxh); - } - return *x != c->x || *y != c->y || *w != c->w || *h != c->h; + /* set minimum possible */ + *w = MAX(1, *w); + *h = MAX(1, *h); + if (interact) + { + if (*x > sw) + *x = sw - WIDTH(c); + if (*y > sh) + *y = sh - HEIGHT(c); + if (*x + *w + 2 * c->bw < 0) + *x = 0; + if (*y + *h + 2 * c->bw < 0) + *y = 0; + } + else + { + if (*x >= m->wx + m->ww) + *x = m->wx + m->ww - WIDTH(c); + if (*y >= m->wy + m->wh) + *y = m->wy + m->wh - HEIGHT(c); + if (*x + *w + 2 * c->bw <= m->wx) + *x = m->wx; + if (*y + *h + 2 * c->bw <= m->wy) + *y = m->wy; + } + if (*h < bh) + *h = bh; + if (*w < bh) + *w = bh; + if (resizehints || c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) + { + if (!c->hintsvalid) + updatesizehints(c); + /* see last two sentences in ICCCM 4.1.2.3 */ + baseismin = c->basew == c->minw && c->baseh == c->minh; + if (!baseismin) + { /* temporarily remove base dimensions */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for aspect limits */ + if (c->mina > 0 && c->maxa > 0) + { + if (c->maxa < (float)*w / *h) + *w = *h * c->maxa + 0.5; + else if (c->mina < (float)*h / *w) + *h = *w * c->mina + 0.5; + } + if (baseismin) + { /* increment calculation requires this */ + *w -= c->basew; + *h -= c->baseh; + } + /* adjust for increment value */ + if (c->incw) + *w -= *w % c->incw; + if (c->inch) + *h -= *h % c->inch; + /* restore base dimensions */ + *w = MAX(*w + c->basew, c->minw); + *h = MAX(*h + c->baseh, c->minh); + if (c->maxw) + *w = MIN(*w, c->maxw); + if (c->maxh) + *h = MIN(*h, c->maxh); + } + return *x != c->x || *y != c->y || *w != c->w || *h != c->h; } -void -arrange(Monitor *m) +void arrange(Monitor *m) { - if (m) - showhide(m->stack); - else for (m = mons; m; m = m->next) - showhide(m->stack); - if (m) { - arrangemon(m); - restack(m); - } else for (m = mons; m; m = m->next) - arrangemon(m); + if (m) + showhide(m->stack); + else + for (m = mons; m; m = m->next) + showhide(m->stack); + if (m) + { + arrangemon(m); + restack(m); + } + else + for (m = mons; m; m = m->next) + arrangemon(m); } -void -arrangemon(Monitor *m) +void arrangemon(Monitor *m) { - strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); - if (m->lt[m->sellt]->arrange) - m->lt[m->sellt]->arrange(m); + strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, sizeof m->ltsymbol); + if (m->lt[m->sellt]->arrange) + m->lt[m->sellt]->arrange(m); } -void -attach(Client *c) +void attach(Client *c) { - c->next = c->mon->clients; - c->mon->clients = c; + c->next = c->mon->clients; + c->mon->clients = c; } -void -attachBelow(Client *c) +void attachBelow(Client *c) { - //If there is nothing on the monitor or the selected client is floating, attach as normal - if(c->mon->sel == NULL || c->mon->sel->isfloating) { - Client *at = nexttagged(c); - if(!at) { - attach(c); - return; - } - c->next = at->next; - at->next = c; - return; - } - - //Set the new client's next property to the same as the currently selected clients next - c->next = c->mon->sel->next; - //Set the currently selected clients next property to the new client - c->mon->sel->next = c; + // If there is nothing on the monitor or the selected client is floating, attach as normal + if (c->mon->sel == NULL || c->mon->sel->isfloating) + { + Client *at = nexttagged(c); + if (!at) + { + attach(c); + return; + } + c->next = at->next; + at->next = c; + return; + } + // Set the new client's next property to the same as the currently selected clients next + c->next = c->mon->sel->next; + // Set the currently selected clients next property to the new client + c->mon->sel->next = c; } -void -attachstack(Client *c) +void attachstack(Client *c) { - c->snext = c->mon->stack; - c->mon->stack = c; + c->snext = c->mon->stack; + c->mon->stack = c; } -void -buttonpress(XEvent *e) +void buttonpress(XEvent *e) { - unsigned int i, x, click; - Arg arg = {0}; - Client *c; - Monitor *m; - XButtonPressedEvent *ev = &e->xbutton; + unsigned int i, x, click; + Arg arg = {0}; + Client *c; + Monitor *m; + XButtonPressedEvent *ev = &e->xbutton; - click = ClkRootWin; - /* focus monitor if necessary */ - if ((m = wintomon(ev->window)) && m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - focus(NULL); - } - if (ev->window == selmon->barwin) { - i = x = 0; - do - x += TEXTW(tags[i]); - while (ev->x >= x && ++i < LENGTH(tags)); - if (i < LENGTH(tags)) { - click = ClkTagBar; - arg.ui = 1 << i; - } else if (ev->x < x + TEXTW(selmon->ltsymbol)) - click = ClkLtSymbol; - else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) - click = ClkStatusText; - else - click = ClkWinTitle; - } else if ((c = wintoclient(ev->window))) { - focus(c); - restack(selmon); - XAllowEvents(dpy, ReplayPointer, CurrentTime); - click = ClkClientWin; - } - for (i = 0; i < LENGTH(buttons); i++) - if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button - && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) - buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); + click = ClkRootWin; + /* focus monitor if necessary */ + if ((m = wintomon(ev->window)) && m != selmon) + { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + if (ev->window == selmon->barwin) + { + i = x = 0; + do + x += TEXTW(tags[i]); + while (ev->x >= x && ++i < LENGTH(tags)); + if (i < LENGTH(tags)) + { + click = ClkTagBar; + arg.ui = 1 << i; + } + else if (ev->x < x + TEXTW(selmon->ltsymbol)) + click = ClkLtSymbol; + else if (ev->x > selmon->ww - (int)TEXTW(stext) - getsystraywidth()) + click = ClkStatusText; + else + click = ClkWinTitle; + } + else if ((c = wintoclient(ev->window))) + { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } + for (i = 0; i < LENGTH(buttons); i++) + if (click == buttons[i].click && buttons[i].func && buttons[i].button == ev->button && CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].func(click == ClkTagBar && buttons[i].arg.i == 0 ? &arg : &buttons[i].arg); } -void -checkotherwm(void) +void checkotherwm(void) { - xerrorxlib = XSetErrorHandler(xerrorstart); - /* this causes an error if some other window manager is running */ - XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); - XSync(dpy, False); - XSetErrorHandler(xerror); - XSync(dpy, False); + xerrorxlib = XSetErrorHandler(xerrorstart); + /* this causes an error if some other window manager is running */ + XSelectInput(dpy, DefaultRootWindow(dpy), SubstructureRedirectMask); + XSync(dpy, False); + XSetErrorHandler(xerror); + XSync(dpy, False); } -void -cleanup(void) +void cleanup(void) { - Arg a = {.ui = ~0}; - Layout foo = { "", NULL }; - Monitor *m; - size_t i; + Arg a = {.ui = ~0}; + Layout foo = {"", NULL}; + Monitor *m; + size_t i; - view(&a); - selmon->lt[selmon->sellt] = &foo; - for (m = mons; m; m = m->next) - while (m->stack) - unmanage(m->stack, 0); - XUngrabKey(dpy, AnyKey, AnyModifier, root); - while (mons) - cleanupmon(mons); + view(&a); + selmon->lt[selmon->sellt] = &foo; + for (m = mons; m; m = m->next) + while (m->stack) + unmanage(m->stack, 0); + XUngrabKey(dpy, AnyKey, AnyModifier, root); + while (mons) + cleanupmon(mons); - if (showsystray) { - XUnmapWindow(dpy, systray->win); - XDestroyWindow(dpy, systray->win); - free(systray); - } + if (showsystray) + { + XUnmapWindow(dpy, systray->win); + XDestroyWindow(dpy, systray->win); + free(systray); + } - for (i = 0; i < CurLast; i++) - drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) - drw_scm_free(drw, scheme[i], 3); - free(scheme); - XDestroyWindow(dpy, wmcheckwin); - drw_free(drw); - XSync(dpy, False); - XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors); i++) + drw_scm_free(drw, scheme[i], 3); + free(scheme); + XDestroyWindow(dpy, wmcheckwin); + drw_free(drw); + XSync(dpy, False); + XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); } -void -cleanupmon(Monitor *mon) +void cleanupmon(Monitor *mon) { - Monitor *m; + Monitor *m; - if (mon == mons) - mons = mons->next; - else { - for (m = mons; m && m->next != mon; m = m->next); - m->next = mon->next; - } - XUnmapWindow(dpy, mon->barwin); - XDestroyWindow(dpy, mon->barwin); - free(mon); + if (mon == mons) + mons = mons->next; + else + { + for (m = mons; m && m->next != mon; m = m->next) + ; + m->next = mon->next; + } + XUnmapWindow(dpy, mon->barwin); + XDestroyWindow(dpy, mon->barwin); + free(mon); } -void -clientmessage(XEvent *e) +void clientmessage(XEvent *e) { - XWindowAttributes wa; - XSetWindowAttributes swa; - XClientMessageEvent *cme = &e->xclient; - Client *c = wintoclient(cme->window); + XWindowAttributes wa; + XSetWindowAttributes swa; + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); - if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) { - /* add systray icons */ - if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) { - if (!(c = (Client *)calloc(1, sizeof(Client)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Client)); - if (!(c->win = cme->data.l[2])) { - free(c); - return; - } - c->mon = selmon; - c->next = systray->icons; - systray->icons = c; - if (!XGetWindowAttributes(dpy, c->win, &wa)) { - /* use sane defaults */ - wa.width = bh; - wa.height = bh; - wa.border_width = 0; - } - c->x = c->oldx = c->y = c->oldy = 0; - c->w = c->oldw = wa.width; - c->h = c->oldh = wa.height; - c->oldbw = wa.border_width; - c->bw = 0; - c->isfloating = True; - /* reuse tags field as mapped status */ - c->tags = 1; - updatesizehints(c); - updatesystrayicongeom(c, wa.width, wa.height); - XAddToSaveSet(dpy, c->win); - XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); - XReparentWindow(dpy, c->win, systray->win, 0, 0); - /* use parents background color */ - swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - /* FIXME not sure if I have to send these events, too */ - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0 , systray->win, XEMBED_EMBEDDED_VERSION); - XSync(dpy, False); - resizebarwin(selmon); - updatesystray(); - setclientstate(c, NormalState); - } - return; - } + if (showsystray && cme->window == systray->win && cme->message_type == netatom[NetSystemTrayOP]) + { + /* add systray icons */ + if (cme->data.l[1] == SYSTEM_TRAY_REQUEST_DOCK) + { + if (!(c = (Client *)calloc(1, sizeof(Client)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Client)); + if (!(c->win = cme->data.l[2])) + { + free(c); + return; + } + c->mon = selmon; + c->next = systray->icons; + systray->icons = c; + if (!XGetWindowAttributes(dpy, c->win, &wa)) + { + /* use sane defaults */ + wa.width = bh; + wa.height = bh; + wa.border_width = 0; + } + c->x = c->oldx = c->y = c->oldy = 0; + c->w = c->oldw = wa.width; + c->h = c->oldh = wa.height; + c->oldbw = wa.border_width; + c->bw = 0; + c->isfloating = True; + /* reuse tags field as mapped status */ + c->tags = 1; + updatesizehints(c); + updatesystrayicongeom(c, wa.width, wa.height); + XAddToSaveSet(dpy, c->win); + XSelectInput(dpy, c->win, StructureNotifyMask | PropertyChangeMask | ResizeRedirectMask); + XReparentWindow(dpy, c->win, systray->win, 0, 0); + /* use parents background color */ + swa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XChangeWindowAttributes(dpy, c->win, CWBackPixel, &swa); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, systray->win, XEMBED_EMBEDDED_VERSION); + /* FIXME not sure if I have to send these events, too */ + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_FOCUS_IN, 0, systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); + sendevent(c->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_MODALITY_ON, 0, systray->win, XEMBED_EMBEDDED_VERSION); + XSync(dpy, False); + resizebarwin(selmon); + updatesystray(); + setclientstate(c, NormalState); + } + return; + } - if (!c) - return; - if (cme->message_type == netatom[NetWMState]) { - if (cme->data.l[1] == netatom[NetWMFullscreen] - || cme->data.l[2] == netatom[NetWMFullscreen]) - setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ - || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); - } else if (cme->message_type == netatom[NetActiveWindow]) { - if (c != selmon->sel && !c->isurgent) - seturgent(c, 1); - } + if (!c) + return; + if (cme->message_type == netatom[NetWMState]) + { + if (cme->data.l[1] == netatom[NetWMFullscreen] || cme->data.l[2] == netatom[NetWMFullscreen]) + setfullscreen(c, (cme->data.l[0] == 1 /* _NET_WM_STATE_ADD */ + || (cme->data.l[0] == 2 /* _NET_WM_STATE_TOGGLE */ && !c->isfullscreen))); + } + else if (cme->message_type == netatom[NetActiveWindow]) + { + if (c != selmon->sel && !c->isurgent) + seturgent(c, 1); + } } -void -configure(Client *c) +void configure(Client *c) { - XConfigureEvent ce; + XConfigureEvent ce; - ce.type = ConfigureNotify; - ce.display = dpy; - ce.event = c->win; - ce.window = c->win; - ce.x = c->x; - ce.y = c->y; - ce.width = c->w; - ce.height = c->h; - ce.border_width = c->bw; - ce.above = None; - ce.override_redirect = False; - XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); + ce.type = ConfigureNotify; + ce.display = dpy; + ce.event = c->win; + ce.window = c->win; + ce.x = c->x; + ce.y = c->y; + ce.width = c->w; + ce.height = c->h; + ce.border_width = c->bw; + ce.above = None; + ce.override_redirect = False; + XSendEvent(dpy, c->win, False, StructureNotifyMask, (XEvent *)&ce); } -void -configurenotify(XEvent *e) +void configurenotify(XEvent *e) { - Monitor *m; - Client *c; - XConfigureEvent *ev = &e->xconfigure; - int dirty; + Monitor *m; + Client *c; + XConfigureEvent *ev = &e->xconfigure; + int dirty; - /* TODO: updategeom handling sucks, needs to be simplified */ - if (ev->window == root) { - dirty = (sw != ev->width || sh != ev->height); - sw = ev->width; - sh = ev->height; - if (updategeom() || dirty) { - drw_resize(drw, sw, bh); - updatebars(); - for (m = mons; m; m = m->next) { - for (c = m->clients; c; c = c->next) - if (c->isfullscreen) - resizeclient(c, m->mx, m->my, m->mw, m->mh); - resizebarwin(m); - } - focus(NULL); - arrange(NULL); - } - } + /* TODO: updategeom handling sucks, needs to be simplified */ + if (ev->window == root) + { + dirty = (sw != ev->width || sh != ev->height); + sw = ev->width; + sh = ev->height; + if (updategeom() || dirty) + { + drw_resize(drw, sw, bh); + updatebars(); + for (m = mons; m; m = m->next) + { + for (c = m->clients; c; c = c->next) + if (c->isfullscreen) + resizeclient(c, m->mx, m->my, m->mw, m->mh); + resizebarwin(m); + } + focus(NULL); + arrange(NULL); + } + } } -void -configurerequest(XEvent *e) +void configurerequest(XEvent *e) { - Client *c; - Monitor *m; - XConfigureRequestEvent *ev = &e->xconfigurerequest; - XWindowChanges wc; + Client *c; + Monitor *m; + XConfigureRequestEvent *ev = &e->xconfigurerequest; + XWindowChanges wc; - if ((c = wintoclient(ev->window))) { - if (ev->value_mask & CWBorderWidth) - c->bw = ev->border_width; - else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) { - m = c->mon; - if (ev->value_mask & CWX) { - c->oldx = c->x; - c->x = m->mx + ev->x; - } - if (ev->value_mask & CWY) { - c->oldy = c->y; - c->y = m->my + ev->y; - } - if (ev->value_mask & CWWidth) { - c->oldw = c->w; - c->w = ev->width; - } - if (ev->value_mask & CWHeight) { - c->oldh = c->h; - c->h = ev->height; - } - if ((c->x + c->w) > m->mx + m->mw && c->isfloating) - c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ - if ((c->y + c->h) > m->my + m->mh && c->isfloating) - c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ - if ((ev->value_mask & (CWX|CWY)) && !(ev->value_mask & (CWWidth|CWHeight))) - configure(c); - if (ISVISIBLE(c)) - XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); - } else - configure(c); - } else { - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); - } - XSync(dpy, False); + if ((c = wintoclient(ev->window))) + { + if (ev->value_mask & CWBorderWidth) + c->bw = ev->border_width; + else if (c->isfloating || !selmon->lt[selmon->sellt]->arrange) + { + m = c->mon; + if (ev->value_mask & CWX) + { + c->oldx = c->x; + c->x = m->mx + ev->x; + } + if (ev->value_mask & CWY) + { + c->oldy = c->y; + c->y = m->my + ev->y; + } + if (ev->value_mask & CWWidth) + { + c->oldw = c->w; + c->w = ev->width; + } + if (ev->value_mask & CWHeight) + { + c->oldh = c->h; + c->h = ev->height; + } + if ((c->x + c->w) > m->mx + m->mw && c->isfloating) + c->x = m->mx + (m->mw / 2 - WIDTH(c) / 2); /* center in x direction */ + if ((c->y + c->h) > m->my + m->mh && c->isfloating) + c->y = m->my + (m->mh / 2 - HEIGHT(c) / 2); /* center in y direction */ + if ((ev->value_mask & (CWX | CWY)) && !(ev->value_mask & (CWWidth | CWHeight))) + configure(c); + if (ISVISIBLE(c)) + XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h); + } + else + configure(c); + } + else + { + wc.x = ev->x; + wc.y = ev->y; + wc.width = ev->width; + wc.height = ev->height; + wc.border_width = ev->border_width; + wc.sibling = ev->above; + wc.stack_mode = ev->detail; + XConfigureWindow(dpy, ev->window, ev->value_mask, &wc); + } + XSync(dpy, False); } -Monitor * -createmon(void) +Monitor *createmon(void) { - Monitor *m; + Monitor *m; - m = ecalloc(1, sizeof(Monitor)); - m->tagset[0] = m->tagset[1] = 1; - m->mfact = mfact; - m->nmaster = nmaster; - m->showbar = showbar; - m->topbar = topbar; - m->gappih = gappih; - m->gappiv = gappiv; - m->gappoh = gappoh; - m->gappov = gappov; - m->lt[0] = &layouts[0]; - m->lt[1] = &layouts[1 % LENGTH(layouts)]; - strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); - return m; + m = ecalloc(1, sizeof(Monitor)); + m->tagset[0] = m->tagset[1] = 1; + m->mfact = mfact; + m->nmaster = nmaster; + m->showbar = showbar; + m->topbar = topbar; + m->gappih = gappih; + m->gappiv = gappiv; + m->gappoh = gappoh; + m->gappov = gappov; + m->lt[0] = &layouts[0]; + m->lt[1] = &layouts[1 % LENGTH(layouts)]; + strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); + return m; } -void -destroynotify(XEvent *e) +void destroynotify(XEvent *e) { - Client *c; - XDestroyWindowEvent *ev = &e->xdestroywindow; + Client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; - if ((c = wintoclient(ev->window))) - unmanage(c, 1); - else if ((c = wintosystrayicon(ev->window))) { - removesystrayicon(c); - resizebarwin(selmon); - updatesystray(); - } + if ((c = wintoclient(ev->window))) + unmanage(c, 1); + else if ((c = wintosystrayicon(ev->window))) + { + removesystrayicon(c); + resizebarwin(selmon); + updatesystray(); + } } -void -detach(Client *c) +void detach(Client *c) { - Client **tc; + Client **tc; - for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); - *tc = c->next; + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next) + ; + *tc = c->next; } -void -detachstack(Client *c) +void detachstack(Client *c) { - Client **tc, *t; + Client **tc, *t; - for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext); - *tc = c->snext; + for (tc = &c->mon->stack; *tc && *tc != c; tc = &(*tc)->snext) + ; + *tc = c->snext; - if (c == c->mon->sel) { - for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext); - c->mon->sel = t; - } + if (c == c->mon->sel) + { + for (t = c->mon->stack; t && !ISVISIBLE(t); t = t->snext) + ; + c->mon->sel = t; + } } -Monitor * -dirtomon(int dir) +Monitor *dirtomon(int dir) { - Monitor *m = NULL; + Monitor *m = NULL; - if (dir > 0) { - if (!(m = selmon->next)) - m = mons; - } else if (selmon == mons) - for (m = mons; m->next; m = m->next); - else - for (m = mons; m->next != selmon; m = m->next); - return m; + if (dir > 0) + { + if (!(m = selmon->next)) + m = mons; + } + else if (selmon == mons) + for (m = mons; m->next; m = m->next) + ; + else + for (m = mons; m->next != selmon; m = m->next) + ; + return m; } -void -drawbar(Monitor *m) +void drawbar(Monitor *m) { - int x, w, tw = 0, stw = 0; - int boxs = drw->fonts->h / 9; - int boxw = drw->fonts->h / 6 + 2; - unsigned int i, occ = 0, urg = 0; - Client *c; + int x, w, tw = 0, stw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; + Client *c; - if (!m->showbar) - return; + if (!m->showbar) + return; - if(showsystray && m == systraytomon(m) && !systrayonleft) - stw = getsystraywidth(); + if (showsystray && m == systraytomon(m) && !systrayonleft) + stw = getsystraywidth(); - /* draw status first so it can be overdrawn by tags later */ - if (m == selmon) { /* status is only drawn on selected monitor */ - drw_setscheme(drw, scheme[SchemeNorm]); - tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */ - drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); - } + /* draw status first so it can be overdrawn by tags later */ + if (m == selmon) + { /* status is only drawn on selected monitor */ + drw_setscheme(drw, scheme[SchemeNorm]); + tw = TEXTW(stext) - lrpad / 2 + 2; /* 2px extra right padding */ + drw_text(drw, m->ww - tw - stw, 0, tw, bh, lrpad / 2 - 2, stext, 0); + } - resizebarwin(m); - for (c = m->clients; c; c = c->next) { - occ |= c->tags; - if (c->isurgent) - urg |= c->tags; - } - x = 0; - for (i = 0; i < LENGTH(tags); i++) { - w = TEXTW(tags[i]); - drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); - if (occ & 1 << i) - drw_rect(drw, x + boxs, boxs, boxw, boxw, - m == selmon && selmon->sel && selmon->sel->tags & 1 << i, - urg & 1 << i); - x += w; - } - w = TEXTW(m->ltsymbol); - drw_setscheme(drw, scheme[SchemeNorm]); - x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + resizebarwin(m); + for (c = m->clients; c; c = c->next) + { + occ |= c->tags; + if (c->isurgent) + urg |= c->tags; + } + x = 0; + for (i = 0; i < LENGTH(tags); i++) + { + w = TEXTW(tags[i]); + drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, tags[i], urg & 1 << i); + if (occ & 1 << i) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m == selmon && selmon->sel && selmon->sel->tags & 1 << i, urg & 1 << i); + x += w; + } + w = TEXTW(m->ltsymbol); + drw_setscheme(drw, scheme[SchemeNorm]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); - if ((w = m->ww - tw - stw - x) > bh) { - if (m->sel) { - drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); - if (m->sel->isfloating) - drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); - } else { - drw_setscheme(drw, scheme[SchemeNorm]); - drw_rect(drw, x, 0, w, bh, 1, 1); - } - } - drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); + if ((w = m->ww - tw - stw - x) > bh) + { + if (m->sel) + { + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + if (m->sel->isfloating) + drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); + } + else + { + drw_setscheme(drw, scheme[SchemeNorm]); + drw_rect(drw, x, 0, w, bh, 1, 1); + } + } + drw_map(drw, m->barwin, 0, 0, m->ww - stw, bh); } -void -drawbars(void) +void drawbars(void) { - Monitor *m; + Monitor *m; - for (m = mons; m; m = m->next) - drawbar(m); + for (m = mons; m; m = m->next) + drawbar(m); } -void -enternotify(XEvent *e) +void enternotify(XEvent *e) { - Client *c; - Monitor *m; - XCrossingEvent *ev = &e->xcrossing; + Client *c; + Monitor *m; + XCrossingEvent *ev = &e->xcrossing; - if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) - return; - c = wintoclient(ev->window); - m = c ? c->mon : wintomon(ev->window); - if (m != selmon) { - unfocus(selmon->sel, 1); - selmon = m; - } else if (!c || c == selmon->sel) - return; - focus(c); + if ((ev->mode != NotifyNormal || ev->detail == NotifyInferior) && ev->window != root) + return; + c = wintoclient(ev->window); + m = c ? c->mon : wintomon(ev->window); + if (m != selmon) + { + unfocus(selmon->sel, 1); + selmon = m; + } + else if (!c || c == selmon->sel) + return; + focus(c); } -void -expose(XEvent *e) +void expose(XEvent *e) { - Monitor *m; - XExposeEvent *ev = &e->xexpose; + Monitor *m; + XExposeEvent *ev = &e->xexpose; - if (ev->count == 0 && (m = wintomon(ev->window))) { - drawbar(m); - if (m == selmon) - updatesystray(); - } + if (ev->count == 0 && (m = wintomon(ev->window))) + { + drawbar(m); + if (m == selmon) + updatesystray(); + } } -void -focus(Client *c) +void focus(Client *c) { - if (!c || !ISVISIBLE(c)) - for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext); - if (selmon->sel && selmon->sel != c) - unfocus(selmon->sel, 0); - if (c) { - if (c->mon != selmon) - selmon = c->mon; - if (c->isurgent) - seturgent(c, 0); - detachstack(c); - attachstack(c); - grabbuttons(c, 1); - XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); - setfocus(c); - } else { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } - selmon->sel = c; - drawbars(); + if (!c || !ISVISIBLE(c)) + for (c = selmon->stack; c && !ISVISIBLE(c); c = c->snext) + ; + if (selmon->sel && selmon->sel != c) + unfocus(selmon->sel, 0); + if (c) + { + if (c->mon != selmon) + selmon = c->mon; + if (c->isurgent) + seturgent(c, 0); + detachstack(c); + attachstack(c); + grabbuttons(c, 1); + XSetWindowBorder(dpy, c->win, scheme[SchemeSel][ColBorder].pixel); + setfocus(c); + } + else + { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } + selmon->sel = c; + drawbars(); } /* there are some broken focus acquiring clients needing extra handling */ -void -focusin(XEvent *e) +void focusin(XEvent *e) { - XFocusChangeEvent *ev = &e->xfocus; + XFocusChangeEvent *ev = &e->xfocus; - if (selmon->sel && ev->window != selmon->sel->win) - setfocus(selmon->sel); + if (selmon->sel && ev->window != selmon->sel->win) + setfocus(selmon->sel); } -void -focusmon(const Arg *arg) +void focusmon(const Arg *arg) { - Monitor *m; + Monitor *m; - if (!mons->next) - return; - if ((m = dirtomon(arg->i)) == selmon) - return; - unfocus(selmon->sel, 0); - selmon = m; - focus(NULL); + if (!mons->next) + return; + if ((m = dirtomon(arg->i)) == selmon) + return; + unfocus(selmon->sel, 0); + selmon = m; + focus(NULL); } -void -focusstack(const Arg *arg) +void focusstack(const Arg *arg) { - Client *c = NULL, *i; + Client *c = NULL, *i; - if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) - return; - if (arg->i > 0) { - for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next); - if (!c) - for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next); - } else { - for (i = selmon->clients; i != selmon->sel; i = i->next) - if (ISVISIBLE(i)) - c = i; - if (!c) - for (; i; i = i->next) - if (ISVISIBLE(i)) - c = i; - } - if (c) { - focus(c); - restack(selmon); - } + if (!selmon->sel || (selmon->sel->isfullscreen && lockfullscreen)) + return; + if (arg->i > 0) + { + for (c = selmon->sel->next; c && !ISVISIBLE(c); c = c->next) + ; + if (!c) + for (c = selmon->clients; c && !ISVISIBLE(c); c = c->next) + ; + } + else + { + for (i = selmon->clients; i != selmon->sel; i = i->next) + if (ISVISIBLE(i)) + c = i; + if (!c) + for (; i; i = i->next) + if (ISVISIBLE(i)) + c = i; + } + if (c) + { + focus(c); + restack(selmon); + } } -Atom -getatomprop(Client *c, Atom prop) +Atom getatomprop(Client *c, Atom prop) { - int di; - unsigned long nitems, dl; - unsigned char *p = NULL; - Atom da, atom = None; + int di; + unsigned long nitems, dl; + unsigned char *p = NULL; + Atom da, atom = None; - /* FIXME getatomprop should return the number of items and a pointer to - * the stored data instead of this workaround */ - Atom req = XA_ATOM; - if (prop == xatom[XembedInfo]) - req = xatom[XembedInfo]; + /* FIXME getatomprop should return the number of items and a pointer to + * the stored data instead of this workaround */ + Atom req = XA_ATOM; + if (prop == xatom[XembedInfo]) + req = xatom[XembedInfo]; - if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, - &da, &di, &nitems, &dl, &p) == Success && p) { - atom = *(Atom *)p; - if (da == xatom[XembedInfo] && nitems == 2) - atom = ((Atom *)p)[1]; - XFree(p); - } - return atom; + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, req, &da, &di, &nitems, &dl, &p) == Success && p) + { + atom = *(Atom *)p; + if (da == xatom[XembedInfo] && nitems == 2) + atom = ((Atom *)p)[1]; + XFree(p); + } + return atom; } -unsigned int -getsystraywidth() +unsigned int getsystraywidth() { - unsigned int w = 0; - Client *i; - if(showsystray) - for(i = systray->icons; i; w += i->w + systrayspacing, i = i->next) ; - return w ? w + systrayspacing : 1; + unsigned int w = 0; + Client *i; + if (showsystray) + for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next) + ; + return w ? w + systrayspacing : 1; } -int -getrootptr(int *x, int *y) +int getrootptr(int *x, int *y) { - int di; - unsigned int dui; - Window dummy; + int di; + unsigned int dui; + Window dummy; - return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); + return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); } -long -getstate(Window w) +long getstate(Window w) { - int format; - long result = -1; - unsigned char *p = NULL; - unsigned long n, extra; - Atom real; + int format; + long result = -1; + unsigned char *p = NULL; + unsigned long n, extra; + Atom real; - if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], - &real, &format, &n, &extra, &p) != Success) - return -1; - if (n != 0 && format == 32) - result = *(long *)p; - XFree(p); - return result; + if (XGetWindowProperty(dpy, w, wmatom[WMState], 0L, 2L, False, wmatom[WMState], &real, &format, &n, &extra, &p) != Success) + return -1; + if (n != 0 && format == 32) + result = *(long *)p; + XFree(p); + return result; } -int -gettextprop(Window w, Atom atom, char *text, unsigned int size) +int gettextprop(Window w, Atom atom, char *text, unsigned int size) { - char **list = NULL; - int n; - XTextProperty name; + char **list = NULL; + int n; + XTextProperty name; - if (!text || size == 0) - return 0; - text[0] = '\0'; - if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) - return 0; - if (name.encoding == XA_STRING) { - strncpy(text, (char *)name.value, size - 1); - } else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) { - strncpy(text, *list, size - 1); - XFreeStringList(list); - } - text[size - 1] = '\0'; - XFree(name.value); - return 1; + if (!text || size == 0) + return 0; + text[0] = '\0'; + if (!XGetTextProperty(dpy, w, &name, atom) || !name.nitems) + return 0; + if (name.encoding == XA_STRING) + { + strncpy(text, (char *)name.value, size - 1); + } + else if (XmbTextPropertyToTextList(dpy, &name, &list, &n) >= Success && n > 0 && *list) + { + strncpy(text, *list, size - 1); + XFreeStringList(list); + } + text[size - 1] = '\0'; + XFree(name.value); + return 1; } -void -grabbuttons(Client *c, int focused) +void grabbuttons(Client *c, int focused) { - updatenumlockmask(); - { - unsigned int i, j; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - if (!focused) - XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, - BUTTONMASK, GrabModeSync, GrabModeSync, None, None); - for (i = 0; i < LENGTH(buttons); i++) - if (buttons[i].click == ClkClientWin) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabButton(dpy, buttons[i].button, - buttons[i].mask | modifiers[j], - c->win, False, BUTTONMASK, - GrabModeAsync, GrabModeSync, None, None); - } + updatenumlockmask(); + { + unsigned int i, j; + unsigned int modifiers[] = {0, LockMask, numlockmask, numlockmask | LockMask}; + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + if (!focused) + XGrabButton(dpy, AnyButton, AnyModifier, c->win, False, BUTTONMASK, GrabModeSync, GrabModeSync, None, None); + for (i = 0; i < LENGTH(buttons); i++) + if (buttons[i].click == ClkClientWin) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabButton(dpy, buttons[i].button, buttons[i].mask | modifiers[j], c->win, False, BUTTONMASK, GrabModeAsync, GrabModeSync, None, None); + } } -void -grabkeys(void) +void grabkeys(void) { - updatenumlockmask(); - { - unsigned int i, j, k; - unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; - int start, end, skip; - KeySym *syms; + updatenumlockmask(); + { + unsigned int i, j, k; + unsigned int modifiers[] = {0, LockMask, numlockmask, numlockmask | LockMask}; + int start, end, skip; + KeySym *syms; - XUngrabKey(dpy, AnyKey, AnyModifier, root); - XDisplayKeycodes(dpy, &start, &end); - syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); - if (!syms) - return; - for (k = start; k <= end; k++) - for (i = 0; i < LENGTH(keys); i++) - /* skip modifier codes, we do that ourselves */ - if (keys[i].keysym == syms[(k - start) * skip]) - for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, k, - keys[i].mod | modifiers[j], - root, True, - GrabModeAsync, GrabModeAsync); - XFree(syms); - } + XUngrabKey(dpy, AnyKey, AnyModifier, root); + XDisplayKeycodes(dpy, &start, &end); + syms = XGetKeyboardMapping(dpy, start, end - start + 1, &skip); + if (!syms) + return; + for (k = start; k <= end; k++) + for (i = 0; i < LENGTH(keys); i++) + /* skip modifier codes, we do that ourselves */ + if (keys[i].keysym == syms[(k - start) * skip]) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, k, keys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); + XFree(syms); + } } -void -incnmaster(const Arg *arg) +void incnmaster(const Arg *arg) { - selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); - arrange(selmon); + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); } #ifdef XINERAMA -static int -isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) +static int isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info) { - while (n--) - if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org - && unique[n].width == info->width && unique[n].height == info->height) - return 0; - return 1; + while (n--) + if (unique[n].x_org == info->x_org && unique[n].y_org == info->y_org && unique[n].width == info->width && unique[n].height == info->height) + return 0; + return 1; } #endif /* XINERAMA */ -void -keypress(XEvent *e) +void keypress(XEvent *e) { - unsigned int i; - KeySym keysym; - XKeyEvent *ev; + unsigned int i; + KeySym keysym; + XKeyEvent *ev; - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for (i = 0; i < LENGTH(keys); i++) - if (keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); + ev = &e->xkey; + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); + for (i = 0; i < LENGTH(keys); i++) + if (keysym == keys[i].keysym && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) && keys[i].func) + keys[i].func(&(keys[i].arg)); } -void -killclient(const Arg *arg) +void killclient(const Arg *arg) { - if (!selmon->sel) - return; + if (!selmon->sel) + return; - if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0 , 0, 0)) { - XGrabServer(dpy); - XSetErrorHandler(xerrordummy); - XSetCloseDownMode(dpy, DestroyAll); - XKillClient(dpy, selmon->sel->win); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } + if (!sendevent(selmon->sel->win, wmatom[WMDelete], NoEventMask, wmatom[WMDelete], CurrentTime, 0, 0, 0)) + { + XGrabServer(dpy); + XSetErrorHandler(xerrordummy); + XSetCloseDownMode(dpy, DestroyAll); + XKillClient(dpy, selmon->sel->win); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } } -void -manage(Window w, XWindowAttributes *wa) +void manage(Window w, XWindowAttributes *wa) { - Client *c, *t = NULL; - Window trans = None; - XWindowChanges wc; + Client *c, *t = NULL; + Window trans = None; + XWindowChanges wc; - c = ecalloc(1, sizeof(Client)); - c->win = w; - /* geometry */ - c->x = c->oldx = wa->x; - c->y = c->oldy = wa->y; - c->w = c->oldw = wa->width; - c->h = c->oldh = wa->height; - c->oldbw = wa->border_width; - c->cfact = 1.0; + c = ecalloc(1, sizeof(Client)); + c->win = w; + /* geometry */ + c->x = c->oldx = wa->x; + c->y = c->oldy = wa->y; + c->w = c->oldw = wa->width; + c->h = c->oldh = wa->height; + c->oldbw = wa->border_width; + c->cfact = 1.0; - updatetitle(c); - if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) { - c->mon = t->mon; - c->tags = t->tags; - } else { - c->mon = selmon; - applyrules(c); - } + updatetitle(c); + if (XGetTransientForHint(dpy, w, &trans) && (t = wintoclient(trans))) + { + c->mon = t->mon; + c->tags = t->tags; + } + else + { + c->mon = selmon; + applyrules(c); + } - if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) - c->x = c->mon->wx + c->mon->ww - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) - c->y = c->mon->wy + c->mon->wh - HEIGHT(c); - c->x = MAX(c->x, c->mon->wx); - c->y = MAX(c->y, c->mon->wy); - c->bw = borderpx; + if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) + c->x = c->mon->wx + c->mon->ww - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) + c->y = c->mon->wy + c->mon->wh - HEIGHT(c); + c->x = MAX(c->x, c->mon->wx); + c->y = MAX(c->y, c->mon->wy); + c->bw = borderpx; - wc.border_width = c->bw; - XConfigureWindow(dpy, w, CWBorderWidth, &wc); - XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); - configure(c); /* propagates border_width, if size doesn't change */ - updatewindowtype(c); - updatesizehints(c); - updatewmhints(c); - XSelectInput(dpy, w, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask); - grabbuttons(c, 0); - if (!c->isfloating) - c->isfloating = c->oldstate = trans != None || c->isfixed; - if (c->isfloating) - XRaiseWindow(dpy, c->win); - attachBelow(c); - attachstack(c); - XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); - XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ - setclientstate(c, NormalState); - if (c->mon == selmon) - unfocus(selmon->sel, 0); - c->mon->sel = c; - arrange(c->mon); - XMapWindow(dpy, c->win); - focus(NULL); + wc.border_width = c->bw; + XConfigureWindow(dpy, w, CWBorderWidth, &wc); + XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); + configure(c); /* propagates border_width, if size doesn't change */ + updatewindowtype(c); + updatesizehints(c); + updatewmhints(c); + { + int format; + unsigned long *data, n, extra; + Monitor *m; + Atom atom; + if (XGetWindowProperty(dpy, c->win, netatom[NetClientInfo], 0L, 2L, False, XA_CARDINAL, &atom, &format, &n, &extra, (unsigned char **)&data) == Success && n == 2) + { + c->tags = *data; + for (m = mons; m; m = m->next) + { + if (m->num == *(data + 1)) + { + c->mon = m; + break; + } + } + } + if (n > 0) + XFree(data); + } + setclienttagprop(c); + + XSelectInput(dpy, w, EnterWindowMask | FocusChangeMask | PropertyChangeMask | StructureNotifyMask); + grabbuttons(c, 0); + if (!c->isfloating) + c->isfloating = c->oldstate = trans != None || c->isfixed; + if (c->isfloating) + XRaiseWindow(dpy, c->win); + attachBelow(c); + attachstack(c); + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *)&(c->win), 1); + XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */ + setclientstate(c, NormalState); + if (c->mon == selmon) + unfocus(selmon->sel, 0); + c->mon->sel = c; + arrange(c->mon); + XMapWindow(dpy, c->win); + focus(NULL); } -void -mappingnotify(XEvent *e) +void mappingnotify(XEvent *e) { - XMappingEvent *ev = &e->xmapping; + XMappingEvent *ev = &e->xmapping; - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) - grabkeys(); + XRefreshKeyboardMapping(ev); + if (ev->request == MappingKeyboard) + grabkeys(); } -void -maprequest(XEvent *e) +void maprequest(XEvent *e) { - static XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; - Client *i; - if ((i = wintosystrayicon(ev->window))) { - sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); - resizebarwin(selmon); - updatesystray(); - } + Client *i; + if ((i = wintosystrayicon(ev->window))) + { + sendevent(i->win, netatom[Xembed], StructureNotifyMask, CurrentTime, XEMBED_WINDOW_ACTIVATE, 0, systray->win, XEMBED_EMBEDDED_VERSION); + resizebarwin(selmon); + updatesystray(); + } - if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) - return; - if (!wintoclient(ev->window)) - manage(ev->window, &wa); + if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) + return; + if (!wintoclient(ev->window)) + manage(ev->window, &wa); } -void -monocle(Monitor *m) +void monocle(Monitor *m) { - unsigned int n = 0; - Client *c; + unsigned int n = 0; + Client *c; - for (c = m->clients; c; c = c->next) - if (ISVISIBLE(c)) - n++; - if (n > 0) /* override layout symbol */ - snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); - for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) - resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); + for (c = m->clients; c; c = c->next) + if (ISVISIBLE(c)) + n++; + if (n > 0) /* override layout symbol */ + snprintf(m->ltsymbol, sizeof m->ltsymbol, "[%d]", n); + for (c = nexttiled(m->clients); c; c = nexttiled(c->next)) + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); } -void -motionnotify(XEvent *e) +void motionnotify(XEvent *e) { - static Monitor *mon = NULL; - Monitor *m; - XMotionEvent *ev = &e->xmotion; + static Monitor *mon = NULL; + Monitor *m; + XMotionEvent *ev = &e->xmotion; - if (ev->window != root) - return; - if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) { - unfocus(selmon->sel, 1); - selmon = m; - focus(NULL); - } - mon = m; + if (ev->window != root) + return; + if ((m = recttomon(ev->x_root, ev->y_root, 1, 1)) != mon && mon) + { + unfocus(selmon->sel, 1); + selmon = m; + focus(NULL); + } + mon = m; } -void -movemouse(const Arg *arg) +void movemouse(const Arg *arg) { - int x, y, ocx, ocy, nx, ny; - Client *c; - Monitor *m; - XEvent ev; - Time lasttime = 0; + int x, y, ocx, ocy, nx, ny; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; - if (!(c = selmon->sel)) - return; - if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ - return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) - return; - if (!getrootptr(&x, &y)) - return; - do { - XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); - switch(ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); - break; - case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate)) - continue; - lasttime = ev.xmotion.time; + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support moving fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurMove]->cursor, CurrentTime) != GrabSuccess) + return; + if (!getrootptr(&x, &y)) + return; + do + { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) + { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate)) + continue; + lasttime = ev.xmotion.time; - nx = ocx + (ev.xmotion.x - x); - ny = ocy + (ev.xmotion.y - y); - if (abs(selmon->wx - nx) < snap) - nx = selmon->wx; - else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) - nx = selmon->wx + selmon->ww - WIDTH(c); - if (abs(selmon->wy - ny) < snap) - ny = selmon->wy; - else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) - ny = selmon->wy + selmon->wh - HEIGHT(c); - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange - && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) - togglefloating(NULL); - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, nx, ny, c->w, c->h, 1); - break; - } - } while (ev.type != ButtonRelease); - XUngrabPointer(dpy, CurrentTime); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } + nx = ocx + (ev.xmotion.x - x); + ny = ocy + (ev.xmotion.y - y); + if (abs(selmon->wx - nx) < snap) + nx = selmon->wx; + else if (abs((selmon->wx + selmon->ww) - (nx + WIDTH(c))) < snap) + nx = selmon->wx + selmon->ww - WIDTH(c); + if (abs(selmon->wy - ny) < snap) + ny = selmon->wy; + else if (abs((selmon->wy + selmon->wh) - (ny + HEIGHT(c))) < snap) + ny = selmon->wy + selmon->wh - HEIGHT(c); + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && (abs(nx - c->x) > snap || abs(ny - c->y) > snap)) + togglefloating(NULL); + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, nx, ny, c->w, c->h, 1); + break; + } + } while (ev.type != ButtonRelease); + XUngrabPointer(dpy, CurrentTime); + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) + { + sendmon(c, m); + selmon = m; + focus(NULL); + } } - Client * -nexttagged(Client *c) { - Client *walked = c->mon->clients; - for(; - walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); - walked = walked->next - ); - return walked; -} - -Client * -nexttiled(Client *c) +Client *nexttagged(Client *c) { - for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); - return c; + Client *walked = c->mon->clients; + for (; walked && (walked->isfloating || !ISVISIBLEONTAG(walked, c->tags)); walked = walked->next) + ; + return walked; } -void -pop(Client *c) +Client *nexttiled(Client *c) { - detach(c); - attach(c); - focus(c); - arrange(c->mon); + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next) + ; + return c; } -void -propertynotify(XEvent *e) +void pop(Client *c) { - Client *c; - Window trans; - XPropertyEvent *ev = &e->xproperty; - - if ((c = wintosystrayicon(ev->window))) { - if (ev->atom == XA_WM_NORMAL_HINTS) { - updatesizehints(c); - updatesystrayicongeom(c, c->w, c->h); - } - else - updatesystrayiconstate(c, ev); - resizebarwin(selmon); - updatesystray(); - } - - if ((ev->window == root) && (ev->atom == XA_WM_NAME)) - updatestatus(); - else if (ev->state == PropertyDelete) - return; /* ignore */ - else if ((c = wintoclient(ev->window))) { - switch(ev->atom) { - default: break; - case XA_WM_TRANSIENT_FOR: - if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && - (c->isfloating = (wintoclient(trans)) != NULL)) - arrange(c->mon); - break; - case XA_WM_NORMAL_HINTS: - c->hintsvalid = 0; - break; - case XA_WM_HINTS: - updatewmhints(c); - drawbars(); - break; - } - if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) { - updatetitle(c); - if (c == c->mon->sel) - drawbar(c->mon); - } - if (ev->atom == netatom[NetWMWindowType]) - updatewindowtype(c); - } + detach(c); + attach(c); + focus(c); + arrange(c->mon); } -void -quit(const Arg *arg) +void propertynotify(XEvent *e) { - running = 0; + Client *c; + Window trans; + XPropertyEvent *ev = &e->xproperty; + + if ((c = wintosystrayicon(ev->window))) + { + if (ev->atom == XA_WM_NORMAL_HINTS) + { + updatesizehints(c); + updatesystrayicongeom(c, c->w, c->h); + } + else + updatesystrayiconstate(c, ev); + resizebarwin(selmon); + updatesystray(); + } + + if ((ev->window == root) && (ev->atom == XA_WM_NAME)) + updatestatus(); + else if (ev->state == PropertyDelete) + return; /* ignore */ + else if ((c = wintoclient(ev->window))) + { + switch (ev->atom) + { + default: + break; + case XA_WM_TRANSIENT_FOR: + if (!c->isfloating && (XGetTransientForHint(dpy, c->win, &trans)) && (c->isfloating = (wintoclient(trans)) != NULL)) + arrange(c->mon); + break; + case XA_WM_NORMAL_HINTS: + c->hintsvalid = 0; + break; + case XA_WM_HINTS: + updatewmhints(c); + drawbars(); + break; + } + if (ev->atom == XA_WM_NAME || ev->atom == netatom[NetWMName]) + { + updatetitle(c); + if (c == c->mon->sel) + drawbar(c->mon); + } + if (ev->atom == netatom[NetWMWindowType]) + updatewindowtype(c); + } } -Monitor * -recttomon(int x, int y, int w, int h) +void quit(const Arg *arg) { running = 0; } + +Monitor *recttomon(int x, int y, int w, int h) { - Monitor *m, *r = selmon; - int a, area = 0; + Monitor *m, *r = selmon; + int a, area = 0; - for (m = mons; m; m = m->next) - if ((a = INTERSECT(x, y, w, h, m)) > area) { - area = a; - r = m; - } - return r; + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) + { + area = a; + r = m; + } + return r; } -void -removesystrayicon(Client *i) +void removesystrayicon(Client *i) { - Client **ii; + Client **ii; - if (!showsystray || !i) - return; - for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next); - if (ii) - *ii = i->next; - free(i); + if (!showsystray || !i) + return; + for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next) + ; + if (ii) + *ii = i->next; + free(i); } -void -resize(Client *c, int x, int y, int w, int h, int interact) +void resize(Client *c, int x, int y, int w, int h, int interact) { - if (applysizehints(c, &x, &y, &w, &h, interact)) - resizeclient(c, x, y, w, h); + if (applysizehints(c, &x, &y, &w, &h, interact)) + resizeclient(c, x, y, w, h); } -void -resizebarwin(Monitor *m) { - unsigned int w = m->ww; - if (showsystray && m == systraytomon(m) && !systrayonleft) - w -= getsystraywidth(); - XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); -} - -void -resizeclient(Client *c, int x, int y, int w, int h) +void resizebarwin(Monitor *m) { - XWindowChanges wc; - - c->oldx = c->x; c->x = wc.x = x; - c->oldy = c->y; c->y = wc.y = y; - c->oldw = c->w; c->w = wc.width = w; - c->oldh = c->h; c->h = wc.height = h; - wc.border_width = c->bw; - XConfigureWindow(dpy, c->win, CWX|CWY|CWWidth|CWHeight|CWBorderWidth, &wc); - configure(c); - XSync(dpy, False); + unsigned int w = m->ww; + if (showsystray && m == systraytomon(m) && !systrayonleft) + w -= getsystraywidth(); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, w, bh); } -void -resizerequest(XEvent *e) +void resizeclient(Client *c, int x, int y, int w, int h) { - XResizeRequestEvent *ev = &e->xresizerequest; - Client *i; + XWindowChanges wc; - if ((i = wintosystrayicon(ev->window))) { - updatesystrayicongeom(i, ev->width, ev->height); - resizebarwin(selmon); - updatesystray(); - } + c->oldx = c->x; + c->x = wc.x = x; + c->oldy = c->y; + c->y = wc.y = y; + c->oldw = c->w; + c->w = wc.width = w; + c->oldh = c->h; + c->h = wc.height = h; + wc.border_width = c->bw; + XConfigureWindow(dpy, c->win, CWX | CWY | CWWidth | CWHeight | CWBorderWidth, &wc); + configure(c); + XSync(dpy, False); } -void -resizemouse(const Arg *arg) +void resizerequest(XEvent *e) { - int ocx, ocy, nw, nh; - Client *c; - Monitor *m; - XEvent ev; - Time lasttime = 0; + XResizeRequestEvent *ev = &e->xresizerequest; + Client *i; - if (!(c = selmon->sel)) - return; - if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ - return; - restack(selmon); - ocx = c->x; - ocy = c->y; - if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, - None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) - return; - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - do { - XMaskEvent(dpy, MOUSEMASK|ExposureMask|SubstructureRedirectMask, &ev); - switch(ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); - break; - case MotionNotify: - if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate)) - continue; - lasttime = ev.xmotion.time; - - nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); - nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); - if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww - && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) - { - if (!c->isfloating && selmon->lt[selmon->sellt]->arrange - && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) - togglefloating(NULL); - } - if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) - resize(c, c->x, c->y, nw, nh, 1); - break; - } - } while (ev.type != ButtonRelease); - XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); - XUngrabPointer(dpy, CurrentTime); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); - if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) { - sendmon(c, m); - selmon = m; - focus(NULL); - } + if ((i = wintosystrayicon(ev->window))) + { + updatesystrayicongeom(i, ev->width, ev->height); + resizebarwin(selmon); + updatesystray(); + } } -void -restack(Monitor *m) +void resizemouse(const Arg *arg) { - Client *c; - XEvent ev; - XWindowChanges wc; + int ocx, ocy, nw, nh; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; - drawbar(m); - if (!m->sel) - return; - if (m->sel->isfloating || !m->lt[m->sellt]->arrange) - XRaiseWindow(dpy, m->sel->win); - if (m->lt[m->sellt]->arrange) { - wc.stack_mode = Below; - wc.sibling = m->barwin; - for (c = m->stack; c; c = c->snext) - if (!c->isfloating && ISVISIBLE(c)) { - XConfigureWindow(dpy, c->win, CWSibling|CWStackMode, &wc); - wc.sibling = c->win; - } - } - XSync(dpy, False); - while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)); + if (!(c = selmon->sel)) + return; + if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */ + return; + restack(selmon); + ocx = c->x; + ocy = c->y; + if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync, None, cursor[CurResize]->cursor, CurrentTime) != GrabSuccess) + return; + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + do + { + XMaskEvent(dpy, MOUSEMASK | ExposureMask | SubstructureRedirectMask, &ev); + switch (ev.type) + { + case ConfigureRequest: + case Expose: + case MapRequest: + handler[ev.type](&ev); + break; + case MotionNotify: + if ((ev.xmotion.time - lasttime) <= (1000 / refreshrate)) + continue; + lasttime = ev.xmotion.time; + + nw = MAX(ev.xmotion.x - ocx - 2 * c->bw + 1, 1); + nh = MAX(ev.xmotion.y - ocy - 2 * c->bw + 1, 1); + if (c->mon->wx + nw >= selmon->wx && c->mon->wx + nw <= selmon->wx + selmon->ww && c->mon->wy + nh >= selmon->wy && c->mon->wy + nh <= selmon->wy + selmon->wh) + { + if (!c->isfloating && selmon->lt[selmon->sellt]->arrange && (abs(nw - c->w) > snap || abs(nh - c->h) > snap)) + togglefloating(NULL); + } + if (!selmon->lt[selmon->sellt]->arrange || c->isfloating) + resize(c, c->x, c->y, nw, nh, 1); + break; + } + } while (ev.type != ButtonRelease); + XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w + c->bw - 1, c->h + c->bw - 1); + XUngrabPointer(dpy, CurrentTime); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; + if ((m = recttomon(c->x, c->y, c->w, c->h)) != selmon) + { + sendmon(c, m); + selmon = m; + focus(NULL); + } } -void -run(void) +void restack(Monitor *m) { - XEvent ev; - /* main event loop */ - XSync(dpy, False); - while (running && !XNextEvent(dpy, &ev)) - if (handler[ev.type]) - handler[ev.type](&ev); /* call handler */ + Client *c; + XEvent ev; + XWindowChanges wc; + + drawbar(m); + if (!m->sel) + return; + if (m->sel->isfloating || !m->lt[m->sellt]->arrange) + XRaiseWindow(dpy, m->sel->win); + if (m->lt[m->sellt]->arrange) + { + wc.stack_mode = Below; + wc.sibling = m->barwin; + for (c = m->stack; c; c = c->snext) + if (!c->isfloating && ISVISIBLE(c)) + { + XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc); + wc.sibling = c->win; + } + } + XSync(dpy, False); + while (XCheckMaskEvent(dpy, EnterWindowMask, &ev)) + ; } -void -runautostart(void) +void run(void) { - char *pathpfx; - char *path; - char *xdgdatahome; - char *home; - struct stat sb; - - if ((home = getenv("HOME")) == NULL) - /* this is almost impossible */ - return; - - /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, - * otherwise use ~/.local/share/dwm as autostart script directory - */ - xdgdatahome = getenv("XDG_DATA_HOME"); - if (xdgdatahome != NULL && *xdgdatahome != '\0') { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); - - if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) { - free(pathpfx); - return; - } - } else { - /* space for path segments, separators and nul */ - pathpfx = ecalloc(1, strlen(home) + strlen(localshare) - + strlen(dwmdir) + 3); - - if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) { - free(pathpfx); - return; - } - } - - /* check if the autostart script directory exists */ - if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) { - /* the XDG conformant path does not exist or is no directory - * so we try ~/.dwm instead - */ - char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); - if(pathpfx_new == NULL) { - free(pathpfx); - return; - } - pathpfx = pathpfx_new; - - if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) { - free(pathpfx); - return; - } - } - - /* try the blocking script first */ - path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); - if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(path); - - /* now the non-blocking script */ - if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) { - free(path); - free(pathpfx); - } - - if (access(path, X_OK) == 0) - system(strcat(path, " &")); - - free(pathpfx); - free(path); + XEvent ev; + /* main event loop */ + XSync(dpy, False); + while (running && !XNextEvent(dpy, &ev)) + if (handler[ev.type]) + handler[ev.type](&ev); /* call handler */ } -void -scan(void) +void runautostart(void) { - unsigned int i, num; - Window d1, d2, *wins = NULL; - XWindowAttributes wa; + char *pathpfx; + char *path; + char *xdgdatahome; + char *home; + struct stat sb; - if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) { - for (i = 0; i < num; i++) { - if (!XGetWindowAttributes(dpy, wins[i], &wa) - || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) - continue; - if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) - manage(wins[i], &wa); - } - for (i = 0; i < num; i++) { /* now the transients */ - if (!XGetWindowAttributes(dpy, wins[i], &wa)) - continue; - if (XGetTransientForHint(dpy, wins[i], &d1) - && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) - manage(wins[i], &wa); - } - if (wins) - XFree(wins); - } + if ((home = getenv("HOME")) == NULL) + /* this is almost impossible */ + return; + + /* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm, + * otherwise use ~/.local/share/dwm as autostart script directory + */ + xdgdatahome = getenv("XDG_DATA_HOME"); + if (xdgdatahome != NULL && *xdgdatahome != '\0') + { + /* space for path segments, separators and nul */ + pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2); + + if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) + { + free(pathpfx); + return; + } + } + else + { + /* space for path segments, separators and nul */ + pathpfx = ecalloc(1, strlen(home) + strlen(localshare) + strlen(dwmdir) + 3); + + if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) + { + free(pathpfx); + return; + } + } + + /* check if the autostart script directory exists */ + if (!(stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) + { + /* the XDG conformant path does not exist or is no directory + * so we try ~/.dwm instead + */ + char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3); + if (pathpfx_new == NULL) + { + free(pathpfx); + return; + } + pathpfx = pathpfx_new; + + if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) + { + free(pathpfx); + return; + } + } + + /* try the blocking script first */ + path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2); + if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) + { + free(path); + free(pathpfx); + } + + if (access(path, X_OK) == 0) + system(path); + + /* now the non-blocking script */ + if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) + { + free(path); + free(pathpfx); + } + + if (access(path, X_OK) == 0) + system(strcat(path, " &")); + + free(pathpfx); + free(path); } -void -sendmon(Client *c, Monitor *m) +void scan(void) { - if (c->mon == m) - return; - unfocus(c, 1); - detach(c); - detachstack(c); - c->mon = m; - c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ - attachBelow(c); - attachstack(c); - focus(NULL); - arrange(NULL); + unsigned int i, num; + Window d1, d2, *wins = NULL; + XWindowAttributes wa; + + if (XQueryTree(dpy, root, &d1, &d2, &wins, &num)) + { + for (i = 0; i < num; i++) + { + if (!XGetWindowAttributes(dpy, wins[i], &wa) || wa.override_redirect || XGetTransientForHint(dpy, wins[i], &d1)) + continue; + if (wa.map_state == IsViewable || getstate(wins[i]) == IconicState) + manage(wins[i], &wa); + } + for (i = 0; i < num; i++) + { /* now the transients */ + if (!XGetWindowAttributes(dpy, wins[i], &wa)) + continue; + if (XGetTransientForHint(dpy, wins[i], &d1) && (wa.map_state == IsViewable || getstate(wins[i]) == IconicState)) + manage(wins[i], &wa); + } + if (wins) + XFree(wins); + } } -void -setclientstate(Client *c, long state) +void sendmon(Client *c, Monitor *m) { - long data[] = { state, None }; - - XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, - PropModeReplace, (unsigned char *)data, 2); + if (c->mon == m) + return; + unfocus(c, 1); + detach(c); + detachstack(c); + c->mon = m; + c->tags = m->tagset[m->seltags]; /* assign tags of target monitor */ + attachBelow(c); + attachstack(c); + setclienttagprop(c); + focus(NULL); + arrange(NULL); } -int -sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) +void setclientstate(Client *c, long state) { - int n; - Atom *protocols, mt; - int exists = 0; - XEvent ev; + long data[] = {state, None}; - if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) { - mt = wmatom[WMProtocols]; - if (XGetWMProtocols(dpy, w, &protocols, &n)) { - while (!exists && n--) - exists = protocols[n] == proto; - XFree(protocols); - } - } - else { - exists = True; - mt = proto; - } - - if (exists) { - ev.type = ClientMessage; - ev.xclient.window = w; - ev.xclient.message_type = mt; - ev.xclient.format = 32; - ev.xclient.data.l[0] = d0; - ev.xclient.data.l[1] = d1; - ev.xclient.data.l[2] = d2; - ev.xclient.data.l[3] = d3; - ev.xclient.data.l[4] = d4; - XSendEvent(dpy, w, False, mask, &ev); - } - return exists; + XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, PropModeReplace, (unsigned char *)data, 2); } -void -setfocus(Client *c) +int sendevent(Window w, Atom proto, int mask, long d0, long d1, long d2, long d3, long d4) { - if (!c->neverfocus) - XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); - XChangeProperty(dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32, - PropModeReplace, (unsigned char *)&c->win, 1); - sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); + int n; + Atom *protocols, mt; + int exists = 0; + XEvent ev; + + if (proto == wmatom[WMTakeFocus] || proto == wmatom[WMDelete]) + { + mt = wmatom[WMProtocols]; + if (XGetWMProtocols(dpy, w, &protocols, &n)) + { + while (!exists && n--) + exists = protocols[n] == proto; + XFree(protocols); + } + } + else + { + exists = True; + mt = proto; + } + + if (exists) + { + ev.type = ClientMessage; + ev.xclient.window = w; + ev.xclient.message_type = mt; + ev.xclient.format = 32; + ev.xclient.data.l[0] = d0; + ev.xclient.data.l[1] = d1; + ev.xclient.data.l[2] = d2; + ev.xclient.data.l[3] = d3; + ev.xclient.data.l[4] = d4; + XSendEvent(dpy, w, False, mask, &ev); + } + return exists; } -void -setfullscreen(Client *c, int fullscreen) +void setfocus(Client *c) { - if (fullscreen && !c->isfullscreen) { - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)&netatom[NetWMFullscreen], 1); - c->isfullscreen = 1; - c->oldstate = c->isfloating; - c->oldbw = c->bw; - c->bw = 0; - c->isfloating = 1; - resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); - XRaiseWindow(dpy, c->win); - } else if (!fullscreen && c->isfullscreen){ - XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, - PropModeReplace, (unsigned char*)0, 0); - c->isfullscreen = 0; - c->isfloating = c->oldstate; - c->bw = c->oldbw; - c->x = c->oldx; - c->y = c->oldy; - c->w = c->oldw; - c->h = c->oldh; - resizeclient(c, c->x, c->y, c->w, c->h); - arrange(c->mon); - } + if (!c->neverfocus) + XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime); + XChangeProperty(dpy, root, netatom[NetActiveWindow], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&c->win, 1); + sendevent(c->win, wmatom[WMTakeFocus], NoEventMask, wmatom[WMTakeFocus], CurrentTime, 0, 0, 0); } -void -setlayout(const Arg *arg) +void setfullscreen(Client *c, int fullscreen) { - if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) - selmon->sellt ^= 1; - if (arg && arg->v) - selmon->lt[selmon->sellt] = (Layout *)arg->v; - strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); - if (selmon->sel) - arrange(selmon); - else - drawbar(selmon); + if (fullscreen && !c->isfullscreen) + { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char *)&netatom[NetWMFullscreen], 1); + c->isfullscreen = 1; + c->oldstate = c->isfloating; + c->oldbw = c->bw; + c->bw = 0; + c->isfloating = 1; + resizeclient(c, c->mon->mx, c->mon->my, c->mon->mw, c->mon->mh); + XRaiseWindow(dpy, c->win); + } + else if (!fullscreen && c->isfullscreen) + { + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, PropModeReplace, (unsigned char *)0, 0); + c->isfullscreen = 0; + c->isfloating = c->oldstate; + c->bw = c->oldbw; + c->x = c->oldx; + c->y = c->oldy; + c->w = c->oldw; + c->h = c->oldh; + resizeclient(c, c->x, c->y, c->w, c->h); + arrange(c->mon); + } } -void -setcfact(const Arg *arg) { - float f; - Client *c; +void setlayout(const Arg *arg) +{ + if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) + selmon->sellt ^= 1; + if (arg && arg->v) + selmon->lt[selmon->sellt] = (Layout *)arg->v; + strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); + if (selmon->sel) + arrange(selmon); + else + drawbar(selmon); +} - c = selmon->sel; +void setcfact(const Arg *arg) +{ + float f; + Client *c; - if(!arg || !c || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f + c->cfact; - if(arg->f == 0.0) - f = 1.0; - else if(f < 0.25 || f > 4.0) - return; - c->cfact = f; - arrange(selmon); + c = selmon->sel; + + if (!arg || !c || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f + c->cfact; + if (arg->f == 0.0) + f = 1.0; + else if (f < 0.25 || f > 4.0) + return; + c->cfact = f; + arrange(selmon); } /* arg > 1.0 will set mfact absolutely */ -void -setmfact(const Arg *arg) +void setmfact(const Arg *arg) { - float f; + float f; - if (!arg || !selmon->lt[selmon->sellt]->arrange) - return; - f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; - if (f < 0.05 || f > 0.95) - return; - selmon->mfact = f; - arrange(selmon); + if (!arg || !selmon->lt[selmon->sellt]->arrange) + return; + f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; + if (f < 0.05 || f > 0.95) + return; + selmon->mfact = f; + arrange(selmon); } -void -setup(void) +void setup(void) { - int i; - XSetWindowAttributes wa; - Atom utf8string; - struct sigaction sa; + int i; + XSetWindowAttributes wa; + Atom utf8string; + struct sigaction sa; - /* do not transform children into zombies when they terminate */ - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); + /* do not transform children into zombies when they terminate */ + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT | SA_RESTART; + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); - /* clean up any zombies (inherited from .xinitrc etc) immediately */ - while (waitpid(-1, NULL, WNOHANG) > 0); + /* clean up any zombies (inherited from .xinitrc etc) immediately */ + while (waitpid(-1, NULL, WNOHANG) > 0) + ; - /* init screen */ - screen = DefaultScreen(dpy); - sw = DisplayWidth(dpy, screen); - sh = DisplayHeight(dpy, screen); - root = RootWindow(dpy, screen); - drw = drw_create(dpy, screen, root, sw, sh); - if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) - die("no fonts could be loaded."); - lrpad = drw->fonts->h; - bh = drw->fonts->h + 2; - updategeom(); - /* init atoms */ - utf8string = XInternAtom(dpy, "UTF8_STRING", False); - wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); - wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); - wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); - wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); - netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); - netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); - netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); - netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); - netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); - netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); - netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); - netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); - netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); - netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); - netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); - netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); - netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); - xatom[Manager] = XInternAtom(dpy, "MANAGER", False); - xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); - xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); - /* init cursors */ - cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); - cursor[CurResize] = drw_cur_create(drw, XC_sizing); - cursor[CurMove] = drw_cur_create(drw, XC_fleur); - /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); - for (i = 0; i < LENGTH(colors); i++) - scheme[i] = drw_scm_create(drw, colors[i], 3); - /* init system tray */ - updatesystray(); - /* init bars */ - updatebars(); - updatestatus(); - /* supporting window for NetWMCheck */ - wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, - PropModeReplace, (unsigned char *) "dwm", 3); - XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, - PropModeReplace, (unsigned char *) &wmcheckwin, 1); - /* EWMH support per view */ - XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, - PropModeReplace, (unsigned char *) netatom, NetLast); - XDeleteProperty(dpy, root, netatom[NetClientList]); - /* select events */ - wa.cursor = cursor[CurNormal]->cursor; - wa.event_mask = SubstructureRedirectMask|SubstructureNotifyMask - |ButtonPressMask|PointerMotionMask|EnterWindowMask - |LeaveWindowMask|StructureNotifyMask|PropertyChangeMask; - XChangeWindowAttributes(dpy, root, CWEventMask|CWCursor, &wa); - XSelectInput(dpy, root, wa.event_mask); - grabkeys(); - focus(NULL); + /* init screen */ + screen = DefaultScreen(dpy); + sw = DisplayWidth(dpy, screen); + sh = DisplayHeight(dpy, screen); + root = RootWindow(dpy, screen); + drw = drw_create(dpy, screen, root, sw, sh); + if (!drw_fontset_create(drw, fonts, LENGTH(fonts))) + die("no fonts could be loaded."); + lrpad = drw->fonts->h; + bh = drw->fonts->h + 2; + updategeom(); + /* init atoms */ + utf8string = XInternAtom(dpy, "UTF8_STRING", False); + wmatom[WMProtocols] = XInternAtom(dpy, "WM_PROTOCOLS", False); + wmatom[WMDelete] = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmatom[WMState] = XInternAtom(dpy, "WM_STATE", False); + wmatom[WMTakeFocus] = XInternAtom(dpy, "WM_TAKE_FOCUS", False); + netatom[NetActiveWindow] = XInternAtom(dpy, "_NET_ACTIVE_WINDOW", False); + netatom[NetSupported] = XInternAtom(dpy, "_NET_SUPPORTED", False); + netatom[NetSystemTray] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S0", False); + netatom[NetSystemTrayOP] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", False); + netatom[NetSystemTrayOrientation] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION", False); + netatom[NetSystemTrayOrientationHorz] = XInternAtom(dpy, "_NET_SYSTEM_TRAY_ORIENTATION_HORZ", False); + netatom[NetWMName] = XInternAtom(dpy, "_NET_WM_NAME", False); + netatom[NetWMState] = XInternAtom(dpy, "_NET_WM_STATE", False); + netatom[NetWMCheck] = XInternAtom(dpy, "_NET_SUPPORTING_WM_CHECK", False); + netatom[NetWMFullscreen] = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); + netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False); + netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False); + netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False); + netatom[NetClientInfo] = XInternAtom(dpy, "_NET_CLIENT_INFO", False); + xatom[Manager] = XInternAtom(dpy, "MANAGER", False); + xatom[Xembed] = XInternAtom(dpy, "_XEMBED", False); + xatom[XembedInfo] = XInternAtom(dpy, "_XEMBED_INFO", False); + /* init cursors */ + cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr); + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ + scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init system tray */ + updatesystray(); + /* init bars */ + updatebars(); + updatestatus(); + /* supporting window for NetWMCheck */ + wmcheckwin = XCreateSimpleWindow(dpy, root, 0, 0, 1, 1, 0, 0, 0); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&wmcheckwin, 1); + XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8, PropModeReplace, (unsigned char *)"dwm", 3); + XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32, PropModeReplace, (unsigned char *)&wmcheckwin, 1); + /* EWMH support per view */ + XChangeProperty(dpy, root, netatom[NetSupported], XA_ATOM, 32, PropModeReplace, (unsigned char *)netatom, NetLast); + XDeleteProperty(dpy, root, netatom[NetClientList]); + XDeleteProperty(dpy, root, netatom[NetClientInfo]); + /* select events */ + wa.cursor = cursor[CurNormal]->cursor; + wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask | ButtonPressMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | StructureNotifyMask | PropertyChangeMask; + XChangeWindowAttributes(dpy, root, CWEventMask | CWCursor, &wa); + XSelectInput(dpy, root, wa.event_mask); + grabkeys(); + focus(NULL); } -void -seturgent(Client *c, int urg) +void seturgent(Client *c, int urg) { - XWMHints *wmh; + XWMHints *wmh; - c->isurgent = urg; - if (!(wmh = XGetWMHints(dpy, c->win))) - return; - wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); - XSetWMHints(dpy, c->win, wmh); - XFree(wmh); + c->isurgent = urg; + if (!(wmh = XGetWMHints(dpy, c->win))) + return; + wmh->flags = urg ? (wmh->flags | XUrgencyHint) : (wmh->flags & ~XUrgencyHint); + XSetWMHints(dpy, c->win, wmh); + XFree(wmh); } -void -showhide(Client *c) +void showhide(Client *c) { - if (!c) - return; - if (ISVISIBLE(c)) { - /* show clients top down */ - XMoveWindow(dpy, c->win, c->x, c->y); - if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) - resize(c, c->x, c->y, c->w, c->h, 0); - showhide(c->snext); - } else { - /* hide clients bottom up */ - showhide(c->snext); - XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); - } + if (!c) + return; + if (ISVISIBLE(c)) + { + /* show clients top down */ + XMoveWindow(dpy, c->win, c->x, c->y); + if ((!c->mon->lt[c->mon->sellt]->arrange || c->isfloating) && !c->isfullscreen) + resize(c, c->x, c->y, c->w, c->h, 0); + showhide(c->snext); + } + else + { + /* hide clients bottom up */ + showhide(c->snext); + XMoveWindow(dpy, c->win, WIDTH(c) * -2, c->y); + } } -void -spawn(const Arg *arg) +void spawn(const Arg *arg) { - struct sigaction sa; + struct sigaction sa; - if (arg->v == dmenucmd) - dmenumon[0] = '0' + selmon->num; - if (fork() == 0) { - if (dpy) - close(ConnectionNumber(dpy)); - setsid(); + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; + if (fork() == 0) + { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); - sigemptyset(&sa.sa_mask); - sa.sa_flags = 0; - sa.sa_handler = SIG_DFL; - sigaction(SIGCHLD, &sa, NULL); + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &sa, NULL); - execvp(((char **)arg->v)[0], (char **)arg->v); - die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); - } + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); + } } -void -tag(const Arg *arg) +void setclienttagprop(Client *c) { - if (selmon->sel && arg->ui & TAGMASK) { - selmon->sel->tags = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); - } + long data[] = {(long)c->tags, (long)c->mon->num}; + XChangeProperty(dpy, c->win, netatom[NetClientInfo], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2); } -void -tagmon(const Arg *arg) +void tag(const Arg *arg) { - if (!selmon->sel || !mons->next) - return; - sendmon(selmon->sel, dirtomon(arg->i)); + Client *c; + if (selmon->sel && arg->ui & TAGMASK) + { + c = selmon->sel; + selmon->sel->tags = arg->ui & TAGMASK; + setclienttagprop(c); + focus(NULL); + arrange(selmon); + } } -void -togglebar(const Arg *arg) +void tagmon(const Arg *arg) { - selmon->showbar = !selmon->showbar; - updatebarpos(selmon); - resizebarwin(selmon); - if (showsystray) { - XWindowChanges wc; - if (!selmon->showbar) - wc.y = -bh; - else if (selmon->showbar) { - wc.y = 0; - if (!selmon->topbar) - wc.y = selmon->mh - bh; - } - XConfigureWindow(dpy, systray->win, CWY, &wc); - } - arrange(selmon); + if (!selmon->sel || !mons->next) + return; + sendmon(selmon->sel, dirtomon(arg->i)); } -void -togglefloating(const Arg *arg) +void togglebar(const Arg *arg) { - if (!selmon->sel) - return; - if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ - return; - selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; - if (selmon->sel->isfloating) - resize(selmon->sel, selmon->sel->x, selmon->sel->y, - selmon->sel->w, selmon->sel->h, 0); - arrange(selmon); + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); + resizebarwin(selmon); + if (showsystray) + { + XWindowChanges wc; + if (!selmon->showbar) + wc.y = -bh; + else if (selmon->showbar) + { + wc.y = 0; + if (!selmon->topbar) + wc.y = selmon->mh - bh; + } + XConfigureWindow(dpy, systray->win, CWY, &wc); + } + arrange(selmon); } -void -toggletag(const Arg *arg) +void togglefloating(const Arg *arg) { - unsigned int newtags; - - if (!selmon->sel) - return; - newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); - if (newtags) { - selmon->sel->tags = newtags; - focus(NULL); - arrange(selmon); - } + if (!selmon->sel) + return; + if (selmon->sel->isfullscreen) /* no support for fullscreen windows */ + return; + selmon->sel->isfloating = !selmon->sel->isfloating || selmon->sel->isfixed; + if (selmon->sel->isfloating) + resize(selmon->sel, selmon->sel->x, selmon->sel->y, selmon->sel->w, selmon->sel->h, 0); + arrange(selmon); } -void -toggleview(const Arg *arg) +void toggletag(const Arg *arg) { - unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + unsigned int newtags; - if (newtagset) { - selmon->tagset[selmon->seltags] = newtagset; - focus(NULL); - arrange(selmon); - } + if (!selmon->sel) + return; + newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); + if (newtags) + { + selmon->sel->tags = newtags; + setclienttagprop(selmon->sel); + focus(NULL); + arrange(selmon); + } } -void -unfocus(Client *c, int setfocus) +void toggleview(const Arg *arg) { - if (!c) - return; - grabbuttons(c, 0); - XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); - if (setfocus) { - XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); - XDeleteProperty(dpy, root, netatom[NetActiveWindow]); - } + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) + { + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); + arrange(selmon); + } } -void -unmanage(Client *c, int destroyed) +void unfocus(Client *c, int setfocus) { - Monitor *m = c->mon; - XWindowChanges wc; - - detach(c); - detachstack(c); - if (!destroyed) { - wc.border_width = c->oldbw; - XGrabServer(dpy); /* avoid race conditions */ - XSetErrorHandler(xerrordummy); - XSelectInput(dpy, c->win, NoEventMask); - XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ - XUngrabButton(dpy, AnyButton, AnyModifier, c->win); - setclientstate(c, WithdrawnState); - XSync(dpy, False); - XSetErrorHandler(xerror); - XUngrabServer(dpy); - } - free(c); - focus(NULL); - updateclientlist(); - arrange(m); + if (!c) + return; + grabbuttons(c, 0); + XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel); + if (setfocus) + { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + XDeleteProperty(dpy, root, netatom[NetActiveWindow]); + } } -void -unmapnotify(XEvent *e) +void unmanage(Client *c, int destroyed) { - Client *c; - XUnmapEvent *ev = &e->xunmap; + Monitor *m = c->mon; + XWindowChanges wc; - if ((c = wintoclient(ev->window))) { - if (ev->send_event) - setclientstate(c, WithdrawnState); - else - unmanage(c, 0); - } - else if ((c = wintosystrayicon(ev->window))) { - /* KLUDGE! sometimes icons occasionally unmap their windows, but do - * _not_ destroy them. We map those windows back */ - XMapRaised(dpy, c->win); - updatesystray(); - } + detach(c); + detachstack(c); + if (!destroyed) + { + wc.border_width = c->oldbw; + XGrabServer(dpy); /* avoid race conditions */ + XSetErrorHandler(xerrordummy); + XSelectInput(dpy, c->win, NoEventMask); + XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */ + XUngrabButton(dpy, AnyButton, AnyModifier, c->win); + setclientstate(c, WithdrawnState); + XSync(dpy, False); + XSetErrorHandler(xerror); + XUngrabServer(dpy); + } + free(c); + focus(NULL); + updateclientlist(); + arrange(m); } -void -updatebars(void) +void unmapnotify(XEvent *e) { - unsigned int w; - Monitor *m; - XSetWindowAttributes wa = { - .override_redirect = True, - .background_pixmap = ParentRelative, - .event_mask = ButtonPressMask|ExposureMask - }; - XClassHint ch = {"dwm", "dwm"}; - for (m = mons; m; m = m->next) { - if (m->barwin) - continue; - w = m->ww; - if (showsystray && m == systraytomon(m)) - w -= getsystraywidth(); - m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), - CopyFromParent, DefaultVisual(dpy, screen), - CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); - XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); - if (showsystray && m == systraytomon(m)) - XMapRaised(dpy, systray->win); - XMapRaised(dpy, m->barwin); - XSetClassHint(dpy, m->barwin, &ch); - } + Client *c; + XUnmapEvent *ev = &e->xunmap; + + if ((c = wintoclient(ev->window))) + { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } + else if ((c = wintosystrayicon(ev->window))) + { + /* KLUDGE! sometimes icons occasionally unmap their windows, but do + * _not_ destroy them. We map those windows back */ + XMapRaised(dpy, c->win); + updatesystray(); + } } -void -updatebarpos(Monitor *m) +void updatebars(void) { - m->wy = m->my; - m->wh = m->mh; - if (m->showbar) { - m->wh -= bh; - m->by = m->topbar ? m->wy : m->wy + m->wh; - m->wy = m->topbar ? m->wy + bh : m->wy; - } else - m->by = -bh; + unsigned int w; + Monitor *m; + XSetWindowAttributes wa = {.override_redirect = True, .background_pixmap = ParentRelative, .event_mask = ButtonPressMask | ExposureMask}; + XClassHint ch = {"dwm", "dwm"}; + for (m = mons; m; m = m->next) + { + if (m->barwin) + continue; + w = m->ww; + if (showsystray && m == systraytomon(m)) + w -= getsystraywidth(); + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, w, bh, 0, DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen), CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + if (showsystray && m == systraytomon(m)) + XMapRaised(dpy, systray->win); + XMapRaised(dpy, m->barwin); + XSetClassHint(dpy, m->barwin, &ch); + } } -void -updateclientlist(void) +void updatebarpos(Monitor *m) { - Client *c; - Monitor *m; - - XDeleteProperty(dpy, root, netatom[NetClientList]); - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - XChangeProperty(dpy, root, netatom[NetClientList], - XA_WINDOW, 32, PropModeAppend, - (unsigned char *) &(c->win), 1); + m->wy = m->my; + m->wh = m->mh; + if (m->showbar) + { + m->wh -= bh; + m->by = m->topbar ? m->wy : m->wy + m->wh; + m->wy = m->topbar ? m->wy + bh : m->wy; + } + else + m->by = -bh; } -int -updategeom(void) +void updateclientlist(void) { - int dirty = 0; + Client *c; + Monitor *m; + + XDeleteProperty(dpy, root, netatom[NetClientList]); + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend, (unsigned char *)&(c->win), 1); +} + +int updategeom(void) +{ + int dirty = 0; #ifdef XINERAMA - if (XineramaIsActive(dpy)) { - int i, j, n, nn; - Client *c; - Monitor *m; - XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); - XineramaScreenInfo *unique = NULL; + if (XineramaIsActive(dpy)) + { + int i, j, n, nn; + Client *c; + Monitor *m; + XineramaScreenInfo *info = XineramaQueryScreens(dpy, &nn); + XineramaScreenInfo *unique = NULL; - for (n = 0, m = mons; m; m = m->next, n++); - /* only consider unique geometries as separate screens */ - unique = ecalloc(nn, sizeof(XineramaScreenInfo)); - for (i = 0, j = 0; i < nn; i++) - if (isuniquegeom(unique, j, &info[i])) - memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); - XFree(info); - nn = j; + for (n = 0, m = mons; m; m = m->next, n++) + ; + /* only consider unique geometries as separate screens */ + unique = ecalloc(nn, sizeof(XineramaScreenInfo)); + for (i = 0, j = 0; i < nn; i++) + if (isuniquegeom(unique, j, &info[i])) + memcpy(&unique[j++], &info[i], sizeof(XineramaScreenInfo)); + XFree(info); + nn = j; - /* new monitors if nn > n */ - for (i = n; i < nn; i++) { - for (m = mons; m && m->next; m = m->next); - if (m) - m->next = createmon(); - else - mons = createmon(); - } - for (i = 0, m = mons; i < nn && m; m = m->next, i++) - if (i >= n - || unique[i].x_org != m->mx || unique[i].y_org != m->my - || unique[i].width != m->mw || unique[i].height != m->mh) - { - dirty = 1; - m->num = i; - m->mx = m->wx = unique[i].x_org; - m->my = m->wy = unique[i].y_org; - m->mw = m->ww = unique[i].width; - m->mh = m->wh = unique[i].height; - updatebarpos(m); - } - /* removed monitors if n > nn */ - for (i = nn; i < n; i++) { - for (m = mons; m && m->next; m = m->next); - while ((c = m->clients)) { - dirty = 1; - m->clients = c->next; - detachstack(c); - c->mon = mons; - attach(c); - attachBelow(c); - attachstack(c); - } - if (m == selmon) - selmon = mons; - cleanupmon(m); - } - free(unique); - } else -#endif /* XINERAMA */ - { /* default monitor setup */ - if (!mons) - mons = createmon(); - if (mons->mw != sw || mons->mh != sh) { - dirty = 1; - mons->mw = mons->ww = sw; - mons->mh = mons->wh = sh; - updatebarpos(mons); - } - } - if (dirty) { - selmon = mons; - selmon = wintomon(root); - } - return dirty; + /* new monitors if nn > n */ + for (i = n; i < nn; i++) + { + for (m = mons; m && m->next; m = m->next) + ; + if (m) + m->next = createmon(); + else + mons = createmon(); + } + for (i = 0, m = mons; i < nn && m; m = m->next, i++) + if (i >= n || unique[i].x_org != m->mx || unique[i].y_org != m->my || unique[i].width != m->mw || unique[i].height != m->mh) + { + dirty = 1; + m->num = i; + m->mx = m->wx = unique[i].x_org; + m->my = m->wy = unique[i].y_org; + m->mw = m->ww = unique[i].width; + m->mh = m->wh = unique[i].height; + updatebarpos(m); + } + /* removed monitors if n > nn */ + for (i = nn; i < n; i++) + { + for (m = mons; m && m->next; m = m->next) + ; + while ((c = m->clients)) + { + dirty = 1; + m->clients = c->next; + detachstack(c); + c->mon = mons; + attach(c); + attachBelow(c); + attachstack(c); + } + if (m == selmon) + selmon = mons; + cleanupmon(m); + } + free(unique); + } + else +#endif /* XINERAMA */ + { /* default monitor setup */ + if (!mons) + mons = createmon(); + if (mons->mw != sw || mons->mh != sh) + { + dirty = 1; + mons->mw = mons->ww = sw; + mons->mh = mons->wh = sh; + updatebarpos(mons); + } + } + if (dirty) + { + selmon = mons; + selmon = wintomon(root); + } + return dirty; } -void -updatenumlockmask(void) +void updatenumlockmask(void) { - unsigned int i, j; - XModifierKeymap *modmap; + unsigned int i, j; + XModifierKeymap *modmap; - numlockmask = 0; - modmap = XGetModifierMapping(dpy); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(dpy, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); + numlockmask = 0; + modmap = XGetModifierMapping(dpy); + for (i = 0; i < 8; i++) + for (j = 0; j < modmap->max_keypermod; j++) + if (modmap->modifiermap[i * modmap->max_keypermod + j] == XKeysymToKeycode(dpy, XK_Num_Lock)) + numlockmask = (1 << i); + XFreeModifiermap(modmap); } -void -updatesizehints(Client *c) +void updatesizehints(Client *c) { - long msize; - XSizeHints size; + long msize; + XSizeHints size; - if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) - /* size is uninitialized, ensure that size.flags aren't used */ - size.flags = PSize; - if (size.flags & PBaseSize) { - c->basew = size.base_width; - c->baseh = size.base_height; - } else if (size.flags & PMinSize) { - c->basew = size.min_width; - c->baseh = size.min_height; - } else - c->basew = c->baseh = 0; - if (size.flags & PResizeInc) { - c->incw = size.width_inc; - c->inch = size.height_inc; - } else - c->incw = c->inch = 0; - if (size.flags & PMaxSize) { - c->maxw = size.max_width; - c->maxh = size.max_height; - } else - c->maxw = c->maxh = 0; - if (size.flags & PMinSize) { - c->minw = size.min_width; - c->minh = size.min_height; - } else if (size.flags & PBaseSize) { - c->minw = size.base_width; - c->minh = size.base_height; - } else - c->minw = c->minh = 0; - if (size.flags & PAspect) { - c->mina = (float)size.min_aspect.y / size.min_aspect.x; - c->maxa = (float)size.max_aspect.x / size.max_aspect.y; - } else - c->maxa = c->mina = 0.0; - c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); - c->hintsvalid = 1; + if (!XGetWMNormalHints(dpy, c->win, &size, &msize)) + /* size is uninitialized, ensure that size.flags aren't used */ + size.flags = PSize; + if (size.flags & PBaseSize) + { + c->basew = size.base_width; + c->baseh = size.base_height; + } + else if (size.flags & PMinSize) + { + c->basew = size.min_width; + c->baseh = size.min_height; + } + else + c->basew = c->baseh = 0; + if (size.flags & PResizeInc) + { + c->incw = size.width_inc; + c->inch = size.height_inc; + } + else + c->incw = c->inch = 0; + if (size.flags & PMaxSize) + { + c->maxw = size.max_width; + c->maxh = size.max_height; + } + else + c->maxw = c->maxh = 0; + if (size.flags & PMinSize) + { + c->minw = size.min_width; + c->minh = size.min_height; + } + else if (size.flags & PBaseSize) + { + c->minw = size.base_width; + c->minh = size.base_height; + } + else + c->minw = c->minh = 0; + if (size.flags & PAspect) + { + c->mina = (float)size.min_aspect.y / size.min_aspect.x; + c->maxa = (float)size.max_aspect.x / size.max_aspect.y; + } + else + c->maxa = c->mina = 0.0; + c->isfixed = (c->maxw && c->maxh && c->maxw == c->minw && c->maxh == c->minh); + c->hintsvalid = 1; } -void -updatestatus(void) +void updatestatus(void) { - if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) - strcpy(stext, "dwm-"VERSION); - drawbar(selmon); - updatesystray(); + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-" VERSION); + drawbar(selmon); + updatesystray(); } - -void -updatesystrayicongeom(Client *i, int w, int h) +void updatesystrayicongeom(Client *i, int w, int h) { - if (i) { - i->h = bh; - if (w == h) - i->w = bh; - else if (h == bh) - i->w = w; - else - i->w = (int) ((float)bh * ((float)w / (float)h)); - applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); - /* force icons into the systray dimensions if they don't want to */ - if (i->h > bh) { - if (i->w == i->h) - i->w = bh; - else - i->w = (int) ((float)bh * ((float)i->w / (float)i->h)); - i->h = bh; - } - } + if (i) + { + i->h = bh; + if (w == h) + i->w = bh; + else if (h == bh) + i->w = w; + else + i->w = (int)((float)bh * ((float)w / (float)h)); + applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False); + /* force icons into the systray dimensions if they don't want to */ + if (i->h > bh) + { + if (i->w == i->h) + i->w = bh; + else + i->w = (int)((float)bh * ((float)i->w / (float)i->h)); + i->h = bh; + } + } } -void -updatesystrayiconstate(Client *i, XPropertyEvent *ev) +void updatesystrayiconstate(Client *i, XPropertyEvent *ev) { - long flags; - int code = 0; + long flags; + int code = 0; - if (!showsystray || !i || ev->atom != xatom[XembedInfo] || - !(flags = getatomprop(i, xatom[XembedInfo]))) - return; + if (!showsystray || !i || ev->atom != xatom[XembedInfo] || !(flags = getatomprop(i, xatom[XembedInfo]))) + return; - if (flags & XEMBED_MAPPED && !i->tags) { - i->tags = 1; - code = XEMBED_WINDOW_ACTIVATE; - XMapRaised(dpy, i->win); - setclientstate(i, NormalState); - } - else if (!(flags & XEMBED_MAPPED) && i->tags) { - i->tags = 0; - code = XEMBED_WINDOW_DEACTIVATE; - XUnmapWindow(dpy, i->win); - setclientstate(i, WithdrawnState); - } - else - return; - sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, - systray->win, XEMBED_EMBEDDED_VERSION); + if (flags & XEMBED_MAPPED && !i->tags) + { + i->tags = 1; + code = XEMBED_WINDOW_ACTIVATE; + XMapRaised(dpy, i->win); + setclientstate(i, NormalState); + } + else if (!(flags & XEMBED_MAPPED) && i->tags) + { + i->tags = 0; + code = XEMBED_WINDOW_DEACTIVATE; + XUnmapWindow(dpy, i->win); + setclientstate(i, WithdrawnState); + } + else + return; + sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0, systray->win, XEMBED_EMBEDDED_VERSION); } -void -updatesystray(void) +void updatesystray(void) { - XSetWindowAttributes wa; - XWindowChanges wc; - Client *i; - Monitor *m = systraytomon(NULL); - unsigned int x = m->mx + m->mw; - unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; - unsigned int w = 1; + XSetWindowAttributes wa; + XWindowChanges wc; + Client *i; + Monitor *m = systraytomon(NULL); + unsigned int x = m->mx + m->mw; + unsigned int sw = TEXTW(stext) - lrpad + systrayspacing; + unsigned int w = 1; - if (!showsystray) - return; - if (systrayonleft) - x -= sw + lrpad / 2; - if (!systray) { - /* init systray */ - if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) - die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); - systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); - wa.event_mask = ButtonPressMask | ExposureMask; - wa.override_redirect = True; - wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - XSelectInput(dpy, systray->win, SubstructureNotifyMask); - XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, - PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); - XChangeWindowAttributes(dpy, systray->win, CWEventMask|CWOverrideRedirect|CWBackPixel, &wa); - XMapRaised(dpy, systray->win); - XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); - if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) { - sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); - XSync(dpy, False); - } - else { - fprintf(stderr, "dwm: unable to obtain system tray.\n"); - free(systray); - systray = NULL; - return; - } - } - for (w = 0, i = systray->icons; i; i = i->next) { - /* make sure the background color stays the same */ - wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; - XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); - XMapRaised(dpy, i->win); - w += systrayspacing; - i->x = w; - XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); - w += i->w; - if (i->mon != m) - i->mon = m; - } - w = w ? w + systrayspacing : 1; - x -= w; - XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); - wc.x = x; wc.y = m->by; wc.width = w; wc.height = bh; - wc.stack_mode = Above; wc.sibling = m->barwin; - XConfigureWindow(dpy, systray->win, CWX|CWY|CWWidth|CWHeight|CWSibling|CWStackMode, &wc); - XMapWindow(dpy, systray->win); - XMapSubwindows(dpy, systray->win); - /* redraw background */ - XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); - XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); - XSync(dpy, False); + if (!showsystray) + return; + if (systrayonleft) + x -= sw + lrpad / 2; + if (!systray) + { + /* init systray */ + if (!(systray = (Systray *)calloc(1, sizeof(Systray)))) + die("fatal: could not malloc() %u bytes\n", sizeof(Systray)); + systray->win = XCreateSimpleWindow(dpy, root, x, m->by, w, bh, 0, 0, scheme[SchemeSel][ColBg].pixel); + wa.event_mask = ButtonPressMask | ExposureMask; + wa.override_redirect = True; + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XSelectInput(dpy, systray->win, SubstructureNotifyMask); + XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&netatom[NetSystemTrayOrientationHorz], 1); + XChangeWindowAttributes(dpy, systray->win, CWEventMask | CWOverrideRedirect | CWBackPixel, &wa); + XMapRaised(dpy, systray->win); + XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime); + if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) + { + sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0); + XSync(dpy, False); + } + else + { + fprintf(stderr, "dwm: unable to obtain system tray.\n"); + free(systray); + systray = NULL; + return; + } + } + for (w = 0, i = systray->icons; i; i = i->next) + { + /* make sure the background color stays the same */ + wa.background_pixel = scheme[SchemeNorm][ColBg].pixel; + XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa); + XMapRaised(dpy, i->win); + w += systrayspacing; + i->x = w; + XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h); + w += i->w; + if (i->mon != m) + i->mon = m; + } + w = w ? w + systrayspacing : 1; + x -= w; + XMoveResizeWindow(dpy, systray->win, x, m->by, w, bh); + wc.x = x; + wc.y = m->by; + wc.width = w; + wc.height = bh; + wc.stack_mode = Above; + wc.sibling = m->barwin; + XConfigureWindow(dpy, systray->win, CWX | CWY | CWWidth | CWHeight | CWSibling | CWStackMode, &wc); + XMapWindow(dpy, systray->win); + XMapSubwindows(dpy, systray->win); + /* redraw background */ + XSetForeground(dpy, drw->gc, scheme[SchemeNorm][ColBg].pixel); + XFillRectangle(dpy, systray->win, drw->gc, 0, 0, w, bh); + XSync(dpy, False); } -void -updatetitle(Client *c) +void updatetitle(Client *c) { - if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) - gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); - if (c->name[0] == '\0') /* hack to mark broken clients */ - strcpy(c->name, broken); + if (!gettextprop(c->win, netatom[NetWMName], c->name, sizeof c->name)) + gettextprop(c->win, XA_WM_NAME, c->name, sizeof c->name); + if (c->name[0] == '\0') /* hack to mark broken clients */ + strcpy(c->name, broken); } -void -updatewindowtype(Client *c) +void updatewindowtype(Client *c) { - Atom state = getatomprop(c, netatom[NetWMState]); - Atom wtype = getatomprop(c, netatom[NetWMWindowType]); + Atom state = getatomprop(c, netatom[NetWMState]); + Atom wtype = getatomprop(c, netatom[NetWMWindowType]); - if (state == netatom[NetWMFullscreen]) - setfullscreen(c, 1); - if (wtype == netatom[NetWMWindowTypeDialog]) - c->isfloating = 1; + if (state == netatom[NetWMFullscreen]) + setfullscreen(c, 1); + if (wtype == netatom[NetWMWindowTypeDialog]) + c->isfloating = 1; } -void -updatewmhints(Client *c) +void updatewmhints(Client *c) { - XWMHints *wmh; + XWMHints *wmh; - if ((wmh = XGetWMHints(dpy, c->win))) { - if (c == selmon->sel && wmh->flags & XUrgencyHint) { - wmh->flags &= ~XUrgencyHint; - XSetWMHints(dpy, c->win, wmh); - } else - c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; - if (wmh->flags & InputHint) - c->neverfocus = !wmh->input; - else - c->neverfocus = 0; - XFree(wmh); - } + if ((wmh = XGetWMHints(dpy, c->win))) + { + if (c == selmon->sel && wmh->flags & XUrgencyHint) + { + wmh->flags &= ~XUrgencyHint; + XSetWMHints(dpy, c->win, wmh); + } + else + c->isurgent = (wmh->flags & XUrgencyHint) ? 1 : 0; + if (wmh->flags & InputHint) + c->neverfocus = !wmh->input; + else + c->neverfocus = 0; + XFree(wmh); + } } -void -view(const Arg *arg) +void view(const Arg *arg) { - if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) - return; - selmon->seltags ^= 1; /* toggle sel tagset */ - if (arg->ui & TAGMASK) - selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; - focus(NULL); - arrange(selmon); + if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + return; + selmon->seltags ^= 1; /* toggle sel tagset */ + if (arg->ui & TAGMASK) + selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); } -Client * -wintoclient(Window w) +Client *wintoclient(Window w) { - Client *c; - Monitor *m; + Client *c; + Monitor *m; - for (m = mons; m; m = m->next) - for (c = m->clients; c; c = c->next) - if (c->win == w) - return c; - return NULL; + for (m = mons; m; m = m->next) + for (c = m->clients; c; c = c->next) + if (c->win == w) + return c; + return NULL; } -Client * -wintosystrayicon(Window w) { - Client *i = NULL; - - if (!showsystray || !w) - return i; - for (i = systray->icons; i && i->win != w; i = i->next) ; - return i; -} - -Monitor * -wintomon(Window w) +Client *wintosystrayicon(Window w) { - int x, y; - Client *c; - Monitor *m; + Client *i = NULL; - if (w == root && getrootptr(&x, &y)) - return recttomon(x, y, 1, 1); - for (m = mons; m; m = m->next) - if (w == m->barwin) - return m; - if ((c = wintoclient(w))) - return c->mon; - return selmon; + if (!showsystray || !w) + return i; + for (i = systray->icons; i && i->win != w; i = i->next) + ; + return i; +} + +Monitor *wintomon(Window w) +{ + int x, y; + Client *c; + Monitor *m; + + if (w == root && getrootptr(&x, &y)) + return recttomon(x, y, 1, 1); + for (m = mons; m; m = m->next) + if (w == m->barwin) + return m; + if ((c = wintoclient(w))) + return c->mon; + return selmon; } /* 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. */ -int -xerror(Display *dpy, XErrorEvent *ee) +int xerror(Display *dpy, XErrorEvent *ee) { - if (ee->error_code == BadWindow - || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) - || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) - || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) - || (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) - || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) - || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) - || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) - || (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) - return 0; - fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", - ee->request_code, ee->error_code); - return xerrorxlib(dpy, ee); /* may call exit */ + if (ee->error_code == BadWindow || (ee->request_code == X_SetInputFocus && ee->error_code == BadMatch) || (ee->request_code == X_PolyText8 && ee->error_code == BadDrawable) || (ee->request_code == X_PolyFillRectangle && ee->error_code == BadDrawable) || + (ee->request_code == X_PolySegment && ee->error_code == BadDrawable) || (ee->request_code == X_ConfigureWindow && ee->error_code == BadMatch) || (ee->request_code == X_GrabButton && ee->error_code == BadAccess) || (ee->request_code == X_GrabKey && ee->error_code == BadAccess) || + (ee->request_code == X_CopyArea && ee->error_code == BadDrawable)) + return 0; + fprintf(stderr, "dwm: fatal error: request code=%d, error code=%d\n", ee->request_code, ee->error_code); + return xerrorxlib(dpy, ee); /* may call exit */ } -int -xerrordummy(Display *dpy, XErrorEvent *ee) -{ - return 0; -} +int xerrordummy(Display *dpy, XErrorEvent *ee) { return 0; } /* Startup Error handler to check if another window manager * is already running. */ -int -xerrorstart(Display *dpy, XErrorEvent *ee) +int xerrorstart(Display *dpy, XErrorEvent *ee) { - die("dwm: another window manager is already running"); - return -1; + die("dwm: another window manager is already running"); + return -1; } -Monitor * -systraytomon(Monitor *m) { - Monitor *t; - int i, n; - if(!systraypinning) { - if(!m) - return selmon; - return m == selmon ? m : NULL; - } - for(n = 1, t = mons; t && t->next; n++, t = t->next) ; - for(i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) ; - if(systraypinningfailfirst && n < systraypinning) - return mons; - return t; +Monitor *systraytomon(Monitor *m) +{ + Monitor *t; + int i, n; + if (!systraypinning) + { + if (!m) + return selmon; + return m == selmon ? m : NULL; + } + for (n = 1, t = mons; t && t->next; n++, t = t->next) + ; + for (i = 1, t = mons; t && t->next && i < systraypinning; i++, t = t->next) + ; + if (systraypinningfailfirst && n < systraypinning) + return mons; + return t; } -void -zoom(const Arg *arg) +void zoom(const Arg *arg) { - Client *c = selmon->sel; + Client *c = selmon->sel; - if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) - return; - if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) - return; - pop(c); + if (!selmon->lt[selmon->sellt]->arrange || !c || c->isfloating) + return; + if (c == nexttiled(selmon->clients) && !(c = nexttiled(c->next))) + return; + pop(c); } -int -main(int argc, char *argv[]) +int main(int argc, char *argv[]) { - if (argc == 2 && !strcmp("-v", argv[1])) - die("dwm-"VERSION); - else if (argc != 1) - die("usage: dwm [-v]"); - if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) - fputs("warning: no locale support\n", stderr); - if (!(dpy = XOpenDisplay(NULL))) - die("dwm: cannot open display"); - checkotherwm(); - setup(); + if (argc == 2 && !strcmp("-v", argv[1])) + die("dwm-" VERSION); + else if (argc != 1) + die("usage: dwm [-v]"); + if (!setlocale(LC_CTYPE, "") || !XSupportsLocale()) + fputs("warning: no locale support\n", stderr); + if (!(dpy = XOpenDisplay(NULL))) + die("dwm: cannot open display"); + checkotherwm(); + setup(); #ifdef __OpenBSD__ - if (pledge("stdio rpath proc exec", NULL) == -1) - die("pledge"); + if (pledge("stdio rpath proc exec", NULL) == -1) + die("pledge"); #endif /* __OpenBSD__ */ - scan(); - runautostart(); - run(); - cleanup(); - XCloseDisplay(dpy); - return EXIT_SUCCESS; + scan(); + runautostart(); + run(); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; } diff --git a/dwm.o b/dwm.o index 427654693479c348280021c0742680b1dfc10e73..a899982ce57228b2e8534816836b05c2e84dbefe 100644 GIT binary patch delta 28032 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 Nt;Wa^KP$