tAdd customize - dwm - [fork] customized build of dwm, the dynamic window manag… | |
git clone git://src.adamsgaard.dk/dwm | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 7c099bd74e3f1691da859a1277a501ebe4d53fd6 | |
parent f09418bbb6651ab4c299cfefbe1d18de401f630e | |
Author: Anders Damsgaard <[email protected]> | |
Date: Sat, 23 May 2020 20:35:34 +0200 | |
Add customize | |
Diffstat: | |
M LICENSE | 1 + | |
A config.h | 241 +++++++++++++++++++++++++++++… | |
M config.mk | 2 +- | |
M dwm.c | 185 +++++++++++++++++++++++++----… | |
4 files changed, 396 insertions(+), 33 deletions(-) | |
--- | |
diff --git a/LICENSE b/LICENSE | |
t@@ -17,6 +17,7 @@ MIT/X Consortium License | |
© 2015-2016 Quentin Rameau <[email protected]> | |
© 2015-2016 Eric Pruitt <[email protected]> | |
© 2016-2017 Markus Teich <[email protected]> | |
+© 2019-2020 Anders Damsgaard <[email protected]> | |
Permission is hereby granted, free of charge, to any person obtaining a | |
copy of this software and associated documentation files (the "Software"), | |
diff --git a/config.h b/config.h | |
t@@ -0,0 +1,241 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+ | |
+/* appearance */ | |
+static const unsigned int borderpx = 0; /* border pixel of windows */ | |
+static const unsigned int gappx = 0; /* gaps 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[] = { "dina:size=9:antialias=false" }; | |
+static const char col_gray1[] = "#1d1f21"; | |
+static const char col_gray2[] = "#444444"; | |
+static const char col_gray3[] = "#c5c8c6"; | |
+static const char col_gray4[] = "#1d1f21"; | |
+static const char col_cyan[] = "#8abeb7"; | |
+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 char *tags[] = { "一", "二", "三", "四", "五", "六", "�… | |
+ | |
+ | |
+/* floatpos: | |
+ * 1--2--3 | |
+ * 4--5--6 | |
+ * 7--8--9 | |
+ * 0: disabled */ | |
+static const Rule rules[] = { | |
+ /* xprop(1): | |
+ * WM_CLASS(STRING) = instance, class | |
+ * WM_NAME(STRING) = title | |
+ */ | |
+ /* class instance title tags floatpos isfloating … | |
+ { "Tor Browser", NULL, NULL, 0, 5, 1, … | |
+ { "tabbed", NULL, NULL, 1<<1, 0, 0, … | |
+ { "Firefox", NULL, NULL, 1<<1, 0, 0, … | |
+ { "Signal", NULL, NULL, 1<<8, 0, 0, … | |
+ { NULL, NULL, "video", ~0, 9, 1, … | |
+ { NULL, NULL, "topleft", 0, 1, 1, … | |
+ { NULL, NULL, "topcenter", 0, 2, 1, … | |
+ { NULL, NULL, "topright", 0, 3, 1, … | |
+ { NULL, NULL, "midleft", 0, 4, 1, … | |
+ { NULL, NULL, "midcenter", 0, 5, 1, … | |
+ { NULL, NULL, "midright", 0, 6, 1, … | |
+ { NULL, NULL, "botleft", 0, 7, 1, … | |
+ { NULL, NULL, "botcenter", 0, 8, 1, … | |
+ { NULL, NULL, "botright", 0, 9, 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 = 0; /* 1 means respect size hints in tiled re… | |
+ | |
+static const Layout layouts[] = { | |
+ /* symbol arrange function */ | |
+ { "", tile }, /* first entry is default */ | |
+ { "F", NULL }, /* no layout function means floating behavior */ | |
+ { "M", monocle }, | |
+}; | |
+ | |
+/* key definitions */ | |
+#define MODKEY Mod1Mask | |
+#define MODALTKEY Mod4Mask | |
+#define TAGKEYS(KEY,TAG) \ | |
+ { MODKEY, KEY, view, {.ui = 1 << … | |
+ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << … | |
+ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << … | |
+ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << … | |
+ | |
+ | |
+static char dmenumon[2] = "0"; | |
+ | |
+#define HOME "/home/ad" | |
+#define TERMINAL "st" | |
+#define EDITOR "vi" | |
+#define BROWSER "firefox.sh" | |
+ | |
+/* helper for spawning shell commands in the pre dwm-5.0 fashion */ | |
+#define TERMCMD(...) {TERMINAL, "-e", __VA_ARGS__, NULL} | |
+#define DUPLEXCMD(cmd) {TERMINAL, "-e", "tmux", "new-session", cmd, NULL} | |
+#define DUPLEXATTACHCMD(name, cmd) {TERMINAL, "-e", "tmux", "new-session", "-A… | |
+ | |
+/* commands */ | |
+static const char *termcmd[] = TERMCMD("ksh", "-l"); | |
+static const char *termplexcmd[] = TERMCMD("tmux"); | |
+ | |
+static const char *dmenucmd[] = {"dmenu_run", NULL}; | |
+static const char *searchcmd[] = {"search", NULL}; | |
+static const char *articlesearchcmd[] = {"articlesearch", NULL}; | |
+static const char *jabbrevcmd[] = {"jabbrev", "-c", NULL}; | |
+static const char *unicodecmd[] = {"unicodepick", NULL}; | |
+static const char *definecmd[] = {"define", "--gui", NULL}; | |
+static const char *passcmd[] = {"passmenu", "-t", "-n", NULL}; | |
+static const char *passemailcmd[] = {"passmenu", "-t", "-u", "anders@adam… | |
+static const char *displaycmd[] = {"displayselect", NULL}; | |
+static const char *torrentcmd[] = {"t-daemon-toggle", NULL}; | |
+static const char *mountcmd[] = {"dmenumount", NULL}; | |
+static const char *umountcmd[] = {"dmenuumount", NULL}; | |
+static const char *contactscmd[] = {"contactmenu", NULL}; | |
+static const char *textcmd[] = {"text.sh", "-i", NULL}; | |
+static const char *videocmd[] = {"videotoggle", NULL}; | |
+static const char *screenrecordcmd[] = {"screenrecord", NULL}; | |
+ | |
+static const char *plumbcmd[] = {"clipplumb", NULL}; | |
+static const char *plumb2cmd[] = {"clipplumb", "-c", NULL}; | |
+static const char *showclipcmd[] = {"showclip", NULL}; | |
+static const char *xlockcmd[] = {"slock", NULL}; | |
+static const char *printscreencmd[] = {"maimfull", NULL}; | |
+static const char *printscreenicmd[] = {"maimpick", NULL}; | |
+static const char *keyboardlayoutcmd[] = {"keyboard-layout-switch.sh", NULL}; | |
+ | |
+static const char *fuzzylaunchcmd[] = TERMCMD("fuzzylaunch"); | |
+static const char *journalcmd[] = TERMCMD("tmux-journal.sh"); | |
+static const char *browsercmd[] = {BROWSER, NULL}; | |
+static const char *torbrowsercmd[] = {"tor-browser", NULL}; | |
+static const char *todocmd[] = DUPLEXATTACHCMD("todo", EDITOR " " HO… | |
+static const char *calendarcmd[] = DUPLEXATTACHCMD("calendar", "calendar… | |
+/* static const char *filecmd[] = TERMCMD("sh", "-c", "cd ~/tmp; ls … | |
+static const char *mailcmd[] = DUPLEXCMD("mutt"); | |
+static const char *irccmd[] = DUPLEXATTACHCMD("irc", "ssh -t irc@ad… | |
+static const char *topcmd[] = TERMCMD("top", "-C"); | |
+ | |
+static const char *mixercmd[] = TERMCMD("audiomixer"); | |
+static const char *musiccmd[] = TERMCMD("ncmpc"); | |
+static const char *mpdtogglecmd[] = {"mpc", "toggle", NULL}; | |
+static const char *mpdnextcmd[] = {"mpc", "next", NULL}; | |
+static const char *mpdprevcmd[] = {"mpc", "prev", NULL}; | |
+static const char *mpdstopcmd[] = {"mpc", "stop", NULL}; | |
+ | |
+static const char *audioextvolupcmd[] = {"sndioctl", "output.level=+0.05… | |
+static const char *audioextvoldncmd[] = {"sndioctl", "output.level=-0.05… | |
+static const char *audioextmutecmd[] = {"sndioctl", "output.mute=!", NU… | |
+ | |
+/* see key names in /usr/include/X11/keysymdef.h */ | |
+static Key keys[] = { | |
+ /* modifier key function argument */ | |
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termc… | |
+ { MODKEY, XK_Return, spawn, {.v = termp… | |
+ | |
+ { MODKEY|ShiftMask, XK_space, spawn, {.v = dmenu… | |
+ { MODKEY, XK_space, spawn, {.v = searc… | |
+ { MODKEY, XK_a, spawn, {.v = artic… | |
+ { MODKEY|ShiftMask, XK_a, spawn, {.v = jabbr… | |
+ { MODKEY, XK_o, spawn, {.v = fuzzy… | |
+ { MODKEY, XK_grave, spawn, {.v = unico… | |
+ { MODKEY, XK_slash, spawn, {.v = defin… | |
+ { MODKEY, XK_p, spawn, {.v = passc… | |
+ { MODKEY|ShiftMask, XK_p, spawn, {.v = passe… | |
+ { MODKEY, XK_F7, spawn, {.v = displ… | |
+ { MODKEY, XK_F8, spawn, {.v = torre… | |
+ { MODKEY, XK_F9, spawn, {.v = mount… | |
+ { MODKEY, XK_F10, spawn, {.v = umoun… | |
+ { MODKEY, XK_F11, spawn, {.v = conta… | |
+ | |
+ { MODKEY, XK_u, spawn, {.v = plumb… | |
+ { MODKEY|ShiftMask, XK_u, spawn, {.v = plumb… | |
+ { MODKEY, XK_x, spawn, {.v = xlock… | |
+ { 0, XK_Print, spawn, {.v = print… | |
+ { ShiftMask, XK_Print, spawn, {.v = print… | |
+ { MODKEY|ShiftMask, XK_c, spawn, {.v = showc… | |
+ { MODKEY|ControlMask|ShiftMask, XK_l, spawn, {.v = keybo… | |
+ | |
+ { MODKEY, XK_v, spawn, {.v = video… | |
+ { MODKEY, XK_r, spawn, {.v = scree… | |
+ { MODKEY, XK_c, spawn, {.v = calen… | |
+ { MODKEY, XK_d, spawn, {.v = todoc… | |
+ { MODKEY|ShiftMask, XK_d, spawn, {.v = journ… | |
+ { MODKEY, XK_w, spawn, {.v = brows… | |
+ { MODKEY|ShiftMask, XK_w, spawn, {.v = torbr… | |
+ { MODKEY, XK_t, spawn, {.v = textc… | |
+ { MODKEY, XK_m, spawn, {.v = mailc… | |
+ { MODKEY, XK_i, spawn, {.v = irccm… | |
+ { MODKEY|ShiftMask, XK_o, spawn, {.v = topcm… | |
+ | |
+ { MODKEY|ControlMask|ShiftMask, XK_a, spawn, {.v = mixer… | |
+ { MODKEY|ControlMask|ShiftMask, XK_m, spawn, {.v = music… | |
+ { MODKEY|ControlMask|ShiftMask, XK_p, spawn, {.v = mpdto… | |
+ { MODKEY|ControlMask|ShiftMask, XK_n, spawn, {.v = mpdne… | |
+ { MODKEY|ControlMask|ShiftMask, XK_b, spawn, {.v = mpdpr… | |
+ { MODKEY|ControlMask|ShiftMask, XK_s, spawn, {.v = mpdst… | |
+ { ShiftMask, XF86XK_AudioRaiseVolume, spawn, {.v = audio… | |
+ { ShiftMask, XF86XK_AudioLowerVolume, spawn, {.v = audio… | |
+ { ShiftMask, XF86XK_AudioMute, spawn, {.v = audio… | |
+ | |
+ { MODKEY|MODALTKEY, XK_b, togglebar, {0} }, | |
+ { MODKEY, XK_j, focusstack, {.i = +1 } … | |
+ { MODKEY, XK_k, focusstack, {.i = -1 } … | |
+ { MODKEY|ShiftMask, XK_j, incnmaster, {.i = +1 } … | |
+ { MODKEY|ShiftMask, XK_k, incnmaster, {.i = -1 } … | |
+ { MODKEY, XK_h, setmfact, {.f = -0.05… | |
+ { MODKEY, XK_l, setmfact, {.f = +0.05… | |
+ { MODKEY, XK_Tab, view, {0} }, | |
+ { MODKEY, XK_q, killclient, {0} }, | |
+ { MODKEY|ShiftMask, XK_t, setlayout, {.v = &layo… | |
+ { MODKEY|ShiftMask, XK_l, setlayout, {.v = &layo… | |
+ { MODKEY|ShiftMask, XK_m, setlayout, {.v = &layo… | |
+ { MODKEY|ShiftMask, XK_f, togglefloating, {0} }, | |
+ { MODKEY, XK_f, zoom, {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|ShiftMask, XK_equal, setgaps, {.i = +1 } … | |
+ { MODKEY|MODALTKEY, XK_equal, setgaps, {.i = 0 } … | |
+ { MODKEY, XK_equal, setgaps, {.i = gappx… | |
+ 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, ClkClientW… | |
+static Button buttons[] = { | |
+ /* click event mask button function … | |
+ { ClkLtSymbol, 0, Button1, setlayout, … | |
+ { ClkLtSymbol, 0, Button3, setlayout, … | |
+ { ClkWinTitle, 0, Button2, zoom, … | |
+ { ClkStatusText, 0, Button2, spawn, … | |
+ { ClkClientWin, MODKEY, Button1, movemouse, … | |
+ { ClkClientWin, MODKEY, Button2, togglefloating… | |
+ { ClkClientWin, MODKEY, Button3, resizemouse, … | |
+ { ClkTagBar, 0, Button1, view, … | |
+ { ClkTagBar, 0, Button3, toggleview, … | |
+ { ClkTagBar, MODKEY, Button1, tag, … | |
+ { ClkTagBar, MODKEY, Button3, toggletag, … | |
+}; | |
+ | |
diff --git a/config.mk b/config.mk | |
t@@ -18,7 +18,7 @@ XINERAMAFLAGS = -DXINERAMA | |
FREETYPELIBS = -lfontconfig -lXft | |
FREETYPEINC = /usr/include/freetype2 | |
# OpenBSD (uncomment) | |
-#FREETYPEINC = ${X11INC}/freetype2 | |
+FREETYPEINC = ${X11INC}/freetype2 | |
# includes and libs | |
INCS = -I${X11INC} -I${FREETYPEINC} | |
diff --git a/dwm.c b/dwm.c | |
t@@ -41,6 +41,9 @@ | |
#endif /* XINERAMA */ | |
#include <X11/Xft/Xft.h> | |
+/* for multimedia keys */ | |
+#include <X11/XF86keysym.h> | |
+ | |
#include "drw.h" | |
#include "util.h" | |
t@@ -92,7 +95,7 @@ struct Client { | |
int basew, baseh, incw, inch, maxw, maxh, minw, minh; | |
int bw, oldbw; | |
unsigned int tags; | |
- int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; | |
+ int isfixed, floatpos, isfloating, isurgent, neverfocus, oldstate, isf… | |
Client *next; | |
Client *snext; | |
Monitor *mon; | |
t@@ -111,6 +114,7 @@ typedef struct { | |
void (*arrange)(Monitor *); | |
} Layout; | |
+typedef struct Pertag Pertag; | |
struct Monitor { | |
char ltsymbol[16]; | |
float mfact; | |
t@@ -119,6 +123,7 @@ struct Monitor { | |
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]; | |
t@@ -130,6 +135,7 @@ struct Monitor { | |
Monitor *next; | |
Window barwin; | |
const Layout *lt[2]; | |
+ Pertag *pertag; | |
}; | |
typedef struct { | |
t@@ -137,6 +143,7 @@ typedef struct { | |
const char *instance; | |
const char *title; | |
unsigned int tags; | |
+ int floatpos; | |
int isfloating; | |
int monitor; | |
} Rule; | |
t@@ -169,7 +176,6 @@ 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); | |
t@@ -200,6 +206,7 @@ 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); | |
t@@ -272,6 +279,15 @@ static Window root, wmcheckwin; | |
/* configuration, allows nested code to access above variables */ | |
#include "config.h" | |
+struct Pertag { | |
+ unsigned int curtag, prevtag; /* current and previous tag */ | |
+ int nmasters[LENGTH(tags) + 1]; /* number of windows in master area */ | |
+ float mfacts[LENGTH(tags) + 1]; /* mfacts per tag */ | |
+ unsigned int sellts[LENGTH(tags) + 1]; /* selected layouts */ | |
+ const Layout *ltidxs[LENGTH(tags) + 1][2]; /* matrix of tags and layou… | |
+ int showbars[LENGTH(tags) + 1]; /* display bar for the current tag */ | |
+}; | |
+ | |
/* compile-time check if all tags fit into an unsigned int bit array. */ | |
struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; | |
t@@ -286,6 +302,7 @@ applyrules(Client *c) | |
XClassHint ch = { NULL, NULL }; | |
/* rule matching */ | |
+ c->floatpos = 0; | |
c->isfloating = 0; | |
c->tags = 0; | |
XGetClassHint(dpy, c->win, &ch); | |
t@@ -299,6 +316,7 @@ applyrules(Client *c) | |
&& (!r->instance || strstr(instance, r->instance))) | |
{ | |
c->isfloating = r->isfloating; | |
+ c->floatpos = r->floatpos; | |
c->tags |= r->tags; | |
for (m = mons; m && m->num != r->monitor; m = m->next); | |
if (m) | |
t@@ -417,7 +435,7 @@ attachstack(Client *c) | |
void | |
buttonpress(XEvent *e) | |
{ | |
- unsigned int i, x, click; | |
+ unsigned int i, x, click, occ = 0; | |
Arg arg = {0}; | |
Client *c; | |
Monitor *m; | |
t@@ -432,9 +450,14 @@ buttonpress(XEvent *e) | |
} | |
if (ev->window == selmon->barwin) { | |
i = x = 0; | |
- do | |
+ for (c = m->clients; c; c = c->next) | |
+ occ |= c->tags == 255 ? 0 : c->tags; | |
+ do { | |
+ /* do not reserve space for vacant tags */ | |
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | |
+ continue; | |
x += TEXTW(tags[i]); | |
- while (ev->x >= x && ++i < LENGTH(tags)); | |
+ } while (ev->x >= x && ++i < LENGTH(tags)); | |
if (i < LENGTH(tags)) { | |
click = ClkTagBar; | |
arg.ui = 1 << i; | |
t@@ -632,6 +655,7 @@ Monitor * | |
createmon(void) | |
{ | |
Monitor *m; | |
+ unsigned int i; | |
m = ecalloc(1, sizeof(Monitor)); | |
m->tagset[0] = m->tagset[1] = 1; | |
t@@ -639,9 +663,24 @@ createmon(void) | |
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); | |
+ m->pertag = ecalloc(1, sizeof(Pertag)); | |
+ m->pertag->curtag = m->pertag->prevtag = 1; | |
+ | |
+ for (i = 0; i <= LENGTH(tags); i++) { | |
+ m->pertag->nmasters[i] = m->nmaster; | |
+ m->pertag->mfacts[i] = m->mfact; | |
+ | |
+ m->pertag->ltidxs[i][0] = m->lt[0]; | |
+ m->pertag->ltidxs[i][1] = m->lt[1]; | |
+ m->pertag->sellts[i] = m->sellt; | |
+ | |
+ m->pertag->showbars[i] = m->showbar; | |
+ } | |
+ | |
return m; | |
} | |
t@@ -696,7 +735,7 @@ dirtomon(int dir) | |
void | |
drawbar(Monitor *m) | |
{ | |
- int x, w, tw = 0; | |
+ int x, w, sw = 0; | |
int boxs = drw->fonts->h / 9; | |
int boxw = drw->fonts->h / 6 + 2; | |
unsigned int i, occ = 0, urg = 0; | |
t@@ -705,33 +744,33 @@ 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); | |
+ sw = TEXTW(stext) - lrpad + 2; /* 2px right padding */ | |
+ drw_text(drw, m->ww - sw, 0, sw, bh, 0, stext, 0); | |
} | |
for (c = m->clients; c; c = c->next) { | |
- occ |= c->tags; | |
+ occ |= c->tags == 255 ? 0 : c->tags; | |
if (c->isurgent) | |
urg |= c->tags; | |
} | |
x = 0; | |
for (i = 0; i < LENGTH(tags); i++) { | |
+ /* do not draw vacant tags */ | |
+ if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i)) | |
+ continue; | |
+ | |
w = TEXTW(tags[i]); | |
drw_setscheme(drw, scheme[m->tagset[m->seltags] & 1 << i ? Sch… | |
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->tag… | |
- 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); | |
- if ((w = m->ww - tw - x) > bh) { | |
+ if ((w = m->ww - sw - x) > bh) { | |
if (m->sel) { | |
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : Sc… | |
+ /*drw_setscheme(drw, scheme[m == selmon ? SchemeSel : … | |
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->s… | |
t@@ -967,7 +1006,7 @@ grabkeys(void) | |
void | |
incnmaster(const Arg *arg) | |
{ | |
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); | |
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = M… | |
arrange(selmon); | |
} | |
t@@ -1050,6 +1089,30 @@ manage(Window w, XWindowAttributes *wa) | |
&& (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mo… | |
c->bw = borderpx; | |
+ switch (c->floatpos) { | |
+ case 1: case 4: case 7: | |
+ c->x = 0; | |
+ break; | |
+ case 3: case 6: case 9: | |
+ c->x = c->mon->mw - WIDTH(c); | |
+ break; | |
+ case 2: case 5: case 8: default: | |
+ c->x = (c->mon->mw - WIDTH(c)) / 2; | |
+ break; | |
+ } | |
+ | |
+ switch (c->floatpos) { | |
+ case 1: case 2: case 3: | |
+ c->y = 0; | |
+ break; | |
+ case 7: case 8: case 9: | |
+ c->y = c->mon->mh - HEIGHT(c); | |
+ break; | |
+ case 4: case 5: case 6: default: | |
+ c->y = (c->mon->mh - HEIGHT(c)) / 2; | |
+ break; | |
+ } | |
+ | |
wc.border_width = c->bw; | |
XConfigureWindow(dpy, w, CWBorderWidth, &wc); | |
XSetWindowBorder(dpy, w, scheme[SchemeNorm][ColBorder].pixel); | |
t@@ -1499,12 +1562,22 @@ setfullscreen(Client *c, int fullscreen) | |
} | |
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; | |
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]… | |
if (arg && arg->v) | |
- selmon->lt[selmon->sellt] = (Layout *)arg->v; | |
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->per… | |
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof se… | |
if (selmon->sel) | |
arrange(selmon); | |
t@@ -1521,9 +1594,9 @@ setmfact(const Arg *arg) | |
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) | |
+ if (f < 0.1 || f > 0.9) | |
return; | |
- selmon->mfact = f; | |
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; | |
arrange(selmon); | |
} | |
t@@ -1684,25 +1757,23 @@ tile(Monitor *m) | |
if (n > m->nmaster) | |
mw = m->nmaster ? m->ww * m->mfact : 0; | |
else | |
- mw = m->ww; | |
- for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->n… | |
+ mw = m->ww - m->gappx; | |
+ for (i = 0, my = ty = m->gappx, c = nexttiled(m->clients); c; c = next… | |
if (i < m->nmaster) { | |
- h = (m->wh - my) / (MIN(n, m->nmaster) - i); | |
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c-… | |
- if (my + HEIGHT(c) < m->wh) | |
- my += HEIGHT(c); | |
+ h = (m->wh - my) / (MIN(n, m->nmaster) - i) - m->gappx; | |
+ resize(c, m->wx + m->gappx, m->wy + my, mw - (2*c->bw)… | |
+ my += HEIGHT(c) + m->gappx; | |
} else { | |
- h = (m->wh - ty) / (n - i); | |
- resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->b… | |
- if (ty + HEIGHT(c) < m->wh) | |
- ty += HEIGHT(c); | |
+ h = (m->wh - ty) / (n - i) - m->gappx; | |
+ resize(c, m->wx + mw + m->gappx, m->wy + ty, m->ww - m… | |
+ ty += HEIGHT(c) + m->gappx; | |
} | |
} | |
void | |
togglebar(const Arg *arg) | |
{ | |
- selmon->showbar = !selmon->showbar; | |
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !… | |
updatebarpos(selmon); | |
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon-… | |
arrange(selmon); | |
t@@ -1741,9 +1812,33 @@ void | |
toggleview(const Arg *arg) | |
{ | |
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & … | |
+ int i; | |
if (newtagset) { | |
selmon->tagset[selmon->seltags] = newtagset; | |
+ | |
+ if (newtagset == ~0) { | |
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |
+ selmon->pertag->curtag = 0; | |
+ } | |
+ | |
+ /* test if the user did not select the same tag */ | |
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { | |
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |
+ for (i = 0; !(newtagset & 1 << i); i++) ; | |
+ selmon->pertag->curtag = i + 1; | |
+ } | |
+ | |
+ /* apply settings for this view */ | |
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->cur… | |
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; | |
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; | |
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->per… | |
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->p… | |
+ | |
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag… | |
+ togglebar(NULL); | |
+ | |
focus(NULL); | |
arrange(selmon); | |
} | |
t@@ -2038,11 +2133,37 @@ updatewmhints(Client *c) | |
void | |
view(const Arg *arg) | |
{ | |
+ int i; | |
+ unsigned int tmptag; | |
+ | |
if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) | |
return; | |
selmon->seltags ^= 1; /* toggle sel tagset */ | |
- if (arg->ui & TAGMASK) | |
+ if (arg->ui & TAGMASK) { | |
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; | |
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |
+ | |
+ if (arg->ui == ~0) | |
+ selmon->pertag->curtag = 0; | |
+ else { | |
+ for (i = 0; !(arg->ui & 1 << i); i++) ; | |
+ selmon->pertag->curtag = i + 1; | |
+ } | |
+ } else { | |
+ tmptag = selmon->pertag->prevtag; | |
+ selmon->pertag->prevtag = selmon->pertag->curtag; | |
+ selmon->pertag->curtag = tmptag; | |
+ } | |
+ | |
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; | |
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; | |
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; | |
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->cur… | |
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->c… | |
+ | |
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag… | |
+ togglebar(NULL); | |
+ | |
focus(NULL); | |
arrange(selmon); | |
} |