From 24eb54c5968fff127b1349325890ecc18fc4e651 Mon Sep 17 00:00:00 2001 From: TolaMironcenko Date: Mon, 1 Jul 2024 10:03:33 +0700 Subject: [PATCH] dwm gaps patch --- dwm/config.def.h | 1 + dwm/config.def.h.orig | 5 + dwm/config.def.h.rej | 32 +- dwm/config.h | 1 + dwm/dwm | Bin 67408 -> 67408 bytes dwm/dwm.c | 18 +- dwm/dwm.c.orig | 2167 +++++++++++++++++++++++++++++++++ dwm/dwm.c.rej | 39 + dwm/dwm.o | Bin 58752 -> 58784 bytes dwm/patches/dwm-gaps-6.0.diff | 53 + 10 files changed, 2284 insertions(+), 32 deletions(-) create mode 100644 dwm/dwm.c.orig create mode 100644 dwm/dwm.c.rej create mode 100644 dwm/patches/dwm-gaps-6.0.diff diff --git a/dwm/config.def.h b/dwm/config.def.h index c76c8ab..2aae1e2 100644 --- a/dwm/config.def.h +++ b/dwm/config.def.h @@ -2,6 +2,7 @@ /* appearance */ static const unsigned int borderpx = 1; /* border pixel of windows */ +static const unsigned int gappx = 1; /* gap pixel between windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ diff --git a/dwm/config.def.h.orig b/dwm/config.def.h.orig index 9efa774..c76c8ab 100644 --- a/dwm/config.def.h.orig +++ b/dwm/config.def.h.orig @@ -37,11 +37,14 @@ static const int nmaster = 1; /* number of clients in master area */ static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ +#include "fibonacci.c" static const Layout layouts[] = { /* symbol arrange function */ { "[]=", tile }, /* first entry is default */ { "><>", NULL }, /* no layout function means floating behavior */ { "[M]", monocle }, + { "[@]", spiral }, + { "[\\]", dwindle }, }; /* key definitions */ @@ -77,6 +80,8 @@ static const Key keys[] = { { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_r, setlayout, {.v = &layouts[3]} }, + { MODKEY|ShiftMask, XK_r, setlayout, {.v = &layouts[4]} }, { MODKEY, XK_space, setlayout, {0} }, { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, { MODKEY, XK_0, view, {.ui = ~0 } }, diff --git a/dwm/config.def.h.rej b/dwm/config.def.h.rej index 6b8c17e..6ca83e3 100644 --- a/dwm/config.def.h.rej +++ b/dwm/config.def.h.rej @@ -1,26 +1,10 @@ --- config.def.h +++ config.def.h -@@ -36,11 +36,14 @@ static const float mfact = 0.55; /* factor of master area size [0.05..0.95] - static const int nmaster = 1; /* number of clients in master area */ - static const int resizehints = 1; /* 1 means respect size hints in tiled resizals */ - -+#include "fibonacci.c" - static const Layout layouts[] = { - /* symbol arrange function */ - { "[]=", tile }, /* first entry is default */ - { "><>", NULL }, /* no layout function means floating behavior */ - { "[M]", monocle }, -+ { "[@]", spiral }, -+ { "[\\]", dwindle }, - }; - - /* key definitions */ -@@ -76,6 +79,8 @@ static Key keys[] = { - { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, -+ { MODKEY, XK_r, setlayout, {.v = &layouts[3]} }, -+ { MODKEY|ShiftMask, XK_r, setlayout, {.v = &layouts[4]} }, - { MODKEY, XK_space, setlayout, {0} }, - { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, - { MODKEY, XK_0, view, {.ui = ~0 } }, +@@ -9,6 +9,7 @@ static const char selbordercolor[] = "#005577"; + static const char selbgcolor[] = "#005577"; + static const char selfgcolor[] = "#eeeeee"; + static const unsigned int borderpx = 1; /* border pixel of windows */ ++static const unsigned int gappx = 1; /* gap pixel between windows */ + static const unsigned int snap = 32; /* snap pixel */ + static const Bool showbar = True; /* False means no bar */ + static const Bool topbar = True; /* False means bottom bar */ diff --git a/dwm/config.h b/dwm/config.h index 98a174c..e00eb92 100644 --- a/dwm/config.h +++ b/dwm/config.h @@ -2,6 +2,7 @@ /* appearance */ static const unsigned int borderpx = 5; /* border pixel of windows */ +static const unsigned int gappx = 5; /* gap pixel between windows */ static const unsigned int snap = 32; /* snap pixel */ static const int showbar = 1; /* 0 means no bar */ static const int topbar = 1; /* 0 means bottom bar */ diff --git a/dwm/dwm b/dwm/dwm index 49684e53f1705bbb50b6c56ccfeddec94ce600e4..ee353bc512b487df24f2dbe5abcd7436a2813195 100755 GIT binary patch delta 11858 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

moq*I}%Fw-jwx=OW)a$G8<37(YT-h?3Lw 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 Qm21?>R&Jl{#@}-Le_XvPW&i*H diff --git a/dwm/dwm.c b/dwm/dwm.c index 67c6b2b..c628af0 100644 --- a/dwm/dwm.c +++ b/dwm/dwm.c @@ -1687,7 +1687,7 @@ tagmon(const Arg *arg) void tile(Monitor *m) { - unsigned int i, n, h, mw, my, ty; + unsigned int i, n, h, r, g = 0, mw, my, ty; Client *c; for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); @@ -1695,20 +1695,22 @@ tile(Monitor *m) return; if (n > m->nmaster) - mw = m->nmaster ? m->ww * m->mfact : 0; + mw = m->nmaster ? (m->ww - (g = gappx)) * m->mfact : 0; else mw = m->ww; for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) if (i < m->nmaster) { - h = (m->wh - my) / (MIN(n, m->nmaster) - i); + r = MIN(n, m->nmaster) - i; + h = (m->wh - my - gappx * (r - 1)) / r; resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); if (my + HEIGHT(c) < m->wh) - my += HEIGHT(c); + my += HEIGHT(c) + gappx; } else { - h = (m->wh - ty) / (n - i); - resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); - if (ty + HEIGHT(c) < m->wh) - ty += HEIGHT(c); + r = n - i; + h = (m->wh - ty - gappx * (r - 1)) / r; + resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), 0); + if (ty + HEIGHT(c) + gappx < m->wh) + ty += HEIGHT(c) + gappx; } } diff --git a/dwm/dwm.c.orig b/dwm/dwm.c.orig new file mode 100644 index 0000000..c628af0 --- /dev/null +++ b/dwm/dwm.c.orig @@ -0,0 +1,2167 @@ +/* See LICENSE file for copyright and license details. + * + * dynamic window manager is designed like any other X client as well. It is + * driven through handling X events. In contrast to other X clients, a window + * manager selects for SubstructureRedirectMask on the root window, to receive + * events about window (dis-)appearance. Only one X connection at a time is + * allowed to select for this event mask. + * + * The event handlers of dwm are organized in an array which is accessed + * whenever a new event has been fetched. This allows event dispatching + * in O(1) time. + * + * Each child of the root window is called a client, except windows which have + * set the override_redirect flag. Clients are organized in a linked client + * list on each monitor, the focus history is remembered through a stack list + * on each monitor. Each client contains a bit array to indicate the tags of a + * client. + * + * Keys and tagging rules are organized as arrays and defined in config.h. + * + * To understand everything else, start reading main(). + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef XINERAMA +#include +#endif /* XINERAMA */ +#include + +#include "drw.h" +#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 ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags])) +#define LENGTH(X) (sizeof X / sizeof X[0]) +#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) + +/* enums */ +enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */ +enum { SchemeNorm, SchemeSel }; /* color schemes */ +enum { NetSupported, NetWMName, NetWMState, NetWMCheck, + NetWMFullscreen, NetActiveWindow, NetWMWindowType, + NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH 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; +} 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; + 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; +} Key; + +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 */ + 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; +} Rule; + +/* function declarations */ +static void applyrules(Client *c); +static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact); +static void arrange(Monitor *m); +static void arrangemon(Monitor *m); +static void attach(Client *c); +static void attachstack(Client *c); +static void buttonpress(XEvent *e); +static void checkotherwm(void); +static void cleanup(void); +static void cleanupmon(Monitor *mon); +static void clientmessage(XEvent *e); +static void configure(Client *c); +static void configurenotify(XEvent *e); +static void configurerequest(XEvent *e); +static Monitor *createmon(void); +static void destroynotify(XEvent *e); +static void detach(Client *c); +static void detachstack(Client *c); +static Monitor *dirtomon(int dir); +static void drawbar(Monitor *m); +static void drawbars(void); +static void enternotify(XEvent *e); +static void expose(XEvent *e); +static void focus(Client *c); +static void focusin(XEvent *e); +static void focusmon(const Arg *arg); +static void focusstack(const Arg *arg); +static Atom getatomprop(Client *c, Atom prop); +static int getrootptr(int *x, int *y); +static long getstate(Window w); +static int gettextprop(Window w, Atom atom, char *text, unsigned int size); +static void grabbuttons(Client *c, int focused); +static void grabkeys(void); +static void incnmaster(const Arg *arg); +static void keypress(XEvent *e); +static void killclient(const Arg *arg); +static void manage(Window w, XWindowAttributes *wa); +static void mappingnotify(XEvent *e); +static void maprequest(XEvent *e); +static void monocle(Monitor *m); +static void motionnotify(XEvent *e); +static void movemouse(const Arg *arg); +static Client *nexttiled(Client *c); +static void pop(Client *c); +static void propertynotify(XEvent *e); +static void quit(const Arg *arg); +static Monitor *recttomon(int x, int y, int w, int h); +static void resize(Client *c, int x, int y, int w, int h, int interact); +static void resizeclient(Client *c, int x, int y, int w, int h); +static void resizemouse(const Arg *arg); +static void restack(Monitor *m); +static void run(void); +static void scan(void); +static int sendevent(Client *c, Atom proto); +static void sendmon(Client *c, Monitor *m); +static void setclientstate(Client *c, long state); +static void setfocus(Client *c); +static void setfullscreen(Client *c, int fullscreen); +static void setlayout(const Arg *arg); +static void setmfact(const Arg *arg); +static void setup(void); +static void seturgent(Client *c, int urg); +static void showhide(Client *c); +static void spawn(const Arg *arg); +static void tag(const Arg *arg); +static void tagmon(const Arg *arg); +static void tile(Monitor *m); +static void togglebar(const Arg *arg); +static void togglefloating(const Arg *arg); +static void toggletag(const Arg *arg); +static void toggleview(const Arg *arg); +static void unfocus(Client *c, int setfocus); +static void unmanage(Client *c, int destroyed); +static void unmapnotify(XEvent *e); +static void updatebarpos(Monitor *m); +static void updatebars(void); +static void updateclientlist(void); +static int updategeom(void); +static void updatenumlockmask(void); +static void updatesizehints(Client *c); +static void updatestatus(void); +static void updatetitle(Client *c); +static void updatewindowtype(Client *c); +static void updatewmhints(Client *c); +static void view(const Arg *arg); +static Client *wintoclient(Window w); +static Monitor *wintomon(Window w); +static int xerror(Display *dpy, XErrorEvent *ee); +static int xerrordummy(Display *dpy, XErrorEvent *ee); +static int xerrorstart(Display *dpy, XErrorEvent *ee); +static void zoom(const Arg *arg); + +/* variables */ +static const char broken[] = "broken"; +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 (*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, + [UnmapNotify] = unmapnotify +}; +static Atom wmatom[WMLast], netatom[NetLast]; +static int running = 1; +static Cur *cursor[CurLast]; +static Clr **scheme; +static Display *dpy; +static Drw *drw; +static Monitor *mons, *selmon; +static Window root, wmcheckwin; + +/* configuration, allows nested code to access above variables */ +#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]; }; + +/* function implementations */ +void +applyrules(Client *c) +{ + 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; + + 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 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; +} + +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); +} + +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); +} + +void +attach(Client *c) +{ + c->next = c->mon->clients; + c->mon->clients = c; +} + +void +attachstack(Client *c) +{ + c->snext = c->mon->stack; + c->mon->stack = c; +} + +void +buttonpress(XEvent *e) +{ + 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)) + 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) +{ + 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) +{ + 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); + for (i = 0; i < CurLast; i++) + drw_cur_free(drw, cursor[i]); + for (i = 0; i < LENGTH(colors); i++) + free(scheme[i]); + 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) +{ + 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); +} + +void +clientmessage(XEvent *e) +{ + XClientMessageEvent *cme = &e->xclient; + Client *c = wintoclient(cme->window); + + 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) +{ + 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); +} + +void +configurenotify(XEvent *e) +{ + 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); + XMoveResizeWindow(dpy, m->barwin, m->wx, m->by, m->ww, bh); + } + focus(NULL); + arrange(NULL); + } + } +} + +void +configurerequest(XEvent *e) +{ + 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); +} + +Monitor * +createmon(void) +{ + 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->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) +{ + Client *c; + XDestroyWindowEvent *ev = &e->xdestroywindow; + + if ((c = wintoclient(ev->window))) + unmanage(c, 1); +} + +void +detach(Client *c) +{ + Client **tc; + + for (tc = &c->mon->clients; *tc && *tc != c; tc = &(*tc)->next); + *tc = c->next; +} + +void +detachstack(Client *c) +{ + Client **tc, *t; + + 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; + } +} + +Monitor * +dirtomon(int dir) +{ + 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; +} + +void +drawbar(Monitor *m) +{ + int x, w, tw = 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; + + /* 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; /* 2px right padding */ + drw_text(drw, m->ww - tw, 0, tw, bh, 0, stext, 0); + } + + 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 - 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, bh); +} + +void +drawbars(void) +{ + Monitor *m; + + for (m = mons; m; m = m->next) + drawbar(m); +} + +void +enternotify(XEvent *e) +{ + 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); +} + +void +expose(XEvent *e) +{ + Monitor *m; + XExposeEvent *ev = &e->xexpose; + + if (ev->count == 0 && (m = wintomon(ev->window))) + drawbar(m); +} + +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(); +} + +/* there are some broken focus acquiring clients needing extra handling */ +void +focusin(XEvent *e) +{ + XFocusChangeEvent *ev = &e->xfocus; + + if (selmon->sel && ev->window != selmon->sel->win) + setfocus(selmon->sel); +} + +void +focusmon(const Arg *arg) +{ + Monitor *m; + + if (!mons->next) + return; + if ((m = dirtomon(arg->i)) == selmon) + return; + unfocus(selmon->sel, 0); + selmon = m; + focus(NULL); +} + +void +focusstack(const Arg *arg) +{ + 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); + } +} + +Atom +getatomprop(Client *c, Atom prop) +{ + int di; + unsigned long dl; + unsigned char *p = NULL; + Atom da, atom = None; + + if (XGetWindowProperty(dpy, c->win, prop, 0L, sizeof atom, False, XA_ATOM, + &da, &di, &dl, &dl, &p) == Success && p) { + atom = *(Atom *)p; + XFree(p); + } + return atom; +} + +int +getrootptr(int *x, int *y) +{ + int di; + unsigned int dui; + Window dummy; + + return XQueryPointer(dpy, root, &dummy, &dummy, x, y, &di, &di, &dui); +} + +long +getstate(Window w) +{ + 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, (unsigned char **)&p) != Success) + return -1; + if (n != 0) + result = *p; + XFree(p); + return result; +} + +int +gettextprop(Window w, Atom atom, char *text, unsigned int size) +{ + 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; +} + +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); + } +} + +void +grabkeys(void) +{ + 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); + } +} + +void +incnmaster(const Arg *arg) +{ + selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); + arrange(selmon); +} + +#ifdef XINERAMA +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; +} +#endif /* XINERAMA */ + +void +keypress(XEvent *e) +{ + 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)); +} + +void +killclient(const Arg *arg) +{ + if (!selmon->sel) + return; + if (!sendevent(selmon->sel, wmatom[WMDelete])) { + 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) +{ + 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; + + 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; + + 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); + attach(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) +{ + XMappingEvent *ev = &e->xmapping; + + XRefreshKeyboardMapping(ev); + if (ev->request == MappingKeyboard) + grabkeys(); +} + +void +maprequest(XEvent *e) +{ + static XWindowAttributes wa; + XMapRequestEvent *ev = &e->xmaprequest; + + if (!XGetWindowAttributes(dpy, ev->window, &wa) || wa.override_redirect) + return; + if (!wintoclient(ev->window)) + manage(ev->window, &wa); +} + +void +monocle(Monitor *m) +{ + 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); +} + +void +motionnotify(XEvent *e) +{ + 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; +} + +void +movemouse(const Arg *arg) +{ + 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 / 60)) + 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); + } +} + +Client * +nexttiled(Client *c) +{ + for (; c && (c->isfloating || !ISVISIBLE(c)); c = c->next); + return c; +} + +void +pop(Client *c) +{ + detach(c); + attach(c); + focus(c); + arrange(c->mon); +} + +void +propertynotify(XEvent *e) +{ + Client *c; + Window trans; + XPropertyEvent *ev = &e->xproperty; + + 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); + } +} + +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; + + for (m = mons; m; m = m->next) + if ((a = INTERSECT(x, y, w, h, m)) > area) { + area = a; + r = m; + } + return r; +} + +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); +} + +void +resizeclient(Client *c, int x, int y, int w, int h) +{ + 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); +} + +void +resizemouse(const Arg *arg) +{ + int ocx, ocy, nw, nh; + Client *c; + Monitor *m; + XEvent ev; + Time lasttime = 0; + + 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 / 60)) + 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 +restack(Monitor *m) +{ + 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 +run(void) +{ + 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) +{ + 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 +sendmon(Client *c, Monitor *m) +{ + 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 */ + attach(c); + attachstack(c); + focus(NULL); + arrange(NULL); +} + +void +setclientstate(Client *c, long state) +{ + long data[] = { state, None }; + + XChangeProperty(dpy, c->win, wmatom[WMState], wmatom[WMState], 32, + PropModeReplace, (unsigned char *)data, 2); +} + +int +sendevent(Client *c, Atom proto) +{ + int n; + Atom *protocols; + int exists = 0; + XEvent ev; + + if (XGetWMProtocols(dpy, c->win, &protocols, &n)) { + while (!exists && n--) + exists = protocols[n] == proto; + XFree(protocols); + } + if (exists) { + ev.type = ClientMessage; + ev.xclient.window = c->win; + ev.xclient.message_type = wmatom[WMProtocols]; + ev.xclient.format = 32; + ev.xclient.data.l[0] = proto; + ev.xclient.data.l[1] = CurrentTime; + XSendEvent(dpy, c->win, False, NoEventMask, &ev); + } + return exists; +} + +void +setfocus(Client *c) +{ + 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, wmatom[WMTakeFocus]); +} + +void +setfullscreen(Client *c, int fullscreen) +{ + 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 +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); +} + +/* arg > 1.0 will set mfact absolutely */ +void +setmfact(const Arg *arg) +{ + 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); +} + +void +setup(void) +{ + 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); + + /* 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[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); + /* 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 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); +} + +void +seturgent(Client *c, int urg) +{ + 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); +} + +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); + } +} + +void +spawn(const Arg *arg) +{ + struct sigaction sa; + + 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); + + execvp(((char **)arg->v)[0], (char **)arg->v); + die("dwm: execvp '%s' failed:", ((char **)arg->v)[0]); + } +} + +void +tag(const Arg *arg) +{ + if (selmon->sel && arg->ui & TAGMASK) { + selmon->sel->tags = arg->ui & TAGMASK; + focus(NULL); + arrange(selmon); + } +} + +void +tagmon(const Arg *arg) +{ + if (!selmon->sel || !mons->next) + return; + sendmon(selmon->sel, dirtomon(arg->i)); +} + +void +tile(Monitor *m) +{ + unsigned int i, n, h, r, g = 0, mw, my, ty; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + + if (n > m->nmaster) + mw = m->nmaster ? (m->ww - (g = gappx)) * m->mfact : 0; + else + mw = m->ww; + for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + r = MIN(n, m->nmaster) - i; + h = (m->wh - my - gappx * (r - 1)) / r; + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0); + if (my + HEIGHT(c) < m->wh) + my += HEIGHT(c) + gappx; + } else { + r = n - i; + h = (m->wh - ty - gappx * (r - 1)) / r; + resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), 0); + if (ty + HEIGHT(c) + gappx < m->wh) + ty += HEIGHT(c) + gappx; + } +} + +void +togglebar(const Arg *arg) +{ + selmon->showbar = !selmon->showbar; + updatebarpos(selmon); + XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); + arrange(selmon); +} + +void +togglefloating(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); +} + +void +toggletag(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); + } +} + +void +toggleview(const Arg *arg) +{ + unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK); + + if (newtagset) { + selmon->tagset[selmon->seltags] = newtagset; + focus(NULL); + arrange(selmon); + } +} + +void +unfocus(Client *c, int setfocus) +{ + 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 +unmanage(Client *c, int destroyed) +{ + 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); +} + +void +unmapnotify(XEvent *e) +{ + Client *c; + XUnmapEvent *ev = &e->xunmap; + + if ((c = wintoclient(ev->window))) { + if (ev->send_event) + setclientstate(c, WithdrawnState); + else + unmanage(c, 0); + } +} + +void +updatebars(void) +{ + 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; + m->barwin = XCreateWindow(dpy, root, m->wx, m->by, m->ww, bh, 0, DefaultDepth(dpy, screen), + CopyFromParent, DefaultVisual(dpy, screen), + CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa); + XDefineCursor(dpy, m->barwin, cursor[CurNormal]->cursor); + XMapRaised(dpy, m->barwin); + XSetClassHint(dpy, m->barwin, &ch); + } +} + +void +updatebarpos(Monitor *m) +{ + 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; +} + +void +updateclientlist(void) +{ + 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; + + 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); + 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) +{ + 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); +} + +void +updatesizehints(Client *c) +{ + 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; +} + +void +updatestatus(void) +{ + if (!gettextprop(root, XA_WM_NAME, stext, sizeof(stext))) + strcpy(stext, "dwm-"VERSION); + drawbar(selmon); +} + +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); +} + +void +updatewindowtype(Client *c) +{ + 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; +} + +void +updatewmhints(Client *c) +{ + 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); + } +} + +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); +} + +Client * +wintoclient(Window w) +{ + 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; +} + +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) +{ + 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; +} + +/* Startup Error handler to check if another window manager + * is already running. */ +int +xerrorstart(Display *dpy, XErrorEvent *ee) +{ + die("dwm: another window manager is already running"); + return -1; +} + +void +zoom(const Arg *arg) +{ + 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); +} + +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(); +#ifdef __OpenBSD__ + if (pledge("stdio rpath proc exec", NULL) == -1) + die("pledge"); +#endif /* __OpenBSD__ */ + scan(); + run(); + cleanup(); + XCloseDisplay(dpy); + return EXIT_SUCCESS; +} diff --git a/dwm/dwm.c.rej b/dwm/dwm.c.rej new file mode 100644 index 0000000..d5ffd8c --- /dev/null +++ b/dwm/dwm.c.rej @@ -0,0 +1,39 @@ +--- dwm.c ++++ dwm.c +@@ -1703,7 +1703,7 @@ textnw(const char *text, unsigned int len) { + + void + tile(Monitor *m) { +- unsigned int i, n, h, mw, my, ty; ++ unsigned int i, n, h, r, g = 0, mw, my, ty; + Client *c; + + for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); +@@ -1711,19 +1711,21 @@ tile(Monitor *m) { + return; + + if(n > m->nmaster) +- mw = m->nmaster ? m->ww * m->mfact : 0; ++ mw = m->nmaster ? (m->ww - (g = gappx)) * m->mfact : 0; + else + mw = m->ww; + for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if(i < m->nmaster) { +- h = (m->wh - my) / (MIN(n, m->nmaster) - i); ++ r = MIN(n, m->nmaster) - i; ++ h = (m->wh - my - gappx * (r - 1)) / r; + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); +- my += HEIGHT(c); ++ my += HEIGHT(c) + gappx; + } + else { +- h = (m->wh - ty) / (n - i); +- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); +- ty += HEIGHT(c); ++ r = n - i; ++ h = (m->wh - ty - gappx * (r - 1)) / r; ++ resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), 0); ++ ty += HEIGHT(c) + gappx; + } + } + diff --git a/dwm/dwm.o b/dwm/dwm.o index 21b824dfdb14e3ec3ea86c24d20840589a1367d9..39aae1cd9c73bb146c340e8200b3f16acab71250 100644 GIT binary patch delta 12586 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 T)nNRb(8zYmYWWEWoNf0%LEIDo delta 12518 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 c; c = nexttiled(c->next), n++); +@@ -1711,19 +1711,21 @@ tile(Monitor *m) { + return; + + if(n > m->nmaster) +- mw = m->nmaster ? m->ww * m->mfact : 0; ++ mw = m->nmaster ? (m->ww - (g = gappx)) * m->mfact : 0; + else + mw = m->ww; + for(i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if(i < m->nmaster) { +- h = (m->wh - my) / (MIN(n, m->nmaster) - i); ++ r = MIN(n, m->nmaster) - i; ++ h = (m->wh - my - gappx * (r - 1)) / r; + resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), False); +- my += HEIGHT(c); ++ my += HEIGHT(c) + gappx; + } + else { +- h = (m->wh - ty) / (n - i); +- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0); +- ty += HEIGHT(c); ++ r = n - i; ++ h = (m->wh - ty - gappx * (r - 1)) / r; ++ resize(c, m->wx + mw + g, m->wy + ty, m->ww - mw - g - (2*c->bw), h - (2*c->bw), 0); ++ ty += HEIGHT(c) + gappx; + } + } +