From 5a60611178537a45c02c0e845c8cb8747b8d1602 Mon Sep 17 00:00:00 2001 From: memL0rz Date: Wed, 18 Sep 2024 19:58:48 +0000 Subject: [PATCH] added colors to bar patch --- config.h | 133 ++ drw.o | Bin 0 -> 11200 bytes dwm | Bin 0 -> 83576 bytes dwm.c | 120 +- dwm.c.orig | 2165 +++++++++++++++++++++++++++++++++ dwm.o | Bin 0 -> 71352 bytes patches/dwm-status2d-6.3.diff | 166 +++ util.o | Bin 0 -> 2296 bytes 8 files changed, 2578 insertions(+), 6 deletions(-) create mode 100644 config.h create mode 100644 drw.o create mode 100755 dwm create mode 100644 dwm.c.orig create mode 100644 dwm.o create mode 100644 patches/dwm-status2d-6.3.diff create mode 100644 util.o diff --git a/config.h b/config.h new file mode 100644 index 0000000..c5568bc --- /dev/null +++ b/config.h @@ -0,0 +1,133 @@ +static const unsigned int borderpx = 3; /* border pixel of windows */ +static const unsigned int snap = 32; /* snap pixel */ +static const unsigned int gappih = 20; /* horiz inner gap between windows */ +static const unsigned int gappiv = 20; /* vert inner gap between windows */ +static const unsigned int gappoh = 20; /* horiz outer gap between windows and screen edge */ +static const unsigned int gappov = 20; /* vert outer gap between windows and screen edge */ +static int smartgaps = 0; /* 1 means no outer gap when there is only one window */ +static const int showbar = 1; /* 0 means no bar */ +static const int topbar = 1; /* 0 means bottom bar */ +static const char *fonts[] = { "monospace:size=10" }; +static const char dmenufont[] = "monospace:size=10"; +static const char col_gray1[] = "#d65d0e"; +static const char col_gray2[] = "#444444"; +static const char col_gray3[] = "#d65d0e"; +static const char col_gray4[] = "#eeeeee"; +static const char col_cyan[] = "#282828"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +/* tagging */ +static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + +static const Rule rules[] = { + { "Gimp", NULL, NULL, 0, 1, -1 }, +}; + +/* layout(s) */ +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 */ +static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */ + +#define FORCE_VSPLIT 1 /* nrowgrid layout: force two clients to always split vertically */ +#include "vanitygaps.c" +#include + +static const Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "[M]", monocle }, + { "[@]", spiral }, + { "[\\]", dwindle }, + { "H[]", deck }, + { "TTT", bstack }, + { "===", bstackhoriz }, + { "HHH", grid }, + { "###", nrowgrid }, + { "---", horizgrid }, + { ":::", gaplessgrid }, + { "|M|", centeredmaster }, + { ">M>", centeredfloatingmaster }, + { "><>", NULL }, /* no layout function means floating behavior */ + { NULL, NULL }, +}; + +#define MODKEY Mod4Mask +#define TAGKEYS(KEY,TAG) \ + { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ + { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \ + { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} }, + +// arrow keymaps +#define XK_Left 0xff51 +#define XK_Right 0xff53 +#define XK_Up 0xff56 +#define XK_Down 0xff54 + +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *termcmd[] = { "st", NULL }; +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, NULL }; +static const char *upvol[] = { "/usr/bin/wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%+", NULL }; +static const char *downvol[] = { "/usr/bin/wpctl", "set-volume", "@DEFAULT_AUDIO_SINK@", "5%-", NULL }; +static const char *mutevol[] = { "/usr/bin/wpctl", "set-mute", "@DEFAULT_AUDIO_SINK@", "toggle", NULL }; + +static const Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_space, spawn, {.v = dmenucmd } }, + { MODKEY, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_Right, focusstack, {.i = +1 } }, + { MODKEY, XK_Left, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY|ShiftMask, XK_Left, setmfact, {.f = -0.05} }, + { MODKEY|ShiftMask, XK_Right, setmfact, {.f = +0.05} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY, XK_q, killclient, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, XK_0, view, {.ui = ~0 } }, + { MODKEY|ShiftMask, XK_0, tag, {.ui = ~0 } }, + { MODKEY, XK_comma, focusmon, {.i = -1 } }, + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, + { MODKEY, XK_minus, setgaps, {.i = -1 } }, + { MODKEY, XK_equal, setgaps, {.i = +1 } }, + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) + TAGKEYS( XK_4, 3) + TAGKEYS( XK_5, 4) + TAGKEYS( XK_6, 5) + TAGKEYS( XK_7, 6) + TAGKEYS( XK_8, 7) + TAGKEYS( XK_9, 8) + + // Media Keys // + { 0, XF86XK_AudioLowerVolume, spawn, {.v = downvol } }, + { 0, XF86XK_AudioMute, spawn, {.v = mutevol } }, + { 0, XF86XK_AudioRaiseVolume, spawn, {.v = upvol } }, + +}; + +static const Button buttons[] = { + { ClkLtSymbol, 0, Button1, setlayout, {0} }, + { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, + { ClkWinTitle, 0, Button2, zoom, {0} }, + { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, + { ClkClientWin, MODKEY, Button1, movemouse, {0} }, + { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkTagBar, 0, Button1, view, {0} }, + { ClkTagBar, 0, Button3, toggleview, {0} }, + { ClkTagBar, MODKEY, Button1, tag, {0} }, + { ClkTagBar, MODKEY, Button3, toggletag, {0} }, +}; + diff --git a/drw.o b/drw.o new file mode 100644 index 0000000000000000000000000000000000000000..c762b1f7baedf4b3bd10b4e77d53836a4daa08a1 GIT binary patch literal 11200 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 literal 0 HcmV?d00001 diff --git a/dwm b/dwm new file mode 100755 index 0000000000000000000000000000000000000000..f6606275d720d63c1fa3b8e3e6bd2923fe339e0b GIT binary patch literal 83576 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 literal 0 HcmV?d00001 diff --git a/dwm.c b/dwm.c index 2a623f7..ef2dee8 100644 --- a/dwm.c +++ b/dwm.c @@ -168,6 +168,7 @@ static void detachstack(Client *c); static Monitor *dirtomon(int dir); static void drawbar(Monitor *m); static void drawbars(void); +static int drawstatusbar(Monitor *m, int bh, char* text); static void enternotify(XEvent *e); static void expose(XEvent *e); static void focus(Client *c); @@ -241,7 +242,7 @@ static void zoom(const Arg *arg); /* variables */ static const char broken[] = "broken"; -static char stext[256]; +static char stext[1024]; static int screen; static int sw, sh; /* X display screen geometry width, height */ static int bh; /* bar height */ @@ -491,7 +492,7 @@ cleanup(void) cleanupmon(mons); for (i = 0; i < CurLast; i++) drw_cur_free(drw, cursor[i]); - for (i = 0; i < LENGTH(colors); i++) + for (i = 0; i < LENGTH(colors) + 1; i++) free(scheme[i]); free(scheme); XDestroyWindow(dpy, wmcheckwin); @@ -704,6 +705,114 @@ dirtomon(int dir) return m; } +int +drawstatusbar(Monitor *m, int bh, char* stext) { + int ret, i, w, x, len; + short isCode = 0; + char *text; + char *p; + + len = strlen(stext) + 1 ; + if (!(text = (char*) malloc(sizeof(char)*len))) + die("malloc"); + p = text; + memcpy(text, stext, len); + + /* compute width of the status text */ + w = 0; + i = -1; + while (text[++i]) { + if (text[i] == '^') { + if (!isCode) { + isCode = 1; + text[i] = '\0'; + w += TEXTW(text) - lrpad; + text[i] = '^'; + if (text[++i] == 'f') + w += atoi(text + ++i); + } else { + isCode = 0; + text = text + i + 1; + i = -1; + } + } + } + if (!isCode) + w += TEXTW(text) - lrpad; + else + isCode = 0; + text = p; + + w += 2; /* 1px padding on both sides */ + ret = x = m->ww - w; + + drw_setscheme(drw, scheme[LENGTH(colors)]); + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + drw_rect(drw, x, 0, w, bh, 1, 1); + x++; + + /* process status text */ + i = -1; + while (text[++i]) { + if (text[i] == '^' && !isCode) { + isCode = 1; + + text[i] = '\0'; + w = TEXTW(text) - lrpad; + drw_text(drw, x, 0, w, bh, 0, text, 0); + + x += w; + + /* process code */ + while (text[++i] != '^') { + if (text[i] == 'c') { + char buf[8]; + memcpy(buf, (char*)text+i+1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColFg], buf); + i += 7; + } else if (text[i] == 'b') { + char buf[8]; + memcpy(buf, (char*)text+i+1, 7); + buf[7] = '\0'; + drw_clr_create(drw, &drw->scheme[ColBg], buf); + i += 7; + } else if (text[i] == 'd') { + drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; + drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; + } else if (text[i] == 'r') { + int rx = atoi(text + ++i); + while (text[++i] != ','); + int ry = atoi(text + ++i); + while (text[++i] != ','); + int rw = atoi(text + ++i); + while (text[++i] != ','); + int rh = atoi(text + ++i); + + drw_rect(drw, rx + x, ry, rw, rh, 1, 0); + } else if (text[i] == 'f') { + x += atoi(text + ++i); + } + } + + text = text + i + 1; + i=-1; + isCode = 0; + } + } + + if (!isCode) { + w = TEXTW(text) - lrpad; + drw_text(drw, x, 0, w, bh, 0, text, 0); + } + + drw_setscheme(drw, scheme[SchemeNorm]); + free(p); + + return ret; +} + void drawbar(Monitor *m) { @@ -718,9 +827,7 @@ drawbar(Monitor *m) /* 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); + tw = m->ww - drawstatusbar(m, bh, stext); } for (c = m->clients; c; c = c->next) { @@ -1612,7 +1719,8 @@ setup(void) cursor[CurResize] = drw_cur_create(drw, XC_sizing); cursor[CurMove] = drw_cur_create(drw, XC_fleur); /* init appearance */ - scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); + scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); + scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); for (i = 0; i < LENGTH(colors); i++) scheme[i] = drw_scm_create(drw, colors[i], 3); /* init bars */ diff --git a/dwm.c.orig b/dwm.c.orig new file mode 100644 index 0000000..2a623f7 --- /dev/null +++ b/dwm.c.orig @@ -0,0 +1,2165 @@ +/* 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; + 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; +} 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 */ + 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; +} 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 setcfact(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 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->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) +{ + 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; + 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); + } + + 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); +} + +void +setcfact(const Arg *arg) { + float f; + Client *c; + + 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) +{ + 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 +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.o b/dwm.o new file mode 100644 index 0000000000000000000000000000000000000000..a5101ae4b336117f4f6cf07b8034692664743fe0 GIT binary patch literal 71352 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 - w; ++ ++ drw_setscheme(drw, scheme[LENGTH(colors)]); ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ drw_rect(drw, x, 0, w, bh, 1, 1); ++ x++; ++ ++ /* process status text */ ++ i = -1; ++ while (text[++i]) { ++ if (text[i] == '^' && !isCode) { ++ isCode = 1; ++ ++ text[i] = '\0'; ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ ++ x += w; ++ ++ /* process code */ ++ while (text[++i] != '^') { ++ if (text[i] == 'c') { ++ char buf[8]; ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ drw_clr_create(drw, &drw->scheme[ColFg], buf); ++ i += 7; ++ } else if (text[i] == 'b') { ++ char buf[8]; ++ memcpy(buf, (char*)text+i+1, 7); ++ buf[7] = '\0'; ++ drw_clr_create(drw, &drw->scheme[ColBg], buf); ++ i += 7; ++ } else if (text[i] == 'd') { ++ drw->scheme[ColFg] = scheme[SchemeNorm][ColFg]; ++ drw->scheme[ColBg] = scheme[SchemeNorm][ColBg]; ++ } else if (text[i] == 'r') { ++ int rx = atoi(text + ++i); ++ while (text[++i] != ','); ++ int ry = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rw = atoi(text + ++i); ++ while (text[++i] != ','); ++ int rh = atoi(text + ++i); ++ ++ drw_rect(drw, rx + x, ry, rw, rh, 1, 0); ++ } else if (text[i] == 'f') { ++ x += atoi(text + ++i); ++ } ++ } ++ ++ text = text + i + 1; ++ i=-1; ++ isCode = 0; ++ } ++ } ++ ++ if (!isCode) { ++ w = TEXTW(text) - lrpad; ++ drw_text(drw, x, 0, w, bh, 0, text, 0); ++ } ++ ++ drw_setscheme(drw, scheme[SchemeNorm]); ++ free(p); ++ ++ return ret; ++} ++ + void + drawbar(Monitor *m) + { +@@ -707,9 +816,7 @@ drawbar(Monitor *m) + + /* 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); ++ tw = m->ww - drawstatusbar(m, bh, stext); + } + + for (c = m->clients; c; c = c->next) { +@@ -1571,7 +1678,8 @@ setup(void) + cursor[CurResize] = drw_cur_create(drw, XC_sizing); + cursor[CurMove] = drw_cur_create(drw, XC_fleur); + /* init appearance */ +- scheme = ecalloc(LENGTH(colors), sizeof(Clr *)); ++ scheme = ecalloc(LENGTH(colors) + 1, sizeof(Clr *)); ++ scheme[LENGTH(colors)] = drw_scm_create(drw, colors[0], 3); + for (i = 0; i < LENGTH(colors); i++) + scheme[i] = drw_scm_create(drw, colors[i], 3); + /* init bars */ diff --git a/util.o b/util.o new file mode 100644 index 0000000000000000000000000000000000000000..1805f34e35efce88e7dd77f120b53c74a2696930 GIT binary patch literal 2296 zcmbtVO>7%g5FR_BF(HZFl0#8|?qLhD)ULcqfG7cE6sOr%77Bl&aB&@bokVeLvwlWS zi$oCNU`0kbaHEGDdgOo*$EdN?14vvrb1B@A;LxfZDnJeMy?w7)t=6hkMtYfHOn-_UEq*I~`%pI-PgT ztkcPxPQH^fm-B30-sy?CWIAVFNv88=Bboln+-7<*ecjxX`i8kL^*83XQh#suq&_fz zW?go62hUEj;c&r8yLS^UI^DdPayq{_-5v7|{N301Fa3}+Qwg|CJ?(UJW`>dRj6#gx z!P%Z?_DitDIj3_QT_Ikn(h4;+$n{wU zd8K$^`^z zSRBcVW2w*Mm&Wd>*sO{@2hFkf#}W#ORwyw@caNf?0}&JER|^c8N*rZJ}KGO%E?}KL7uyivLH+}Y`Zz9;<|i;HEZ~pu()hT-(I;kI z6$kDjLHUxYuEw3s=cX}7YMyV3VrfJ9tF@NZ@alYGVvAEz&|NE3yyB*-JNtjy;B;&S z&Ne7n<(yIbq+=nMCOClo%W8tsJ@v5Yb9st!