tAdd customize - dwm - [fork] customized build of dwm, the dynamic window manager
(HTM) git clone git://src.adamsgaard.dk/dwm
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit 7c099bd74e3f1691da859a1277a501ebe4d53fd6
(DIR) parent f09418bbb6651ab4c299cfefbe1d18de401f630e
(HTM) Author: Anders Damsgaard <anders@adamsgaard.dk>
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(-)
---
(DIR) diff --git a/LICENSE b/LICENSE
t@@ -17,6 +17,7 @@ MIT/X Consortium License
© 2015-2016 Quentin Rameau <quinq@fifth.space>
© 2015-2016 Eric Pruitt <eric.pruitt@gmail.com>
© 2016-2017 Markus Teich <markus.teich@stusta.mhn.de>
+© 2019-2020 Anders Damsgaard <anders@adamsgaard.dk>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
(DIR) 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 monitor */
+ { "Tor Browser", NULL, NULL, 0, 5, 1, -1 },
+ { "tabbed", NULL, NULL, 1<<1, 0, 0, -1 },
+ { "Firefox", NULL, NULL, 1<<1, 0, 0, -1 },
+ { "Signal", NULL, NULL, 1<<8, 0, 0, -1 },
+ { NULL, NULL, "video", ~0, 9, 1, -1 },
+ { NULL, NULL, "topleft", 0, 1, 1, -1 },
+ { NULL, NULL, "topcenter", 0, 2, 1, -1 },
+ { NULL, NULL, "topright", 0, 3, 1, -1 },
+ { NULL, NULL, "midleft", 0, 4, 1, -1 },
+ { NULL, NULL, "midcenter", 0, 5, 1, -1 },
+ { NULL, NULL, "midright", 0, 6, 1, -1 },
+ { NULL, NULL, "botleft", 0, 7, 1, -1 },
+ { NULL, NULL, "botcenter", 0, 8, 1, -1 },
+ { NULL, NULL, "botright", 0, 9, 1, -1 },
+};
+
+/* layout(s) */
+static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */
+static const int nmaster = 1; /* number of clients in master area */
+static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */
+
+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 << TAG} }, \
+ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \
+ { MODKEY|ShiftMask, KEY, tag, {.ui = 1 << TAG} }, \
+ { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui = 1 << TAG} },
+
+
+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", "-s", name, cmd, NULL}
+
+/* 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@adamsgaard.dk\t", "-n", NULL};
+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 " " HOME "/doc/todo/todo.md");
+static const char *calendarcmd[] = DUPLEXATTACHCMD("calendar", "calendar.sh");
+/* static const char *filecmd[] = TERMCMD("sh", "-c", "cd ~/tmp; ls -p; $SHELL -l"); */
+static const char *mailcmd[] = DUPLEXCMD("mutt");
+static const char *irccmd[] = DUPLEXATTACHCMD("irc", "ssh -t irc@adamsgaard.dk 'tmux -u new-session -A -D -s irc irssi'");
+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", NULL};
+static const char *audioextvoldncmd[] = {"sndioctl", "output.level=-0.05", NULL};
+static const char *audioextmutecmd[] = {"sndioctl", "output.mute=!", NULL};
+
+/* see key names in /usr/include/X11/keysymdef.h */
+static Key keys[] = {
+ /* modifier key function argument */
+ { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } },
+ { MODKEY, XK_Return, spawn, {.v = termplexcmd } },
+
+ { MODKEY|ShiftMask, XK_space, spawn, {.v = dmenucmd } },
+ { MODKEY, XK_space, spawn, {.v = searchcmd } },
+ { MODKEY, XK_a, spawn, {.v = articlesearchcmd } },
+ { MODKEY|ShiftMask, XK_a, spawn, {.v = jabbrevcmd } },
+ { MODKEY, XK_o, spawn, {.v = fuzzylaunchcmd } },
+ { MODKEY, XK_grave, spawn, {.v = unicodecmd } },
+ { MODKEY, XK_slash, spawn, {.v = definecmd } },
+ { MODKEY, XK_p, spawn, {.v = passcmd } },
+ { MODKEY|ShiftMask, XK_p, spawn, {.v = passemailcmd } },
+ { MODKEY, XK_F7, spawn, {.v = displaycmd } },
+ { MODKEY, XK_F8, spawn, {.v = torrentcmd } },
+ { MODKEY, XK_F9, spawn, {.v = mountcmd } },
+ { MODKEY, XK_F10, spawn, {.v = umountcmd } },
+ { MODKEY, XK_F11, spawn, {.v = contactscmd } },
+
+ { MODKEY, XK_u, spawn, {.v = plumbcmd } },
+ { MODKEY|ShiftMask, XK_u, spawn, {.v = plumb2cmd } },
+ { MODKEY, XK_x, spawn, {.v = xlockcmd } },
+ { 0, XK_Print, spawn, {.v = printscreencmd } },
+ { ShiftMask, XK_Print, spawn, {.v = printscreenicmd } },
+ { MODKEY|ShiftMask, XK_c, spawn, {.v = showclipcmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_l, spawn, {.v = keyboardlayoutcmd } },
+
+ { MODKEY, XK_v, spawn, {.v = videocmd } },
+ { MODKEY, XK_r, spawn, {.v = screenrecordcmd } },
+ { MODKEY, XK_c, spawn, {.v = calendarcmd } },
+ { MODKEY, XK_d, spawn, {.v = todocmd } },
+ { MODKEY|ShiftMask, XK_d, spawn, {.v = journalcmd } },
+ { MODKEY, XK_w, spawn, {.v = browsercmd } },
+ { MODKEY|ShiftMask, XK_w, spawn, {.v = torbrowsercmd } },
+ { MODKEY, XK_t, spawn, {.v = textcmd } },
+ { MODKEY, XK_m, spawn, {.v = mailcmd } },
+ { MODKEY, XK_i, spawn, {.v = irccmd } },
+ { MODKEY|ShiftMask, XK_o, spawn, {.v = topcmd } },
+
+ { MODKEY|ControlMask|ShiftMask, XK_a, spawn, {.v = mixercmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_m, spawn, {.v = musiccmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_p, spawn, {.v = mpdtogglecmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_n, spawn, {.v = mpdnextcmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_b, spawn, {.v = mpdprevcmd } },
+ { MODKEY|ControlMask|ShiftMask, XK_s, spawn, {.v = mpdstopcmd } },
+ { ShiftMask, XF86XK_AudioRaiseVolume, spawn, {.v = audioextvolupcmd } },
+ { ShiftMask, XF86XK_AudioLowerVolume, spawn, {.v = audioextvoldncmd } },
+ { ShiftMask, XF86XK_AudioMute, spawn, {.v = audioextmutecmd } },
+
+ { 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 = &layouts[0]} },
+ { MODKEY|ShiftMask, XK_l, setlayout, {.v = &layouts[1]} },
+ { MODKEY|ShiftMask, XK_m, setlayout, {.v = &layouts[2]} },
+ { 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, 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} },
+};
+
(DIR) 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}
(DIR) 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, isfullscreen;
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 layouts indexes */
+ 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 ? 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);
- if ((w = m->ww - tw - x) > bh) {
+ if ((w = m->ww - sw - x) > bh) {
if (m->sel) {
- drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);
+ /*drw_setscheme(drw, scheme[m == selmon ? SchemeSel : SchemeNorm]);*/
drw_text(drw, x, 0, w, bh, lrpad / 2, m->sel->name, 0);
if (m->sel->isfloating)
drw_rect(drw, x + boxs, boxs, boxw, boxw, m->sel->isfixed, 0);
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] = MAX(selmon->nmaster + arg->i, 0);
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->mon->my);
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] ^= 1;
if (arg && arg->v)
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
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->next), i++)
+ mw = m->ww - m->gappx;
+ 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);
- resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
- if (my + HEIGHT(c) < m->wh)
- my += HEIGHT(c);
+ 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, h - (2*c->bw), 0);
+ 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->bw), h - (2*c->bw), 0);
- 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 - mw - (2*c->bw) - 2*m->gappx, h - (2*c->bw), 0);
+ ty += HEIGHT(c) + m->gappx;
}
}
void
togglebar(const Arg *arg)
{
- selmon->showbar = !selmon->showbar;
+ selmon->showbar = selmon->pertag->showbars[selmon->pertag->curtag] = !selmon->showbar;
updatebarpos(selmon);
XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
arrange(selmon);
t@@ -1741,9 +1812,33 @@ void
toggleview(const Arg *arg)
{
unsigned int newtagset = selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK);
+ 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->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->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ 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->curtag][selmon->sellt];
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
+
+ if (selmon->showbar != selmon->pertag->showbars[selmon->pertag->curtag])
+ togglebar(NULL);
+
focus(NULL);
arrange(selmon);
}