From 0f439a1c9613067908e7f6e81c6f382ef7bf1630 Mon Sep 17 00:00:00 2001 From: horhik Date: Wed, 7 Oct 2020 21:51:49 +0300 Subject: [PATCH] add alternativetags --- dwm-6.2/config.def.h | 2 + dwm-6.2/config.def.h.orig | 152 +++ dwm-6.2/config.def.h.rej | 18 + dwm-6.2/config.h | 2 + dwm-6.2/dwm | Bin 71360 -> 71464 bytes dwm-6.2/dwm.c | 21 +- dwm-6.2/dwm.c.orig | 2292 +++++++++++++++++++++++++++++++++++++ dwm-6.2/dwm.c.rej | 11 + dwm-6.2/dwm.o | Bin 61816 -> 62808 bytes 9 files changed, 2495 insertions(+), 3 deletions(-) create mode 100644 dwm-6.2/config.def.h.orig create mode 100644 dwm-6.2/config.def.h.rej create mode 100644 dwm-6.2/dwm.c.orig create mode 100644 dwm-6.2/dwm.c.rej diff --git a/dwm-6.2/config.def.h b/dwm-6.2/config.def.h index 2c56145..98088cb 100644 --- a/dwm-6.2/config.def.h +++ b/dwm-6.2/config.def.h @@ -34,6 +34,7 @@ static const char *const autostart[] = { /* tagging */ static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; +static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* launcher commands (They must be NULL terminated) */ static const char* surf[] = { "surf", "duckduckgo.com", NULL }; @@ -121,6 +122,7 @@ static Key keys[] = { /*SCRATCHPADS*/ { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, + { MODKEY, XK_n, togglealttag, {0} }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff --git a/dwm-6.2/config.def.h.orig b/dwm-6.2/config.def.h.orig new file mode 100644 index 0000000..2c56145 --- /dev/null +++ b/dwm-6.2/config.def.h.orig @@ -0,0 +1,152 @@ +/* See LICENSE file for copyright and license details. */ + +/* appearance */ +static const unsigned int borderpx = 3; /* border pixel of windows */ +static const unsigned int gappx = 10; /* 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 */ +static const char *fonts[] = { "Mononoki Nerd Font:size=10"}; +static const char dmenufont[] = "Mononoki Nerd Font:size=16"; +static const char col_gray1[] = "#282828"; +static const char col_gray2[] = "#928374"; +static const char col_gray3[] = "#d5c4a1"; +static const char col_gray4[] = "#ebdbb2"; +static const char col_cyan[] = "#d65d0e"; +static const char *colors[][3] = { + /* fg bg border */ + [SchemeNorm] = { col_gray3, col_gray1, col_gray2 }, + [SchemeSel] = { col_gray4, col_cyan, col_cyan }, +}; + +static const char *const autostart[] = { + "pulsemixer", "-k", NULL, + "firefox", NULL, + "variety", NULL, + "redshift", NULL, + "picom", "--experimental-backends", "--detect-rounded-corners", NULL, + "setxkbmap","us,ru,fi",",winkeys","grp:alt_shift_toggle", NULL, + "xrandr", "--output", "HDMI1", "--above", "eDP1", NULL, + "$HOME/.local/scripts/status/launch", NULL, + "pulseaudio","-k", NULL, + NULL /* terminate */ +}; + +/* tagging */ +static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; + +/* launcher commands (They must be NULL terminated) */ +static const char* surf[] = { "surf", "duckduckgo.com", NULL }; + +static const Launcher launchers[] = { + /* command name to display */ + { surf, "surf" }, +}; + + +static const Rule rules[] = { + /* xprop(1): + * WM_CLASS(STRING) = instance, class + * WM_NAME(STRING) = title + */ + /* class instance title tags mask isfloating monitor scratch key */ +{ "Gimp", NULL, NULL, 0, 1, -1, 0 }, +{ "firefox", NULL, NULL, 0 << 2, 0, -1, 0 }, +{ NULL, NULL, "scratchpad", 0, 1, -1, 's' }, +{ NULL, NULL, "sp_volume", 0, 1, -1, 'v' }, + +}; + +/* 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 Layout layouts[] = { + /* symbol arrange function */ + { "[]=", tile }, /* first entry is default */ + { "><>", NULL }, /* no layout function means floating behavior */ + { "[M]", monocle }, +}; + +/* key definitions */ +#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} }, + +/* helper for spawning shell commands in the pre dwm-5.0 fashion */ +#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } } + +/* commands ,*/ +static char dmenumon[2] = "0"; /* component of dmenucmd, manipulated in spawn() */ +static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, "-fn", dmenufont, "-nb", col_gray1, "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4, "-c", "-l", "20", NULL}; +static const char *termcmd[] = { "alacritty", NULL }; + +/*First arg only serves to match against key in rules*/ +static const char *scratchpadcmd[] = {"s", "alacritty", "-t", "scratchpad", NULL}; +static const char *sp_volume_control[] = {"v","alacritty", "-t", "sp_volume","-e", "pulsemixer", NULL}; + + +static Key keys[] = { + /* modifier key function argument */ + { MODKEY, XK_p, spawn, {.v = dmenucmd } }, + { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, + { MODKEY, XK_b, togglebar, {0} }, + { MODKEY, XK_j, focusstack, {.i = +1 } }, + { MODKEY, XK_k, focusstack, {.i = -1 } }, + { MODKEY, XK_i, incnmaster, {.i = +1 } }, + { MODKEY, XK_d, incnmaster, {.i = -1 } }, + { MODKEY, XK_h, setmfact, {.f = -0.05} }, + { MODKEY, XK_l, setmfact, {.f = +0.05} }, + { MODKEY, XK_Return, zoom, {0} }, + { MODKEY, XK_Tab, view, {0} }, + { MODKEY|ShiftMask, XK_c, killclient, {0} }, + { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, + { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, + { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, + { MODKEY, XK_space, setlayout, {0} }, + { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, + { MODKEY, 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 = -5 } }, + { MODKEY, XK_equal, setgaps, {.i = +5 } }, + { MODKEY|ShiftMask, XK_equal, setgaps, {.i = 0 } }, + /*SCRATCHPADS*/ + { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, + { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, + 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) + { MODKEY|ShiftMask, XK_q, quit, {0} }, +}; + +/* button definitions */ +/* click can be ClkTagBar, ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ +static Button buttons[] = { + /* click event mask button function argument */ + { 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, Button2, togglefloating, {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/dwm-6.2/config.def.h.rej b/dwm-6.2/config.def.h.rej new file mode 100644 index 0000000..8f3d02b --- /dev/null +++ b/dwm-6.2/config.def.h.rej @@ -0,0 +1,18 @@ +--- config.def.h ++++ config.def.h +@@ -20,6 +20,7 @@ static const char *colors[][3] = { + + /* tagging */ + static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; ++static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; + + static const Rule rules[] = { + /* xprop(1): +@@ -84,6 +85,7 @@ static Key keys[] = { + { MODKEY, XK_period, focusmon, {.i = +1 } }, + { MODKEY|ShiftMask, XK_comma, tagmon, {.i = -1 } }, + { MODKEY|ShiftMask, XK_period, tagmon, {.i = +1 } }, ++ { MODKEY, XK_n, togglealttag, {0} }, + TAGKEYS( XK_1, 0) + TAGKEYS( XK_2, 1) + TAGKEYS( XK_3, 2) diff --git a/dwm-6.2/config.h b/dwm-6.2/config.h index 2c56145..98088cb 100644 --- a/dwm-6.2/config.h +++ b/dwm-6.2/config.h @@ -34,6 +34,7 @@ static const char *const autostart[] = { /* tagging */ static const char *tags[] = { "ﳎ ", " ", " ", " ", "", "", " ", " ", "龎 " }; +static const char *tagsalt[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; /* launcher commands (They must be NULL terminated) */ static const char* surf[] = { "surf", "duckduckgo.com", NULL }; @@ -121,6 +122,7 @@ static Key keys[] = { /*SCRATCHPADS*/ { MODKEY, XK_u, togglescratch, {.v = scratchpadcmd } }, { MODKEY|ShiftMask, XK_m, togglescratch, {.v = sp_volume_control } }, + { MODKEY, XK_n, togglealttag, {0} }, TAGKEYS( XK_1, 0) TAGKEYS( XK_2, 1) TAGKEYS( XK_3, 2) diff --git a/dwm-6.2/dwm b/dwm-6.2/dwm index 366f37633e8416675be52604fd92f1a86d11dd6e..a0f5596334f82f10bfdbcfbc75fc9f50241f4a0d 100755 GIT binary patch delta 22020 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 delta 21204 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

Z*(#xT$W)fKODJSsj*5iRN91u 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%0APO2}}nx@)h*8+%Ua6F9T zi7G8kBgr?-j#-?Y$k|hz&Eo0B(=v{q<+wO8ui`lU-68t0 z+XcvND(;Yu%wV{*N);0Q1yI@qt9bRoI9|#PiLd)@e1AF3@hvk|#YbHKBFERvQUP&< zyUy*$Gy7OiY&^pqo;JE2c6)*lHeejvo22`cW8#24COoS4cpG@Yjc ze4t75I4%yJ*<61S$HiCq<2hc)adCuh&hd{puAc32{eX)V_N?WEcqz!^_(tF|eXqW& z0*g7mgDj{tJLs=>)Akb|^Dp7-F^*U9Er<^{shs0ua#h7UTwmdMzXdA5Ze|eu569o( zxbRl4MZNNNNORVz8E|jM9s>yK&{>`#o#Tx;-t8?FARLe8`1c$i!|@&*kIGX4i>%5M z+@UE8X&SX-w?2p_^9*7qv8wvgaE^;Dirx5to4|2#1oq+uWN}=)C2!z%=#PD9#g6m0 z=P6X5wr&9@#A~-WSFPZ;Hp*c4TyIcBge&Cl6t@nk|aM)@V`GI`J+JkG$B{+;Lr1LR@^4sDTi zJs}6Ec1X*6K7nIcUTGX<;#M=A5_11B{gEUsx15I2*SNl-8J^YLhaY*% z4(C2RXL*fe!4q>}5PlFvTfg)pm3)osv?0Y$%yLJnBPX!1KMRMma2g92(2&GG4Z!!Z zRBtm2;n`Dj;BnYBVSCm7sk?Jb=Ozp9u<$VpF_oT~<;E;*!@{mC>`#_HGY6*CQ@#A0 zdl|^ROeY7C3-bu!J1qQ!gZ^nwSS~9kg{@f8j_0V z0r(+0O{3ljC$kVg9{3}K%>1K4H2oPFZN1AWe{a2wz}X+})9hCVSpG9Cyvo8V7XHCP z1Cd|QSsVQ#Qtrv(16i0s!@&7Q>hC{CMLuOo=?f3y@xmA1KvNq#>3j&>gdEhnC4Byh zGs#y>=Qy)^mg{U@sn*~rZ`t!q=Q<0knI`?E3~H^gx2kf7?_M(Tahv5p7Ph8gNxXZc zTx;y)Svz;iQQo^0Z#hhdpK27EWNj$- zmNykS8_JPBVsRI8a?x=L2dr0J5OQ0Qm#-XIM=a`5CyILb%AM+ndx6*!MQfonts->h / 9; int boxw = drw->fonts->h / 6 + 2; unsigned int i, occ = 0, urg = 0; @@ -777,8 +779,9 @@ drawbar(Monitor *m) x = 0; for (i = 0; i < LENGTH(tags); i++) { w = TEXTW(tags[i]); + wdelta = selmon->alttag ? abs(TEXTW(tags[i]) - TEXTW(tagsalt[i])) / 2 : 0; 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); + drw_text(drw, x, 0, w, bh, wdelta + lrpad / 2, (selmon->alttag ? tagsalt[i] : 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, @@ -798,8 +801,12 @@ drawbar(Monitor *m) if ((w = m->ww - tw - x) > bh) { if (m->sel) { + /* fix overflow when window name is bigger than window width */ + int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x; + /* make sure name will not overlap on tags even when it is very long */ + mid = mid >= lrpad / 2 ? mid : lrpad / 2; drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); - drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0); + drw_text(drw, x, 0, w, bh, mid, m->sel->name, 0); if (m->sel->isfloating) drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0); } else { @@ -1687,6 +1694,14 @@ seturgent(Client *c, int urg) XFree(wmh); } +void +togglealttag() +{ + selmon->alttag = !selmon->alttag; + drawbar(selmon); +} + + void showhide(Client *c) { diff --git a/dwm-6.2/dwm.c.orig b/dwm-6.2/dwm.c.orig new file mode 100644 index 0000000..42e2cdc --- /dev/null +++ b/dwm-6.2/dwm.c.orig @@ -0,0 +1,2292 @@ +/* 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; + int bw, oldbw; + unsigned int tags; + int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; + char scratchkey; + 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 gappx; /* gaps between windows */ + 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; + const char scratchkey; +} Rule; + +typedef struct { + const char** command; + const char* name; +} Launcher; + + +/* 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 *); +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 setgaps(const Arg *arg); +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 sigchld(int unused); +static void spawn(const Arg *arg); +static void spawnscratch(const Arg *arg); +static void tag(const Arg *arg); +static void tagmon(const Arg *arg); +static void tile(Monitor *); +static void togglebar(const Arg *arg); +static void togglefloating(const Arg *arg); +static void togglescratch(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); +static void autostart_exec(void); + +/* 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, blw = 0; /* bar geometry */ +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]; }; + +/* dwm will keep pid's of processes from autostart array and kill them at quit */ +static pid_t *autostart_pids; +static size_t autostart_len; + +/* execute command from autostart array */ +static void +autostart_exec() { + const char *const *p; + size_t i = 0; + + /* count entries */ + for (p = autostart; *p; autostart_len++, p++) + while (*++p); + + autostart_pids = malloc(autostart_len * sizeof(pid_t)); + for (p = autostart; *p; i++, p++) { + if ((autostart_pids[i] = fork()) == 0) { + setsid(); + execvp(*p, (char *const *)p); + fprintf(stderr, "dwm: execvp %s\n", *p); + perror(" failed"); + _exit(EXIT_FAILURE); + } + /* skip arguments */ + while (*++p); + } +} + +/* 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; + c->scratchkey = 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; + c->scratchkey = r->scratchkey; + 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) { + /* 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; + goto execute_handler; + } else if (ev->x < x + blw) { + click = ClkLtSymbol; + goto execute_handler; + } + + x += blw; + + for(i = 0; i < LENGTH(launchers); i++) { + x += TEXTW(launchers[i].name); + + if (ev->x < x) { + Arg a; + a.v = launchers[i].command; + spawn(&a); + return; + } + } + + if (ev->x > selmon->ww - TEXTW(stext)) + click = ClkStatusText; + else + click = ClkWinTitle; + } else if ((c = wintoclient(ev->window))) { + focus(c); + restack(selmon); + XAllowEvents(dpy, ReplayPointer, CurrentTime); + click = ClkClientWin; + } + + execute_handler: + + 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]); + 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 */)); + } 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; + 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) { + 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->gappx = gappx; + 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; + + /* 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 = blw = TEXTW(m->ltsymbol); + drw_setscheme(drw, scheme[SchemeNorm]); + x = drw_text(drw, x, 0, w, bh, lrpad / 2, m->ltsymbol, 0); + + for (i = 0; i < LENGTH(launchers); i++) + { + w = TEXTW(launchers[i].name); + drw_text(drw, x, 0, w, bh, lrpad / 2, launchers[i].name, urg & 1 << i); + x += w; + } + + if ((w = m->ww - tw - x) > bh) { + if (m->sel) { + /* fix overflow when window name is bigger than window width */ + int mid = (m->ww - (int)TEXTW(m->sel->name)) / 2 - x; + /* make sure name will not overlap on tags even when it is very long */ + mid = mid >= lrpad / 2 ? mid : lrpad / 2; + drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]); + drw_text(drw, x, 0, w, bh, mid, 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) + 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; + unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask|LockMask }; + KeyCode code; + + XUngrabKey(dpy, AnyKey, AnyModifier, root); + for (i = 0; i < LENGTH(keys); i++) + if ((code = XKeysymToKeycode(dpy, keys[i].keysym))) + for (j = 0; j < LENGTH(modifiers); j++) + XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, + True, GrabModeAsync, GrabModeAsync); + } +} + +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->mx + c->mon->mw) + c->x = c->mon->mx + c->mon->mw - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) + c->y = c->mon->my + c->mon->mh - HEIGHT(c); + c->x = MAX(c->x, c->mon->mx); + /* only fix client y-offset, if the client center might cover the bar */ + c->y = MAX(c->y, ((c->mon->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) + && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + c->bw = borderpx; + + wc.border_width = c->bw; + if (((nexttiled(c->mon->clients) == c && !nexttiled(c->next)) + || &monocle == c->mon->lt[c->mon->sellt]->arrange)) + { + c->w = wc.width += c->bw * 2; + c->h = wc.height += c->bw * 2; + wc.border_width = 0; + } + 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)) + return; + if (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; + 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: + updatesizehints(c); + 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) +{ + size_t i; + + /* kill child processes */ + for (i = 0; i < autostart_len; i++) { + if (0 < autostart_pids[i]) { + kill(autostart_pids[i], SIGTERM); + waitpid(autostart_pids[i], NULL, 0); + } + } + + 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; + 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; + } else if (!fullscreen && c->isfullscreen){ + XChangeProperty(dpy, c->win, netatom[NetWMState], XA_ATOM, 32, + PropModeReplace, (unsigned char*)0, 0); + c->isfullscreen = 0; + } +} + +void +setgaps(const Arg *arg) +{ + if ((arg->i == 0) || (selmon->gappx + arg->i < 0)) + selmon->gappx = 0; + else + selmon->gappx += arg->i; + arrange(selmon); +} + +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; + + /* clean up any zombies immediately */ + sigchld(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) + 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 +sigchld(int unused) +{ + pid_t pid; + + if (signal(SIGCHLD, sigchld) == SIG_ERR) + die("can't install SIGCHLD handler:"); + while (0 < (pid = waitpid(-1, NULL, WNOHANG))) { + pid_t *p, *lim; + + if (!(p = autostart_pids)) + continue; + lim = &p[autostart_len]; + + for (; p < lim; p++) { + if (*p == pid) { + *p = -1; + break; + } + } + + } +} + +void +spawn(const Arg *arg) +{ + if (arg->v == dmenucmd) + dmenumon[0] = '0' + selmon->num; + if (fork() == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(((char **)arg->v)[0], (char **)arg->v); + fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[0]); + perror(" failed"); + exit(EXIT_SUCCESS); + } +} + +void spawnscratch(const Arg *arg) +{ + if (fork() == 0) { + if (dpy) + close(ConnectionNumber(dpy)); + setsid(); + execvp(((char **)arg->v)[1], ((char **)arg->v)+1); + fprintf(stderr, "dwm: execvp %s", ((char **)arg->v)[1]); + perror(" failed"); + exit(EXIT_SUCCESS); + } +} + + +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, mw, my, ty, ns; + Client *c; + + for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); + if (n == 0) + return; + if(n == 1){ + c = nexttiled(m->clients); + resize(c, m->wx, m->wy, m->ww - 2 * c->bw, m->wh - 2 * c->bw, 0); + return; + } + + if (n > m->nmaster){ + mw = m->nmaster ? m->ww * m->mfact : 0; + ns = m->nmaster > 0 ? 2 : 1; + } + else{ + mw = m->ww - m->gappx; + ns = 1; + } + for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++) + if (i < m->nmaster) { + h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; + resize(c, m->wx + m->gappx, m->wy + my, mw - 2*c->bw - m->gappx*(5-ns)/2, h - 2*c->bw, 0); + if(my + HEIGHT(c) + m->gappx < m->wh) + my += HEIGHT(c) + m->gappx; + } else { + h = (m->wh - ty) / (n - i) - m->gappx; + resize(c, m->wx + mw + m->gappx/ns, m->wy + ty, m->ww - mw - (2*c->bw) - m->gappx*(5-ns)/2, h - 2*c->bw, 0); + if(ty + HEIGHT(c) + m->gappx < m->wh) + ty += HEIGHT(c) + m->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; + 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 +togglescratch(const Arg *arg) +{ + Client *c; + unsigned int found = 0; + + for (c = selmon->clients; c && !(found = c->scratchkey == ((char**)arg->v)[0][0]); c = c->next); + if (found) { + c->tags = ISVISIBLE(c) ? 0 : selmon->tagset[selmon->seltags]; + focus(NULL); + arrange(selmon); + + if (ISVISIBLE(c)) { + focus(c); + restack(selmon); + } + + } else{ + spawnscratch(arg); + } +} + +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); + 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() +{ + 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; + if (n <= nn) { /* new monitors available */ + for (i = 0; i < (nn - n); 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); + } + } else { /* less monitors available nn < n */ + 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); +} + +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 + || (selmon->sel && selmon->sel->isfloating)) + return; + if (c == nexttiled(selmon->clients)) + if (!c || !(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(); + autostart_exec(); + 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-6.2/dwm.c.rej b/dwm-6.2/dwm.c.rej new file mode 100644 index 0000000..f44b1d6 --- /dev/null +++ b/dwm-6.2/dwm.c.rej @@ -0,0 +1,11 @@ +--- dwm.c ++++ dwm.c +@@ -697,7 +699,7 @@ dirtomon(int dir) + void + drawbar(Monitor *m) + { +- int x, w, sw = 0; ++ int x, w, wdelta, sw = 0; + int boxs = drw->fonts->h / 9; + int boxw = drw->fonts->h / 6 + 2; + unsigned int i, occ = 0, urg = 0; diff --git a/dwm-6.2/dwm.o b/dwm-6.2/dwm.o index 18f9057e5cb86f7e324fb3c4db674aa20c0eace7..bf792680fb86bd57cc2e8e231a6526fc33b34441 100644 GIT binary patch delta 20132 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 b>J*ld?II6@_hQem&OI!VsB|m&X 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