initial commit

This commit is contained in:
2023-09-18 23:34:29 +02:00
commit faedc5a5ea
292 changed files with 26289 additions and 0 deletions

223
patch/alttab.c Normal file
View File

@@ -0,0 +1,223 @@
int alttabn; /* move that many clients forward */
int ntabs; /* number of active clients in tag */
int isalt;
Client **altsnext; /* array of all clients in the tag */
Window alttabwin;
void
alttab()
{
Monitor *m = selmon;
/* move to next window */
if (m->sel && m->sel->snext) {
alttabn++;
if (alttabn >= ntabs)
alttabn = 0; /* reset alttabn */
focus(altsnext[alttabn]);
restack(m);
}
/* redraw tab */
XRaiseWindow(dpy, alttabwin);
drawtab(ntabs, 0, m);
}
void
alttabend()
{
Monitor *m = selmon;
Client *buff;
int i;
if (!isalt)
return;
/* Move all clients between first and choosen position,
* one down in stack and put choosen client to the first position
* so they remain in right order for the next time that alt-tab is used
*/
if (ntabs > 1) {
if (alttabn != 0) { /* if user picked original client do nothing */
buff = altsnext[alttabn];
if (alttabn > 1)
for (i = alttabn; i > 0; i--)
altsnext[i] = altsnext[i - 1];
else /* swap them if there are just 2 clients */
altsnext[alttabn] = altsnext[0];
altsnext[0] = buff;
}
/* restack clients */
for (i = ntabs - 1; i >= 0; i--) {
focus(altsnext[i]);
restack(m);
}
free(altsnext); /* free list of clients */
}
/* destroy the window */
isalt = 0;
ntabs = 0;
XUnmapWindow(dpy, alttabwin);
XDestroyWindow(dpy, alttabwin);
}
void
drawtab(int nwins, int first, Monitor *m)
{
Client *c;
int i, h;
int y = 0;
int px = m->mx;
int py = m->my;
if (first) {
XSetWindowAttributes wa = {
.override_redirect = True,
#if BAR_ALPHA_PATCH
.background_pixel = 0,
.border_pixel = 0,
.colormap = cmap,
#else
.background_pixmap = ParentRelative,
#endif // BAR_ALPHA_PATCH
.event_mask = ButtonPressMask|ExposureMask
};
/* decide position of tabwin */
if (tabposx == 1)
px = m->mx + (m->mw / 2) - (maxwtab / 2);
else if (tabposx == 2)
px = m->mx + m->mw - maxwtab;
if (tabposy == 1)
py = m->my + (m->mh / 2) - (maxhtab / 2);
else if (tabposy == 2)
py = m->my + m->mh - maxhtab;
h = maxhtab;
#if BAR_ALPHA_PATCH
alttabwin = XCreateWindow(dpy, root, px, py, maxwtab, maxhtab, 2, depth,
InputOutput, visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa);
#else
alttabwin = XCreateWindow(dpy, root, px, py, maxwtab, maxhtab, 2, DefaultDepth(dpy, screen),
CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa);
#endif // BAR_ALPHA_PATCH
XDefineCursor(dpy, alttabwin, cursor[CurNormal]->cursor);
XMapRaised(dpy, alttabwin);
}
h = maxhtab / ntabs;
for (i = 0; i < ntabs; i++) { /* draw all clients into tabwin */
c = altsnext[i];
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c))
continue;
drw_setscheme(drw, scheme[c == m->sel ? SchemeSel : SchemeNorm]);
drw_text(drw, 0, y, maxwtab, h, 0, c->name, 0, 0);
y += h;
}
drw_setscheme(drw, scheme[SchemeNorm]);
drw_map(drw, alttabwin, 0, 0, maxwtab, maxhtab);
}
void
alttabstart(const Arg *arg)
{
Client *c;
Monitor *m = selmon;
int grabbed;
int i;
altsnext = NULL;
if (alttabwin)
alttabend();
if (isalt == 1) {
alttabend();
return;
}
isalt = 1;
alttabn = 0;
ntabs = 0;
for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c))
continue;
++ntabs;
}
if (!ntabs) {
alttabend();
return;
}
altsnext = (Client **) malloc(ntabs * sizeof(Client *));
for (i = 0, c = m->stack; c; c = c->snext) {
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c))
continue;
altsnext[i] = c;
i++;
}
drawtab(ntabs, 1, m);
struct timespec ts = { .tv_sec = 0, .tv_nsec = 1000000 };
/* grab keyboard (take all input from keyboard) */
grabbed = 1;
for (i = 0; i < 1000; i++) {
if (XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeAsync, CurrentTime) == GrabSuccess)
break;
nanosleep(&ts, NULL);
if (i == 1000 - 1)
grabbed = 0;
}
XEvent event;
alttab();
if (grabbed == 0) {
alttabend();
return;
}
while (grabbed) {
XNextEvent(dpy, &event);
if (event.type == KeyPress || event.type == KeyRelease) {
if (event.type == KeyRelease && event.xkey.keycode == tabmodkey) /* if mod key is released break cycle */
break;
if (event.type == KeyPress) {
if (event.xkey.keycode == tabcyclekey) { /* if tab is pressed move to the next window */
alttab();
}
}
}
}
c = m->sel;
alttabend();
XUngrabKeyboard(dpy, CurrentTime);
focus(c);
restack(m);
}

5
patch/alttab.h Normal file
View File

@@ -0,0 +1,5 @@
#include <time.h>
static void drawtab(int nwins, int first, Monitor *m);
static void alttabstart(const Arg *arg);
static void alttabend();

25
patch/aspectresize.c Normal file
View File

@@ -0,0 +1,25 @@
void
aspectresize(const Arg *arg)
{
/* only floating windows can be moved */
Client *c;
c = selmon->sel;
float ratio;
int w, h,nw, nh;
if (!c || !arg)
return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
return;
ratio = (float)c->w / (float)c->h;
h = arg->i;
w = (int)(ratio * h);
nw = c->w + w;
nh = c->h + h;
XRaiseWindow(dpy, c->win);
resize(c, c->x, c->y, nw, nh, True);
}

2
patch/aspectresize.h Normal file
View File

@@ -0,0 +1,2 @@
static void aspectresize(const Arg *arg);

59
patch/attachx.c Normal file
View File

@@ -0,0 +1,59 @@
void
attachx(Client *c)
{
#if ATTACHABOVE_PATCH || ATTACHASIDE_PATCH || ATTACHBOTTOM_PATCH || SEAMLESS_RESTART_PATCH
Client *at;
#endif // ATTACHABOVE_PATCH | ATTACHASIDE_PATCH | ATTACHBOTTOM_PATCH | SEAMLESS_RESTART_PATCH
#if SEAMLESS_RESTART_PATCH
if (c->idx > 0) { /* then the client has a designated position in the client list */
for (at = c->mon->clients; at; at = at->next) {
if (c->idx < at->idx) {
c->next = at;
c->mon->clients = c;
return;
} else if (at->idx <= c->idx && (!at->next || c->idx <= at->next->idx)) {
c->next = at->next;
at->next = c;
return;
}
}
}
#endif // SEAMLESS_RESTART_PATCH
#if ATTACHABOVE_PATCH
if (!(c->mon->sel == NULL || c->mon->sel == c->mon->clients || c->mon->sel->isfloating)) {
for (at = c->mon->clients; at->next != c->mon->sel; at = at->next);
c->next = at->next;
at->next = c;
return;
}
#elif ATTACHASIDE_PATCH
unsigned int n;
for (at = c->mon->clients, n = 0; at; at = at->next)
if (!at->isfloating && ISVISIBLEONTAG(at, c->tags))
if (++n >= c->mon->nmaster)
break;
if (at && c->mon->nmaster) {
c->next = at->next;
at->next = c;
return;
}
#elif ATTACHBELOW_PATCH
if (!(c->mon->sel == NULL || c->mon->sel == c || c->mon->sel->isfloating)) {
c->next = c->mon->sel->next;
c->mon->sel->next = c;
return;
}
#elif ATTACHBOTTOM_PATCH
for (at = c->mon->clients; at && at->next; at = at->next);
if (at) {
at->next = c;
c->next = NULL;
return;
}
#endif
attach(c); // master (default)
}

2
patch/attachx.h Normal file
View File

@@ -0,0 +1,2 @@
static void attachx(Client *c);

76
patch/autostart.c Normal file
View File

@@ -0,0 +1,76 @@
void
runautostart(void)
{
char *pathpfx;
char *path;
char *xdgdatahome;
char *home;
struct stat sb;
if ((home = getenv("HOME")) == NULL)
/* this is almost impossible */
return;
/* if $XDG_DATA_HOME is set and not empty, use $XDG_DATA_HOME/dwm,
* otherwise use ~/.local/share/dwm as autostart script directory
*/
xdgdatahome = getenv("XDG_DATA_HOME");
if (xdgdatahome != NULL && *xdgdatahome != '\0') {
/* space for path segments, separators and nul */
pathpfx = ecalloc(1, strlen(xdgdatahome) + strlen(dwmdir) + 2);
if (sprintf(pathpfx, "%s/%s", xdgdatahome, dwmdir) <= 0) {
free(pathpfx);
return;
}
} else {
/* space for path segments, separators and nul */
pathpfx = ecalloc(1, strlen(home) + strlen(localshare)
+ strlen(dwmdir) + 3);
if (sprintf(pathpfx, "%s/%s/%s", home, localshare, dwmdir) < 0) {
free(pathpfx);
return;
}
}
/* check if the autostart script directory exists */
if (! (stat(pathpfx, &sb) == 0 && S_ISDIR(sb.st_mode))) {
/* the XDG conformant path does not exist or is no directory
* so we try ~/.dwm instead
*/
char *pathpfx_new = realloc(pathpfx, strlen(home) + strlen(dwmdir) + 3);
if(pathpfx_new == NULL) {
free(pathpfx);
return;
}
pathpfx = pathpfx_new;
if (sprintf(pathpfx, "%s/.%s", home, dwmdir) <= 0) {
free(pathpfx);
return;
}
}
/* try the blocking script first */
path = ecalloc(1, strlen(pathpfx) + strlen(autostartblocksh) + 2);
if (sprintf(path, "%s/%s", pathpfx, autostartblocksh) <= 0) {
free(path);
free(pathpfx);
}
if (access(path, X_OK) == 0)
system(path);
/* now the non-blocking script */
if (sprintf(path, "%s/%s", pathpfx, autostartsh) <= 0) {
free(path);
free(pathpfx);
}
if (access(path, X_OK) == 0)
system(strcat(path, " &"));
free(pathpfx);
free(path);
}

2
patch/autostart.h Normal file
View File

@@ -0,0 +1,2 @@
static void runautostart(void);

39
patch/bar.c Normal file
View File

@@ -0,0 +1,39 @@
void
barhover(XEvent *e, Bar *bar)
{
const BarRule *br;
Monitor *m = bar->mon;
XMotionEvent *ev = &e->xmotion;
BarArg barg = { 0, 0, 0, 0 };
int r;
for (r = 0; r < LENGTH(barrules); r++) {
br = &barrules[r];
if (br->bar != bar->idx || (br->monitor == 'A' && m != selmon) || br->hoverfunc == NULL)
continue;
if (br->monitor != 'A' && br->monitor != -1 && br->monitor != bar->mon->num)
continue;
if (bar->x[r] > ev->x || ev->x > bar->x[r] + bar->w[r])
continue;
barg.x = ev->x - bar->x[r];
barg.y = ev->y - bar->borderpx;
barg.w = bar->w[r];
barg.h = bar->bh - 2 * bar->borderpx;
br->hoverfunc(bar, &barg, ev);
break;
}
}
Bar *
wintobar(Window win)
{
Monitor *m;
Bar *bar;
for (m = mons; m; m = m->next)
for (bar = m->bar; bar; bar = bar->next)
if (bar->win == win)
return bar;
return NULL;
}

2
patch/bar.h Normal file
View File

@@ -0,0 +1,2 @@
static void barhover(XEvent *e, Bar *bar);
static Bar *wintobar(Window win);

43
patch/bar_alpha.c Normal file
View File

@@ -0,0 +1,43 @@
static int useargb = 0;
static Visual *visual;
static int depth;
static Colormap cmap;
void
xinitvisual()
{
XVisualInfo *infos;
XRenderPictFormat *fmt;
int nitems;
int i;
XVisualInfo tpl = {
.screen = screen,
.depth = 32,
.class = TrueColor
};
long masks = VisualScreenMask | VisualDepthMask | VisualClassMask;
infos = XGetVisualInfo(dpy, masks, &tpl, &nitems);
visual = NULL;
for (i = 0; i < nitems; i ++) {
fmt = XRenderFindVisualFormat(dpy, infos[i].visual);
if (fmt->type == PictTypeDirect && fmt->direct.alphaMask) {
visual = infos[i].visual;
depth = infos[i].depth;
cmap = XCreateColormap(dpy, root, visual, AllocNone);
useargb = 1;
break;
}
}
XFree(infos);
if (!visual) {
visual = DefaultVisual(dpy, screen);
depth = DefaultDepth(dpy, screen);
cmap = DefaultColormap(dpy, screen);
}
}

4
patch/bar_alpha.h Normal file
View File

@@ -0,0 +1,4 @@
#define OPAQUE 0xffU
static void xinitvisual();

View File

@@ -0,0 +1,7 @@
void
togglealttag()
{
selmon->alttag = !selmon->alttag;
drawbar(selmon);
}

View File

@@ -0,0 +1,2 @@
static void togglealttag();

94
patch/bar_anybar.c Normal file
View File

@@ -0,0 +1,94 @@
void
managealtbar(Window win, XWindowAttributes *wa)
{
Monitor *m;
Bar *bar;
int i = 0;
if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height)))
return;
for (bar = m->bar; bar && bar->win && bar->next; bar = bar->next); // find last bar
if (!bar) {
bar = m->bar = ecalloc(1, sizeof(Bar));
bar->topbar = topbar;
} else if (bar && bar->win) {
i = bar->idx + 1;
bar->next = ecalloc(1, sizeof(Bar));
#if BAR_ANYBAR_TOP_AND_BOTTOM_BARS_PATCH
bar->next->topbar = !bar->topbar;
#else
bar->next->topbar = topbar;
#endif // BAR_ANYBAR_TOP_AND_BOTTOM_BARS_PATCH
bar = bar->next;
}
bar->external = 1;
bar->showbar = 1;
bar->mon = m;
bar->idx = i;
bar->borderpx = 0;
bar->win = win;
bar->bw = wa->width;
bar->bh = wa->height;
updatebarpos(m);
arrange(m);
XSelectInput(dpy, win, EnterWindowMask|FocusChangeMask|PropertyChangeMask|StructureNotifyMask);
XMapWindow(dpy, win);
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
arrange(selmon);
XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
(unsigned char *) &win, 1);
}
void
spawnbar()
{
if (*altbarcmd)
system(altbarcmd);
}
void
unmanagealtbar(Window w)
{
Monitor *m = wintomon(w);
Bar *bar, *next, *prev = NULL;
if (!m)
return;
for (bar = m->bar; bar && bar->win; bar = next) {
next = bar->next;
if (bar->win == w) {
if (prev)
prev->next = next;
else
m->bar = next;
free(bar);
break;
}
prev = bar;
}
updatebarpos(m);
arrange(m);
}
int
wmclasscontains(Window win, const char *class, const char *name)
{
XClassHint ch = { NULL, NULL };
int res = 1;
if (XGetClassHint(dpy, win, &ch)) {
if (ch.res_name && strstr(ch.res_name, name) == NULL)
res = 0;
if (ch.res_class && strstr(ch.res_class, class) == NULL)
res = 0;
} else
res = 0;
if (ch.res_class)
XFree(ch.res_class);
if (ch.res_name)
XFree(ch.res_name);
return res;
}

5
patch/bar_anybar.h Normal file
View File

@@ -0,0 +1,5 @@
static void managealtbar(Window win, XWindowAttributes *wa);
static void spawnbar();
static void unmanagealtbar(Window w);
static int wmclasscontains(Window win, const char *class, const char *name);

123
patch/bar_awesomebar.c Normal file
View File

@@ -0,0 +1,123 @@
int
width_awesomebar(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_awesomebar(Bar *bar, BarArg *a)
{
int n = 0, scm, remainder = 0, tabw, tpad, tx, tw;
unsigned int i;
#if BAR_CENTEREDWINDOWNAME_PATCH
int cpad;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
#if BAR_WINICON_PATCH
int ipad;
#endif // BAR_WINICON_PATCH
#if BAR_TITLE_LEFT_PAD_PATCH && BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad;
#elif BAR_TITLE_LEFT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad / 2;
#elif BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x, w = a->w - lrpad / 2;
#else
int x = a->x, w = a->w;
#endif // BAR_TITLE_LEFT_PAD_PATCH | BAR_TITLE_RIGHT_PAD_PATCH
Client *c;
for (c = bar->mon->clients; c; c = c->next)
if (ISVISIBLE(c))
n++;
if (n > 0) {
remainder = w % n;
tabw = w / n;
for (i = 0, c = bar->mon->clients; c; c = c->next, i++) {
if (!ISVISIBLE(c))
continue;
if (bar->mon->sel == c && HIDDEN(c))
scm = SchemeHidSel;
else if (HIDDEN(c))
scm = SchemeHidNorm;
else if (bar->mon->sel == c)
scm = SchemeTitleSel;
else
scm = SchemeTitleNorm;
tpad = lrpad / 2;
#if BAR_CENTEREDWINDOWNAME_PATCH
cpad = 0;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
#if BAR_WINICON_PATCH
ipad = c->icon ? c->icw + ICONSPACING : 0;
#endif // BAR_WINICON_PATCH
tx = x;
tw = tabw;
#if BAR_WINICON_PATCH && BAR_CENTEREDWINDOWNAME_PATCH
if (TEXTW(c->name) + ipad < tabw)
cpad = (tabw - TEXTW(c->name) - ipad) / 2;
#elif BAR_CENTEREDWINDOWNAME_PATCH
if (TEXTW(c->name) < tabw)
cpad = (tabw - TEXTW(c->name)) / 2;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
drw_setscheme(drw, scheme[scm]);
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, tx, a->y, tw, a->h);
#if BAR_CENTEREDWINDOWNAME_PATCH
/* Apply center padding, if any */
tx += cpad;
tw -= cpad;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
tx += tpad;
tw -= lrpad;
#if BAR_WINICON_PATCH
if (ipad) {
drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon);
tx += ipad;
tw -= ipad;
}
#endif // BAR_WINICON_PATCH
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
drawstateindicator(c->mon, c, 1, x, a->y, tabw + (i < remainder ? 1 : 0), a->h, 0, 0, c->isfixed);
x += tabw + (i < remainder ? 1 : 0);
}
}
return n;
}
int
click_awesomebar(Bar *bar, Arg *arg, BarArg *a)
{
int x = 0, n = 0;
Client *c;
for (c = bar->mon->clients; c; c = c->next)
if (ISVISIBLE(c))
n++;
c = bar->mon->clients;
do {
if (!c || !ISVISIBLE(c))
continue;
else
x += (1.0 / (double)n) * a->w;
} while (c && a->x > x && (c = c->next));
if (c) {
arg->v = c;
return ClkWinTitle;
}
return -1;
}

4
patch/bar_awesomebar.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_awesomebar(Bar *bar, BarArg *a);
static int draw_awesomebar(Bar *bar, BarArg *a);
static int click_awesomebar(Bar *bar, Arg *arg, BarArg *a);

51
patch/bar_dwmblocks.c Normal file
View File

@@ -0,0 +1,51 @@
static int statussig;
pid_t statuspid = -1;
pid_t
getstatusbarpid()
{
char buf[32], *str = buf, *c;
FILE *fp;
if (statuspid > 0) {
snprintf(buf, sizeof(buf), "/proc/%u/cmdline", statuspid);
if ((fp = fopen(buf, "r"))) {
fgets(buf, sizeof(buf), fp);
while ((c = strchr(str, '/')))
str = c + 1;
fclose(fp);
if (!strcmp(str, STATUSBAR))
return statuspid;
}
}
if (!(fp = popen("pgrep -o "STATUSBAR, "r")))
return -1;
fgets(buf, sizeof(buf), fp);
pclose(fp);
return strtol(buf, NULL, 10);
}
void
sigstatusbar(const Arg *arg)
{
union sigval sv;
if (!statussig)
return;
if ((statuspid = getstatusbarpid()) <= 0)
return;
#if BAR_DWMBLOCKS_SIGUSR1_PATCH
sv.sival_int = (statussig << 8) | arg->i;
if (sigqueue(statuspid, SIGUSR1, sv) == -1) {
if (errno == ESRCH) {
if (!getstatusbarpid())
sigqueue(statuspid, SIGUSR1, sv);
}
}
#else
sv.sival_int = arg->i;
sigqueue(statuspid, SIGRTMIN+statussig, sv);
#endif // BAR_DWMBLOCKS_SIGUSR1_PATCH
}

3
patch/bar_dwmblocks.h Normal file
View File

@@ -0,0 +1,3 @@
static int getstatusbarpid();
static void sigstatusbar(const Arg *arg);

52
patch/bar_ewmhtags.c Normal file
View File

@@ -0,0 +1,52 @@
void
setcurrentdesktop(void)
{
long data[] = { 0 };
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}
void
setdesktopnames(void)
{
int i;
XTextProperty text;
char *tags[NUMTAGS];
for (i = 0; i < NUMTAGS; i++)
tags[i] = tagicon(selmon, i);
Xutf8TextListToTextProperty(dpy, tags, NUMTAGS, XUTF8StringStyle, &text);
XSetTextProperty(dpy, root, &text, netatom[NetDesktopNames]);
}
void
setfloatinghint(Client *c)
{
Atom target = XInternAtom(dpy, "_IS_FLOATING", 0);
unsigned int floating[1] = {c->isfloating};
XChangeProperty(dpy, c->win, target, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)floating, 1);
}
void
setnumdesktops(void)
{
long data[] = { NUMTAGS };
XChangeProperty(dpy, root, netatom[NetNumberOfDesktops], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}
void
setviewport(void)
{
long data[] = { 0, 0 };
XChangeProperty(dpy, root, netatom[NetDesktopViewport], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 2);
}
void
updatecurrentdesktop(void)
{
long rawdata[] = { selmon->tagset[selmon->seltags] };
int i = 0;
while (*rawdata >> (i + 1)) {
i++;
}
long data[] = { i };
XChangeProperty(dpy, root, netatom[NetCurrentDesktop], XA_CARDINAL, 32, PropModeReplace, (unsigned char *)data, 1);
}

7
patch/bar_ewmhtags.h Normal file
View File

@@ -0,0 +1,7 @@
static void setcurrentdesktop(void);
static void setdesktopnames(void);
static void setfloatinghint(Client *c);
static void setnumdesktops(void);
static void setviewport(void);
static void updatecurrentdesktop(void);

103
patch/bar_fancybar.c Normal file
View File

@@ -0,0 +1,103 @@
int
width_fancybar(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_fancybar(Bar *bar, BarArg *a)
{
int tabw, mw, ew = 0, n = 0, tx, tw;
#if BAR_WINICON_PATCH
int ipad;
#endif // BAR_WINICON_PATCH
unsigned int i;
Client *c;
Monitor *m = bar->mon;
#if BAR_TITLE_LEFT_PAD_PATCH && BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad;
#elif BAR_TITLE_LEFT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad / 2;
#elif BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x, w = a->w - lrpad / 2;
#else
int x = a->x, w = a->w;
#endif // BAR_TITLE_LEFT_PAD_PATCH | BAR_TITLE_RIGHT_PAD_PATCH
for (c = m->clients; c; c = c->next) {
if (ISVISIBLE(c))
n++;
}
if (n > 0) {
tabw = TEXTW(m->sel->name);
#if BAR_WINICON_PATCH
if (m->sel->icon)
tabw += m->sel->icw + ICONSPACING;
#endif // BAR_WINICON_PATCH
mw = (tabw >= w || n == 1) ? 0 : (w - tabw) / (n - 1);
i = 0;
for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c) || c == m->sel)
continue;
tabw = TEXTW(c->name);
#if BAR_WINICON_PATCH
if (c->icon)
tabw += c->icw + ICONSPACING;
#endif // BAR_WINICON_PATCH
if (tabw < mw)
ew += (mw - tabw);
else
i++;
}
if (i > 0)
mw += ew / i;
for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
tabw = MIN(m->sel == c ? w : mw, TEXTW(c->name));
#if BAR_WINICON_PATCH
ipad = c->icon ? c->icw + ICONSPACING : 0;
tabw += ipad;
#endif // BAR_WINICON_PATCH
tx = x;
tw = tabw;
drw_setscheme(drw, scheme[m->sel == c ? SchemeTitleSel : SchemeTitleNorm]);
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, tx, a->y, tw, a->h);
if (tabw <= 0) /* trap special handling of 0 in drw_text */
continue;
tx += lrpad / 2;
tw -= lrpad;
#if BAR_WINICON_PATCH
if (ipad) {
drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon);
tx += ipad;
tw -= ipad;
}
#endif // BAR_WINICON_PATCH
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
drawstateindicator(c->mon, c, 1, x, a->y, tabw, a->h, 0, 0, c->isfixed);
x += tabw;
w -= tabw;
}
}
return n;
}
int
click_fancybar(Bar *bar, Arg *arg, BarArg *a)
{
return ClkWinTitle;
}

4
patch/bar_fancybar.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_fancybar(Bar *bar, BarArg *a);
static int draw_fancybar(Bar *bar, BarArg *a);
static int click_fancybar(Bar *bar, Arg *arg, BarArg *a);

482
patch/bar_flexwintitle.c Normal file
View File

@@ -0,0 +1,482 @@
/* Flexwintitle properties, you can override these in your config.h if you want. */
#ifndef FLEXWINTITLE_BORDERS
#define FLEXWINTITLE_BORDERS 1 // 0 = off, 1 = on
#endif
#ifndef FLEXWINTITLE_SHOWFLOATING
#define FLEXWINTITLE_SHOWFLOATING 0 // whether to show titles for floating windows, hidden clients are always shown
#endif
#ifndef FLEXWINTITLE_MASTERWEIGHT
#define FLEXWINTITLE_MASTERWEIGHT 9 // master weight compared to stack, hidden and floating window titles
#endif
#ifndef FLEXWINTITLE_STACKWEIGHT
#define FLEXWINTITLE_STACKWEIGHT 3 // stack weight compared to master, hidden and floating window titles
#endif
#ifndef FLEXWINTITLE_HIDDENWEIGHT
#define FLEXWINTITLE_HIDDENWEIGHT 1 // hidden window title weight
#endif
#ifndef FLEXWINTITLE_FLOATWEIGHT
#define FLEXWINTITLE_FLOATWEIGHT 1 // floating window title weight, set to 0 to not show floating windows
#endif
#define SCHEMEFOR(c) getschemefor(m, c, groupactive == c)
enum { GRP_NOSELECTION, GRP_MASTER, GRP_STACK1, GRP_STACK2, GRP_FLOAT, GRP_HIDDEN };
int
width_flexwintitle(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_flexwintitle(Bar *bar, BarArg *a)
{
drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1);
return flextitlecalculate(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a);
}
int
click_flexwintitle(Bar *bar, Arg *arg, BarArg *a)
{
flextitlecalculate(bar->mon, 0, a->w, a->x, flextitleclick, arg, a);
return ClkWinTitle;
}
Client *
flextitledrawarea(Monitor *m, Client *c, int x, int r, int w, int max_clients, int scheme, int draw_tiled, int draw_hidden, int draw_floating,
int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg)
{
int i;
for (i = 0; c && i < max_clients; c = c->next) {
if (
ISVISIBLE(c) &&
(
(draw_tiled && !c->isfloating && !HIDDEN(c)) ||
(draw_floating && c->isfloating && !HIDDEN(c)) ||
(draw_hidden && HIDDEN(c))
)
) {
tabfn(m, c, passx, x, w + (i < r ? 1 : 0), scheme, arg, barg);
x += w + (i < r ? 1 : 0);
i++;
}
}
return c;
}
int
getschemefor(Monitor *m, int group, int activegroup)
{
switch (group) {
case GRP_NOSELECTION:
case GRP_MASTER:
case GRP_STACK1:
case GRP_STACK2:
#if BSTACK_LAYOUT
if (m->lt[m->sellt]->arrange == &bstack)
return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
#endif // BSTACK_LAYOUT
#if BSTACKHORIZ_LAYOUT
if (m->lt[m->sellt]->arrange == &bstackhoriz) {
if (group == GRP_MASTER)
return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
else
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
}
#endif // BSTACKHORIZ_LAYOUT
#if CENTEREDMASTER_LAYOUT
if (m->lt[m->sellt]->arrange == &centeredmaster)
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
#endif // CENTEREDMASTER_LAYOUT
#if CENTEREDFLOATINGMASTER_LAYOUT
if (m->lt[m->sellt]->arrange == &centeredfloatingmaster)
return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
#endif // CENTEREDFLOATINGMASTER_LAYOUT
#if COLUMNS_LAYOUT
if (m->lt[m->sellt]->arrange == &col) {
if (group == GRP_MASTER)
return (activegroup ? SchemeFlexActLTR : SchemeFlexInaLTR);
else
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
}
#endif // COLUMNS_LAYOUT
#if DECK_LAYOUT
if (m->lt[m->sellt]->arrange == &deck) {
if (group == GRP_MASTER)
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
else
return (activegroup ? SchemeFlexActMONO : SchemeFlexInaMONO);
}
#endif // DECK_LAYOUT
#if FIBONACCI_DWINDLE_LAYOUT
if (m->lt[m->sellt]->arrange == &dwindle)
return (activegroup ? SchemeFlexActDWDL : SchemeFlexInaDWDL);
#endif // FIBONACCI_DWINDLE_LAYOUT
#if FIBONACCI_SPIRAL_LAYOUT
if (m->lt[m->sellt]->arrange == &spiral)
return (activegroup ? SchemeFlexActSPRL : SchemeFlexInaSPRL);
#endif // FIBONACCI_SPIRAL_LAYOUT
#if FLEXTILE_DELUXE_LAYOUT
if (m->lt[m->sellt]->arrange == &flextile)
return (activegroup ? SchemeFlexActTTB + m->ltaxis[group] : SchemeFlexInaTTB + m->ltaxis[group]);
#endif // FLEXTILE_DELUXE_LAYOUT
#if GAPPLESSGRID_LAYOUT
if (m->lt[m->sellt]->arrange == &gaplessgrid)
return (activegroup ? SchemeFlexActGRID : SchemeFlexInaGRID);
#endif // GAPPLESSGRID_LAYOUT
#if GRIDMODE_LAYOUT
if (m->lt[m->sellt]->arrange == &grid)
return (activegroup ? SchemeFlexActGRDM : SchemeFlexInaGRDM);
#endif // GRIDMODE_LAYOUT
#if HORIZGRID_LAYOUT
if (m->lt[m->sellt]->arrange == &horizgrid)
return (activegroup ? SchemeFlexActHGRD : SchemeFlexInaHGRD);
#endif // HORIZGRID_LAYOUT
#if NROWGRID_LAYOUT
if (m->lt[m->sellt]->arrange == &nrowgrid)
return (activegroup ? SchemeFlexActGRD1 : SchemeFlexInaGRD1);
#endif // NROWGRID_LAYOUT
#if TILE_LAYOUT
if (m->lt[m->sellt]->arrange == &tile)
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB);
#endif // TILE_LAYOUT
#if MONOCLE_LAYOUT
if (m->lt[m->sellt]->arrange == &monocle)
return (activegroup ? SchemeFlexActMONO : SchemeFlexInaMONO);
#endif // MONOCLE_LAYOUT
return SchemeTitleNorm;
case GRP_HIDDEN:
return SchemeHidNorm;
case GRP_FLOAT:
return (activegroup ? SchemeFlexActFloat : SchemeFlexInaFloat);
}
return SchemeTitleNorm;
}
int
getselschemefor(int scheme)
{
if (scheme == SchemeFlexActFloat || scheme == SchemeFlexInaFloat)
return SchemeFlexSelFloat;
if (scheme >= SchemeFlexInaTTB)
return scheme + SchemeFlexInaTTB - SchemeFlexActTTB;
if (scheme >= SchemeFlexActTTB)
return scheme + SchemeFlexSelTTB - SchemeFlexActTTB;
return SchemeTitleSel;
}
void
flextitledraw(Monitor *m, Client *c, int unused, int x, int w, int tabscheme, Arg *arg, BarArg *a)
{
if (!c)
return;
int i, nclienttags = 0, nviewtags = 0;
int tpad = lrpad / 2;
#if BAR_WINICON_PATCH
int ipad = c->icon ? c->icw + ICONSPACING : 0;
#endif // BAR_WINICON_PATCH
#if BAR_CENTEREDWINDOWNAME_PATCH
int cpad = 0;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
int tx = x;
int tw = w;
int clientscheme = (
#if RENAMED_SCRATCHPADS_PATCH
c->scratchkey != 0 && c == selmon->sel
? SchemeScratchSel
: c->scratchkey != 0
? SchemeScratchNorm
:
#endif // RENAMED_SCRATCHPADS_PATCH
c == selmon->sel && HIDDEN(c)
? SchemeHidSel
: HIDDEN(c)
? SchemeHidNorm
: c == selmon->sel
? getselschemefor(tabscheme)
: c->isurgent
? SchemeUrg
: tabscheme
);
drw_setscheme(drw, scheme[clientscheme]);
XSetWindowBorder(dpy, c->win, scheme[clientscheme][ColBorder].pixel);
if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small
tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
#if BAR_WINICON_PATCH && BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) + ipad < w)
cpad = (w - TEXTW(c->name) - ipad) / 2;
#elif BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) < w)
cpad = (w - TEXTW(c->name)) / 2;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h);
#if BAR_CENTEREDWINDOWNAME_PATCH
/* Apply center padding, if any */
tx += cpad;
tw -= cpad;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
tx += tpad;
tw -= lrpad;
#if BAR_WINICON_PATCH
if (ipad) {
drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon);
tx += ipad;
tw -= ipad;
}
#endif // BAR_WINICON_PATCH
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
drawstateindicator(m, c, 1, x + 2, a->y, w, a->h, 0, 0, 0);
if (FLEXWINTITLE_BORDERS) {
XSetForeground(drw->dpy, drw->gc, scheme[SchemeSel][ColBorder].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, 1, a->h);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= a->w ? 1 : 0), a->y, 1, a->h);
}
/* Optional tags icons */
for (i = 0; i < NUMTAGS; i++) {
if ((m->tagset[m->seltags] >> i) & 1)
nviewtags++;
if ((c->tags >> i) & 1)
nclienttags++;
}
if (TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1)
drawindicator(m, c, 1, x, a->y, w, a->h, 0, 0, 0, INDICATOR_RIGHT_TAGS);
}
#ifndef HIDDEN
#define HIDDEN(C) 0
#endif
void
flextitleclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg)
{
if (passx >= x && passx <= x + w)
arg->v = c;
}
int
flextitlecalculate(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
) {
Client *c;
int n, center = 0, mirror = 0, fixed = 0; // layout configuration
int clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0, clientsnhidden = 0;
int i, w, r, num = 0, den, fulllayout = 0;
int clientsnstack2 = 0;
int groupactive = 0;
int selidx = 0;
int dualstack = 0;
int rw, rr;
int mas_x = offx, st1_x = offx, st2_x = offx, hid_x = offx, flt_x = offx;
int mas_w, st1_w, st2_w, hid_w;
for (i = 0, c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c)) {
if (FLEXWINTITLE_HIDDENWEIGHT)
clientsnhidden++;
continue;
}
if (c->isfloating) {
if (FLEXWINTITLE_FLOATWEIGHT)
clientsnfloating++;
continue;
}
if (m->sel == c)
selidx = i;
if (i < m->nmaster)
clientsnmaster++;
#if FLEXTILE_DELUXE_LAYOUT
else if (m->nstack) {
if (clientsnstack < m->nstack)
clientsnstack++;
else
clientsnstack2++;
}
#endif // FLEXTILE_DELUXE_LAYOUT
else if ((i - m->nmaster) % 2)
clientsnstack2++;
else
clientsnstack++;
i++;
}
if (!m->sel)
groupactive = GRP_NOSELECTION;
else if (HIDDEN(m->sel))
groupactive = GRP_HIDDEN;
else if (m->sel->isfloating)
groupactive = GRP_FLOAT;
else if (selidx < clientsnmaster)
groupactive = GRP_MASTER;
else if (selidx < clientsnmaster + clientsnstack)
groupactive = GRP_STACK1;
else if (selidx < clientsnmaster + clientsnstack + clientsnstack2)
groupactive = GRP_STACK2;
n = clientsnmaster + clientsnstack + clientsnstack2 + clientsnfloating + clientsnhidden;
if (n == 0)
return 0;
#if FLEXTILE_DELUXE_LAYOUT
else if (m->lt[m->sellt]->arrange == &flextile) {
int layout = m->ltaxis[LAYOUT];
if (layout < 0) {
mirror = 1;
layout *= -1;
}
if (layout > FLOATING_MASTER) {
layout -= FLOATING_MASTER;
fixed = 1;
}
if (layout == SPLIT_HORIZONTAL_DUAL_STACK || layout == SPLIT_HORIZONTAL_DUAL_STACK_FIXED)
dualstack = 1;
else if (layout == SPLIT_CENTERED_VERTICAL && (fixed || n - m->nmaster > 1))
center = 1;
else if (layout == FLOATING_MASTER)
center = 1;
else if (layout == SPLIT_CENTERED_HORIZONTAL) {
if (fixed || n - m->nmaster > 1)
center = 1;
}
}
#endif // FLEXTILE_DELUXE_LAYOUT
#if CENTEREDMASTER_LAYOUT
else if (m->lt[m->sellt]->arrange == &centeredmaster && (fixed || n - m->nmaster > 1))
center = 1;
#endif // CENTEREDMASTER_LAYOUT
#if CENTEREDFLOATINGMASTER_LAYOUT
else if (m->lt[m->sellt]->arrange == &centeredfloatingmaster)
center = 1;
#endif // CENTEREDFLOATINGMASTER_LAYOUT
/* Certain layouts have no master / stack areas */
if (!m->lt[m->sellt]->arrange // floating layout
|| (!n || (!fixed && m->nmaster && n <= m->nmaster)) // no master
#if MONOCLE_LAYOUT
|| m->lt[m->sellt]->arrange == &monocle
#endif // MONOCLE_LAYOUT
#if GRIDMODE_LAYOUT
|| m->lt[m->sellt]->arrange == &grid
#endif // GRIDMODE_LAYOUT
#if HORIZGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &horizgrid
#endif // HORIZGRID_LAYOUT
#if GAPPLESSGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &gaplessgrid
#endif // GAPPLESSGRID_LAYOUT
#if NROWGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &nrowgrid
#endif // NROWGRID_LAYOUT
#if FLEXTILE_DELUXE_LAYOUT
|| (m->lt[m->sellt]->arrange == &flextile && m->ltaxis[LAYOUT] == NO_SPLIT)
#endif // FLEXTILE_DELUXE_LAYOUT
)
fulllayout = 1;
num = tabw;
c = m->clients;
/* floating mode */
if ((fulllayout && FLEXWINTITLE_FLOATWEIGHT > 0) || clientsnmaster + clientsnstack == 0 || !m->lt[m->sellt]->arrange) {
den = clientsnmaster + clientsnstack + clientsnstack2 + clientsnfloating + clientsnhidden;
w = num / den;
r = num % den; // rest
c = flextitledrawarea(m, c, mas_x, r, w, den, !m->lt[m->sellt]->arrange ? SchemeFlexActFloat : SCHEMEFOR(GRP_MASTER), 1, FLEXWINTITLE_HIDDENWEIGHT, FLEXWINTITLE_FLOATWEIGHT, passx, tabfn, arg, barg); // floating
/* no master and stack mode, e.g. monocole, grid layouts, fibonacci */
} else if (fulllayout) {
den = clientsnmaster + clientsnstack + clientsnstack2 + clientsnhidden;
w = num / den;
r = num % den; // rest
c = flextitledrawarea(m, c, mas_x, r, w, den, SCHEMEFOR(GRP_MASTER), 1, FLEXWINTITLE_HIDDENWEIGHT, 0, passx, tabfn, arg, barg); // full
/* tiled mode */
} else {
den = clientsnmaster * FLEXWINTITLE_MASTERWEIGHT + (clientsnstack + clientsnstack2) * FLEXWINTITLE_STACKWEIGHT + clientsnfloating * FLEXWINTITLE_FLOATWEIGHT + clientsnhidden * FLEXWINTITLE_HIDDENWEIGHT;
w = num / den; // weight width per client
r = num % den; // weight rest width
rw = r / n; // rest incr per client
rr = r % n; // rest rest
#if FLEXTILE_DELUXE_LAYOUT
if ((!center && !dualstack) || (center && n <= m->nmaster + (m->nstack ? m->nstack : 1)))
#else
if ((!center && !dualstack) || (center && n <= m->nmaster + 1))
#endif // FLEXTILE_DELUXE_LAYOUT
{
clientsnstack += clientsnstack2;
clientsnstack2 = 0;
if (groupactive == GRP_STACK2)
groupactive = GRP_STACK1;
}
mas_w = clientsnmaster * rw + w * clientsnmaster * FLEXWINTITLE_MASTERWEIGHT + (rr > 0 ? MIN(rr, clientsnmaster) : 0);
rr -= clientsnmaster;
st1_w = clientsnstack * (rw + w * FLEXWINTITLE_STACKWEIGHT) + (rr > 0 ? MIN(rr, clientsnstack) : 0);
rr -= clientsnstack;
st2_w = clientsnstack2 * (rw + w * FLEXWINTITLE_STACKWEIGHT) + (rr > 0 ? MIN(rr, clientsnstack2) : 0);
rr -= clientsnstack2;
hid_w = clientsnhidden * (rw + w * FLEXWINTITLE_HIDDENWEIGHT) + (rr > 0 ? MIN(rr, clientsnhidden) : 0);
rr -= clientsnhidden;
rr = r % n;
if (mirror) {
if (center && clientsnstack2) {
mas_x = st1_x + st1_w;
st2_x = mas_x + mas_w;
hid_x = st2_x + st2_w;
} else {
if (clientsnstack2) {
st2_x = st1_x + st1_w;
mas_x = st2_x + st2_w;
} else
mas_x = st1_x + st1_w;
hid_x = mas_x + mas_w;
}
} else {
if (center && clientsnstack2) {
mas_x = st2_x + st2_w;
st1_x = mas_x + mas_w;
hid_x = st1_x + st1_w;
} else {
st1_x = mas_x + mas_w;
if (clientsnstack2) {
st2_x = st1_x + st1_w;
hid_x = st2_x + st2_w;
} else
hid_x = st1_x + st1_w;
}
}
flt_x = hid_x + hid_w;
c = flextitledrawarea(m, c, mas_x, rr, w * FLEXWINTITLE_MASTERWEIGHT + rw, clientsnmaster, SCHEMEFOR(GRP_MASTER), 1, 0, 0, passx, tabfn, arg, barg); // master
rr -= clientsnmaster;
c = flextitledrawarea(m, c, st1_x, rr, w * FLEXWINTITLE_STACKWEIGHT + rw, clientsnstack, SCHEMEFOR(GRP_STACK1), 1, 0, 0, passx, tabfn, arg, barg); // stack1
rr -= clientsnstack;
if (clientsnstack2) {
c = flextitledrawarea(m, c, st2_x, rr, w * FLEXWINTITLE_STACKWEIGHT + rw, clientsnstack2, SCHEMEFOR(GRP_STACK2), 1, 0, 0, passx, tabfn, arg, barg); // stack2
rr -= clientsnstack2;
}
c = flextitledrawarea(m, m->clients, hid_x, rr, w * FLEXWINTITLE_HIDDENWEIGHT + rw, clientsnhidden, SCHEMEFOR(GRP_HIDDEN), 0, 1, 0, passx, tabfn, arg, barg); // hidden
rr -= clientsnhidden;
c = flextitledrawarea(m, m->clients, flt_x, rr, w * FLEXWINTITLE_FLOATWEIGHT + rw, clientsnfloating, SCHEMEFOR(GRP_FLOAT), 0, 0, 1, passx, tabfn, arg, barg); // floating
}
return 1;
}

11
patch/bar_flexwintitle.h Normal file
View File

@@ -0,0 +1,11 @@
static int width_flexwintitle(Bar *bar, BarArg *a);
static int draw_flexwintitle(Bar *bar, BarArg *a);
static int click_flexwintitle(Bar *bar, Arg *arg, BarArg *a);
static void flextitledraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *barg);
static void flextitleclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg);
static int flextitlecalculate(Monitor *m, int offx, int w, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg);
static int getschemefor(Monitor *m, int group, int activegroup);
static int getselschemefor(int scheme);
static Client *flextitledrawarea(Monitor *m, Client *c, int x, int r, int w, int max_clients, int tabscheme, int draw_tiled, int draw_hidden, int draw_floating, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg);

43
patch/bar_holdbar.c Normal file
View File

@@ -0,0 +1,43 @@
void
holdbar(const Arg *arg)
{
if (selmon->showbar)
return;
Bar *bar;
selmon->showbar = 2;
updatebarpos(selmon);
for (bar = selmon->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
drawbar(selmon);
}
void
keyrelease(XEvent *e)
{
Bar *bar;
if (XEventsQueued(dpy, QueuedAfterReading)) {
XEvent ne;
XPeekEvent(dpy, &ne);
if (ne.type == KeyPress && ne.xkey.time == e->xkey.time &&
ne.xkey.keycode == e->xkey.keycode) {
XNextEvent(dpy, &ne);
return;
}
}
if (e->xkey.keycode == XKeysymToKeycode(dpy, HOLDKEY) && selmon->showbar == 2) {
selmon->showbar = 0;
updatebarpos(selmon);
for (bar = selmon->bar; bar; bar = bar->next)
XMoveResizeWindow(dpy, bar->win, bar->bx, bar->by, bar->bw, bar->bh);
#if BAR_SYSTRAY_PATCH
if (!selmon->showbar && systray)
XMoveWindow(dpy, systray->win, -32000, -32000);
#endif // BAR_SYSTRAY_PATCH
arrange(selmon);
}
#if COMBO_PATCH
combo = 0;
#endif // COMBO_PATCH
}

3
patch/bar_holdbar.h Normal file
View File

@@ -0,0 +1,3 @@
static void keyrelease(XEvent *e);
static void holdbar(const Arg *arg);

111
patch/bar_indicators.c Normal file
View File

@@ -0,0 +1,111 @@
/* Indicator properties, you can override these in your config.h if you want. */
#ifndef TAGSINDICATOR
#define TAGSINDICATOR 1 // 0 = off, 1 = on if >1 client/view tag, 2 = always on
#endif
#ifndef TAGSPX
#define TAGSPX 5 // # pixels for tag grid boxes
#endif
#ifndef TAGSROWS
#define TAGSROWS 3 // # rows in tag grid (9 tags, e.g. 3x3)
#endif
void
drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type)
{
int i, boxw, boxs, indn = 0;
if (!(occ & 1 << tag) || type == INDICATOR_NONE)
return;
boxs = drw->fonts->h / 9;
boxw = drw->fonts->h / 6 + 2;
if (filled == -1)
filled = m == selmon && m->sel && m->sel->tags & 1 << tag;
switch (type) {
default:
case INDICATOR_TOP_LEFT_SQUARE:
drw_rect(drw, x + boxs, y + boxs, boxw, boxw, filled, invert);
break;
case INDICATOR_TOP_LEFT_LARGER_SQUARE:
drw_rect(drw, x + boxs + 2, y + boxs+1, boxw+1, boxw+1, filled, invert);
break;
case INDICATOR_TOP_BAR:
drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), boxw/2, filled, invert);
break;
case INDICATOR_TOP_BAR_SLIM:
drw_rect(drw, x + boxw, y, w - ( 2 * boxw + 1), 1, 0, invert);
break;
case INDICATOR_BOTTOM_BAR:
drw_rect(drw, x + boxw, y + h - boxw/2, w - ( 2 * boxw + 1), boxw/2, filled, invert);
break;
case INDICATOR_BOTTOM_BAR_SLIM:
drw_rect(drw, x + boxw, y + h - 1, w - ( 2 * boxw + 1), 1, 0, invert);
break;
case INDICATOR_BOX:
drw_rect(drw, x + boxw, y, w - 2 * boxw, h, 0, invert);
break;
case INDICATOR_BOX_WIDER:
drw_rect(drw, x + boxw/2, y, w - boxw, h, 0, invert);
break;
case INDICATOR_BOX_FULL:
drw_rect(drw, x, y, w - 2, h, 0, invert);
break;
case INDICATOR_CLIENT_DOTS:
for (c = m->clients; c; c = c->next) {
if (c->tags & (1 << tag)) {
drw_rect(drw, x, 1 + (indn * 2), m->sel == c ? 6 : 1, 1, 1, invert);
indn++;
}
if (h <= 1 + (indn * 2)) {
indn = 0;
x += 2;
}
}
break;
case INDICATOR_RIGHT_TAGS:
if (!c)
break;
for (i = 0; i < NUMTAGS; i++) {
drw_rect(drw,
( x + w - 2 - ((NUMTAGS / TAGSROWS) * TAGSPX)
- (i % (NUMTAGS/TAGSROWS)) + ((i % (NUMTAGS / TAGSROWS)) * TAGSPX)
),
( y + 2 + ((i / (NUMTAGS/TAGSROWS)) * TAGSPX)
- ((i / (NUMTAGS/TAGSROWS)))
),
TAGSPX, TAGSPX, (c->tags >> i) & 1, 0
);
}
break;
case INDICATOR_PLUS_AND_LARGER_SQUARE:
boxs += 2;
boxw += 2;
/* falls through */
case INDICATOR_PLUS_AND_SQUARE:
drw_rect(drw, x + boxs, y + boxs, boxw % 2 ? boxw : boxw + 1, boxw % 2 ? boxw : boxw + 1, filled, invert);
/* falls through */
case INDICATOR_PLUS:
if (!(boxw % 2))
boxw += 1;
drw_rect(drw, x + boxs + boxw / 2, y + boxs, 1, boxw, filled, invert); // |
drw_rect(drw, x + boxs, y + boxs + boxw / 2, boxw + 1, 1, filled, invert); //
break;
}
}
void
drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert)
{
#if FAKEFULLSCREEN_CLIENT_PATCH && !FAKEFULLSCREEN_PATCH
if (c->fakefullscreen && c->isfloating)
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatfakefsindicatortype);
else if (c->fakefullscreen)
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, fakefsindicatortype);
else
#endif // FAKEFULLSCREEN_CLIENT_PATCH
if (c->isfloating)
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, floatindicatortype);
else
drawindicator(m, c, occ, x, y, w, h, tag, filled, invert, tiledindicatortype);
}

21
patch/bar_indicators.h Normal file
View File

@@ -0,0 +1,21 @@
enum {
INDICATOR_NONE,
INDICATOR_TOP_LEFT_SQUARE,
INDICATOR_TOP_LEFT_LARGER_SQUARE,
INDICATOR_TOP_BAR,
INDICATOR_TOP_BAR_SLIM,
INDICATOR_BOTTOM_BAR,
INDICATOR_BOTTOM_BAR_SLIM,
INDICATOR_BOX,
INDICATOR_BOX_WIDER,
INDICATOR_BOX_FULL,
INDICATOR_CLIENT_DOTS,
INDICATOR_RIGHT_TAGS,
INDICATOR_PLUS,
INDICATOR_PLUS_AND_SQUARE,
INDICATOR_PLUS_AND_LARGER_SQUARE,
};
static void drawindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert, int type);
static void drawstateindicator(Monitor *m, Client *c, unsigned int occ, int x, int y, int w, int h, unsigned int tag, int filled, int invert);

18
patch/bar_layoutmenu.c Normal file
View File

@@ -0,0 +1,18 @@
void
layoutmenu(const Arg *arg) {
FILE *p;
char c[3], *s;
int i;
if (!(p = popen(layoutmenu_cmd, "r")))
return;
s = fgets(c, sizeof(c), p);
pclose(p);
if (!s || *s == '\0' || c[0] == '\0')
return;
i = atoi(c);
setlayout(&((Arg) { .v = &layouts[i] }));
}

2
patch/bar_layoutmenu.h Normal file
View File

@@ -0,0 +1,2 @@
static void layoutmenu(const Arg *arg);

18
patch/bar_ltsymbol.c Normal file
View File

@@ -0,0 +1,18 @@
int
width_ltsymbol(Bar *bar, BarArg *a)
{
return TEXTW(bar->mon->ltsymbol);
}
int
draw_ltsymbol(Bar *bar, BarArg *a)
{
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, bar->mon->ltsymbol, 0, False);
}
int
click_ltsymbol(Bar *bar, Arg *arg, BarArg *a)
{
return ClkLtSymbol;
}

4
patch/bar_ltsymbol.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_ltsymbol(Bar *bar, BarArg *a);
static int draw_ltsymbol(Bar *bar, BarArg *a);
static int click_ltsymbol(Bar *bar, Arg *arg, BarArg *a);

View File

@@ -0,0 +1,122 @@
static Clr **statusscheme;
int
width_pwrl_status(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return widthpowerlinestatus(rawstext);
#else
return widthpowerlinestatus(stext);
#endif // BAR_STATUSCMD_PATCH
}
#if BAR_EXTRASTATUS_PATCH
int
width_pwrl_status_es(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return widthpowerlinestatus(rawestext);
#else
return widthpowerlinestatus(estext);
#endif // BAR_STATUSCMD_PATCH
}
#endif // BAR_EXTRASTATUS_PATCH
int
draw_pwrl_status(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return drawpowerlinestatus(a->x + a->w, rawstext, a);
#else
return drawpowerlinestatus(a->x + a->w, stext, a);
#endif // BAR_STATUSCMD_PATCH
}
#if BAR_EXTRASTATUS_PATCH
int
draw_pwrl_status_es(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return drawpowerlinestatus(a->x + a->w, rawestext, a);
#else
return drawpowerlinestatus(a->x + a->w, estext, a);
#endif // BAR_STATUSCMD_PATCH
}
#endif // BAR_EXTRASTATUS_PATCH
int
click_pwrl_status(Bar *bar, Arg *arg, BarArg *a)
{
return ClkStatusText;
}
int
widthpowerlinestatus(char *stext)
{
char status[512];
int w = 0, i, n = strlen(stext);
int plw = drw->fonts->h / 2 + 1;
char *bs, bp = '|';
strcpy(status, stext);
for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) {
if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '>' || *bs == '|') { /* block start */
if (bp != '|')
w += plw;
w += TEXTW(bs+2);
bp = *bs;
*bs = 0;
}
}
if (bp != '|')
w += plw * 2;
return w;
}
int
drawpowerlinestatus(int xpos, char *stext, BarArg *barg)
{
char status[512];
int i, n = strlen(stext), cn = 0;
int x = xpos, w = 0;
int plw = drw->fonts->h / 2 + 1;
char *bs, bp = '|';
Clr *prevscheme = statusscheme[0], *nxtscheme;
strcpy(status, stext);
for (i = n, bs = &status[n-1]; i >= 0; i--, bs--) {
if (*bs == '<' || *bs == '/' || *bs == '\\' || *bs == '>' || *bs == '|') { /* block start */
cn = ((int) *(bs+1)) - 1;
if (cn < LENGTH(statuscolors)) {
drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[cn]));
} else {
drw_settrans(drw, prevscheme, (nxtscheme = statusscheme[0]));
}
if (bp != '|') {
drw_arrow(drw, x - plw, barg->y, plw, barg->h, bp == '\\' || bp == '>' ? 1 : 0, bp == '<' ? 0 : 1);
x -= plw;
}
drw_setscheme(drw, nxtscheme);
w = TEXTW(bs+2);
drw_text(drw, x - w, barg->y, w, barg->h, lrpad / 2, bs+2, 0, False);
x -= w;
bp = *bs;
*bs = 0;
prevscheme = nxtscheme;
}
}
if (bp != '|') {
drw_settrans(drw, prevscheme, scheme[SchemeNorm]);
drw_arrow(drw, x - plw, barg->y, plw, barg->h, bp == '\\' || bp == '>' ? 1 : 0, bp == '<' ? 0 : 1);
drw_rect(drw, x - 2 * plw, barg->y, plw, barg->h, 1, 1);
x -= plw * 2;
}
return xpos - x;
}

View File

@@ -0,0 +1,12 @@
static int width_pwrl_status(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int width_pwrl_status_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int draw_pwrl_status(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int draw_pwrl_status_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int click_pwrl_status(Bar *bar, Arg *arg, BarArg *a);
static int drawpowerlinestatus(int x, char *stext, BarArg *a);
static int widthpowerlinestatus(char *stext);

107
patch/bar_powerline_tags.c Normal file
View File

@@ -0,0 +1,107 @@
int
width_pwrl_tags(Bar *bar, BarArg *a)
{
int w, i;
int plw = drw->fonts->h / 2 + 1;
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
for (w = 0, i = 0; i < NUMTAGS; i++) {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
w += TEXTW(tagicon(bar->mon, i)) + plw;
}
return w + lrpad;
}
int
draw_pwrl_tags(Bar *bar, BarArg *a)
{
int x, w;
int invert;
int plw = drw->fonts->h / 2 + 1;
unsigned int i, occ = 0, urg = 0;
char *icon;
Client *c;
Clr *prevscheme, *nxtscheme;
for (c = bar->mon->clients; c; c = c->next) {
#if BAR_HIDEVACANTTAGS_PATCH
occ |= c->tags == 255 ? 0 : c->tags;
#else
occ |= c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
if (c->isurgent)
urg |= c->tags;
}
x = a->x;
prevscheme = scheme[SchemeNorm];
for (i = 0; i < NUMTAGS; i++) {
#if BAR_HIDEVACANTTAGS_PATCH
/* do not draw vacant tags */
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
icon = tagicon(bar->mon, i);
invert = 0;
w = TEXTW(icon);
if (urg & 1 << i) {
drw_settrans(drw, prevscheme, (nxtscheme = scheme[bar->mon->tagset[bar->mon->seltags] & 1 << i ? SchemeSel : SchemeUrg]));
} else {
drw_settrans(drw, prevscheme, (nxtscheme = scheme[bar->mon->tagset[bar->mon->seltags] & 1 << i ? SchemeSel : SchemeNorm]));
}
#if BAR_POWERLINE_TAGS_SLASH_PATCH
drw_arrow(drw, x, a->y, plw, a->h, 1, 1);
#else
drw_arrow(drw, x, a->y, plw, a->h, 1, 0);
#endif // BAR_POWERLINE_TAGS_SLASH_PATCH
x += plw;
drw_setscheme(drw, nxtscheme);
drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False);
drawindicator(bar->mon, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype);
x += w;
prevscheme = nxtscheme;
}
nxtscheme = scheme[SchemeNorm];
drw_settrans(drw, prevscheme, nxtscheme);
#if BAR_POWERLINE_TAGS_SLASH_PATCH
drw_arrow(drw, x, a->y, plw, a->h, 1, 1);
#else
drw_arrow(drw, x, a->y, plw, a->h, 1, 0);
#endif // BAR_POWERLINE_TAGS_SLASH_PATCH
return 1;
}
int
click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a)
{
int i = 0, x = lrpad / 2;
int plw = drw->fonts->h / 2 + 1;
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
do {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
x += TEXTW(tagicon(bar->mon, i)) + plw;
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
arg->ui = 1 << i;
}
return ClkTagBar;
}

View File

@@ -0,0 +1,4 @@
static int width_pwrl_tags(Bar *bar, BarArg *a);
static int draw_pwrl_tags(Bar *bar, BarArg *a);
static int click_pwrl_tags(Bar *bar, Arg *arg, BarArg *a);

34
patch/bar_status.c Normal file
View File

@@ -0,0 +1,34 @@
int
width_status(Bar *bar, BarArg *a)
{
return TEXTWM(stext);
}
#if BAR_EXTRASTATUS_PATCH
int
width_status_es(Bar *bar, BarArg *a)
{
return TEXTWM(estext) - lrpad;
}
#endif // BAR_EXTRASTATUS_PATCH
int
draw_status(Bar *bar, BarArg *a)
{
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, stext, 0, True);
}
#if BAR_EXTRASTATUS_PATCH
int
draw_status_es(Bar *bar, BarArg *a)
{
return drw_text(drw, a->x, a->y, a->w, a->h, 0, estext, 0, True);
}
#endif // BAR_EXTRASTATUS_PATCH
int
click_status(Bar *bar, Arg *arg, BarArg *a)
{
return ClkStatusText;
}

10
patch/bar_status.h Normal file
View File

@@ -0,0 +1,10 @@
static int width_status(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int width_status_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int draw_status(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int draw_status_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int click_status(Bar *bar, Arg *arg, BarArg *a);

268
patch/bar_status2d.c Normal file
View File

@@ -0,0 +1,268 @@
#if BAR_STATUS2D_XRDB_TERMCOLORS_PATCH
static char termcol0[] = "#000000"; /* black */
static char termcol1[] = "#ff0000"; /* red */
static char termcol2[] = "#33ff00"; /* green */
static char termcol3[] = "#ff0099"; /* yellow */
static char termcol4[] = "#0066ff"; /* blue */
static char termcol5[] = "#cc00ff"; /* magenta */
static char termcol6[] = "#00ffff"; /* cyan */
static char termcol7[] = "#d0d0d0"; /* white */
static char termcol8[] = "#808080"; /* black */
static char termcol9[] = "#ff0000"; /* red */
static char termcol10[] = "#33ff00"; /* green */
static char termcol11[] = "#ff0099"; /* yellow */
static char termcol12[] = "#0066ff"; /* blue */
static char termcol13[] = "#cc00ff"; /* magenta */
static char termcol14[] = "#00ffff"; /* cyan */
static char termcol15[] = "#ffffff"; /* white */
static char *termcolor[] = {
termcol0, termcol1, termcol2, termcol3, termcol4, termcol5, termcol6, termcol7,
termcol8, termcol9, termcol10, termcol11, termcol12, termcol13, termcol14, termcol15,
};
#endif // BAR_STATUS2D_XRDB_TERMCOLORS_PATCH
int
width_status2d(Bar *bar, BarArg *a)
{
int width;
#if BAR_EXTRASTATUS_PATCH || BAR_STATUSCMD_PATCH
width = status2dtextlength(rawstext);
#else
width = status2dtextlength(stext);
#endif // #if BAR_EXTRASTATUS_PATCH | BAR_STATUSCMD_PATCH
return width ? width + lrpad : 0;
}
#if BAR_EXTRASTATUS_PATCH
int
width_status2d_es(Bar *bar, BarArg *a)
{
int width;
#if BAR_STATUSCMD_PATCH
width = status2dtextlength(rawestext);
#else
width = status2dtextlength(estext);
#endif // BAR_STATUSCMD_PATCH
return width ? width + lrpad : 0;
}
#endif // BAR_EXTRASTATUS_PATCH
int
draw_status2d(Bar *bar, BarArg *a)
{
#if BAR_EXTRASTATUS_PATCH || BAR_STATUSCMD_PATCH
return drawstatusbar(a, rawstext);
#else
return drawstatusbar(a, stext);
#endif // #if BAR_EXTRASTATUS_PATCH | BAR_STATUSCMD_PATCH
}
#if BAR_EXTRASTATUS_PATCH
int
draw_status2d_es(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return drawstatusbar(a, rawestext);
#else
return drawstatusbar(a, estext);
#endif // BAR_STATUSCMD_PATCH
}
#endif // BAR_EXTRASTATUS_PATCH
#if !BAR_STATUSCMD_PATCH
int
click_status2d(Bar *bar, Arg *arg, BarArg *a)
{
return ClkStatusText;
}
#endif // BAR_STATUSCMD_PATCH
int
drawstatusbar(BarArg *a, char* stext)
{
int i, w, len;
int x = a->x;
int y = a->y;
short isCode = 0;
char *text;
char *p;
Clr oldbg, oldfg;
len = strlen(stext);
if (!(text = (char*) malloc(sizeof(char)*(len + 1))))
die("malloc");
p = text;
#if BAR_STATUSCMD_PATCH
copyvalidchars(text, stext);
#else
memcpy(text, stext, len);
#endif // BAR_STATUSCMD_PATCH
x += lrpad / 2;
drw_setscheme(drw, scheme[LENGTH(colors)]);
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
/* process status text */
i = -1;
while (text[++i]) {
if (text[i] == '^' && !isCode) {
isCode = 1;
text[i] = '\0';
w = TEXTWM(text) - lrpad;
drw_text(drw, x, y, w, bh, 0, text, 0, True);
x += w;
/* process code */
while (text[++i] != '^') {
if (text[i] == 'c') {
char buf[8];
if (i + 7 >= len) {
i += 7;
len = 0;
break;
}
memcpy(buf, (char*)text+i+1, 7);
buf[7] = '\0';
#if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColFg], buf, 0xff);
#elif BAR_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColFg], buf, alphas[SchemeNorm][ColFg]);
#else
drw_clr_create(drw, &drw->scheme[ColFg], buf);
#endif // BAR_ALPHA_PATCH
i += 7;
} else if (text[i] == 'b') {
char buf[8];
if (i + 7 >= len) {
i += 7;
len = 0;
break;
}
memcpy(buf, (char*)text+i+1, 7);
buf[7] = '\0';
#if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColBg], buf, 0xff);
#elif BAR_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColBg], buf, alphas[SchemeNorm][ColBg]);
#else
drw_clr_create(drw, &drw->scheme[ColBg], buf);
#endif // BAR_ALPHA_PATCH
i += 7;
#if BAR_STATUS2D_XRDB_TERMCOLORS_PATCH
} else if (text[i] == 'C') {
int c = atoi(text + ++i) % 16;
#if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColFg], termcolor[c], 0xff);
#elif BAR_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColFg], termcolor[c], alphas[SchemeNorm][ColBg]);
#else
drw_clr_create(drw, &drw->scheme[ColFg], termcolor[c]);
#endif // BAR_ALPHA_PATCH
} else if (text[i] == 'B') {
int c = atoi(text + ++i) % 16;
#if BAR_ALPHA_PATCH && BAR_STATUS2D_NO_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColBg], termcolor[c], 0xff);
#elif BAR_ALPHA_PATCH
drw_clr_create(drw, &drw->scheme[ColBg], termcolor[c], alphas[SchemeNorm][ColBg]);
#else
drw_clr_create(drw, &drw->scheme[ColBg], termcolor[c]);
#endif // BAR_ALPHA_PATCH
#endif // BAR_STATUS2D_XRDB_TERMCOLORS_PATCH
} else if (text[i] == 'd') {
drw->scheme[ColFg] = scheme[SchemeNorm][ColFg];
drw->scheme[ColBg] = scheme[SchemeNorm][ColBg];
} else if (text[i] == 'w') {
Clr swp;
swp = drw->scheme[ColFg];
drw->scheme[ColFg] = drw->scheme[ColBg];
drw->scheme[ColBg] = swp;
} else if (text[i] == 'v') {
oldfg = drw->scheme[ColFg];
oldbg = drw->scheme[ColBg];
} else if (text[i] == 't') {
drw->scheme[ColFg] = oldfg;
drw->scheme[ColBg] = oldbg;
} else if (text[i] == 'r') {
int rx = atoi(text + ++i);
while (text[++i] != ',');
int ry = atoi(text + ++i);
while (text[++i] != ',');
int rw = atoi(text + ++i);
while (text[++i] != ',');
int rh = atoi(text + ++i);
if (ry < 0)
ry = 0;
if (rx < 0)
rx = 0;
drw_rect(drw, rx + x, y + ry, rw, rh, 1, 0);
} else if (text[i] == 'f') {
x += atoi(text + ++i);
}
}
text = text + i + 1;
len -= i + 1;
i = -1;
isCode = 0;
if (len <= 0)
break;
}
}
if (!isCode && len > 0) {
w = TEXTWM(text) - lrpad;
drw_text(drw, x, y, w, bh, 0, text, 0, True);
x += w;
}
free(p);
drw_setscheme(drw, scheme[SchemeNorm]);
return 1;
}
int
status2dtextlength(char* stext)
{
int i, w, len;
short isCode = 0;
char *text;
char *p;
len = strlen(stext) + 1;
if (!(text = (char*) malloc(sizeof(char)*len)))
die("malloc");
p = text;
#if BAR_STATUSCMD_PATCH
copyvalidchars(text, stext);
#else
memcpy(text, stext, len);
#endif // BAR_STATUSCMD_PATCH
/* compute width of the status text */
w = 0;
i = -1;
while (text[++i]) {
if (text[i] == '^') {
if (!isCode) {
isCode = 1;
text[i] = '\0';
w += TEXTWM(text) - lrpad;
text[i] = '^';
if (text[++i] == 'f')
w += atoi(text + ++i);
} else {
isCode = 0;
text = text + i + 1;
i = -1;
}
}
}
if (!isCode)
w += TEXTWM(text) - lrpad;
free(p);
return w;
}

14
patch/bar_status2d.h Normal file
View File

@@ -0,0 +1,14 @@
static int width_status2d(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int width_status2d_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int draw_status2d(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int draw_status2d_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
#if !BAR_STATUSCMD_PATCH
static int click_status2d(Bar *bar, Arg *arg, BarArg *a);
#endif // BAR_STATUSCMD_PATCH
static int drawstatusbar(BarArg *a, char *text);
static int status2dtextlength(char *stext);

18
patch/bar_statusbutton.c Normal file
View File

@@ -0,0 +1,18 @@
int
width_stbutton(Bar *bar, BarArg *a)
{
return TEXTW(buttonbar);
}
int
draw_stbutton(Bar *bar, BarArg *a)
{
return drw_text(drw, a->x, a->y, a->w, a->h, lrpad / 2, buttonbar, 0, False);
}
int
click_stbutton(Bar *bar, Arg *arg, BarArg *a)
{
return ClkButton;
}

4
patch/bar_statusbutton.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_stbutton(Bar *bar, BarArg *a);
static int draw_stbutton(Bar *bar, BarArg *a);
static int click_stbutton(Bar *bar, Arg *arg, BarArg *a);

79
patch/bar_statuscmd.c Normal file
View File

@@ -0,0 +1,79 @@
#if !BAR_DWMBLOCKS_PATCH
static const char statusexport[] = "export BUTTON=-;";
static int statuscmdn;
static char lastbutton[] = "-";
#endif // BAR_DWMBLOCKS_PATCH
int
click_statuscmd(Bar *bar, Arg *arg, BarArg *a)
{
return click_statuscmd_text(arg, a->x, rawstext);
}
#if BAR_EXTRASTATUS_PATCH
int
click_statuscmd_es(Bar *bar, Arg *arg, BarArg *a)
{
return click_statuscmd_text(arg, a->x, rawestext);
}
#endif // BAR_EXTRASTATUS_PATCH
int
click_statuscmd_text(Arg *arg, int rel_x, char *text)
{
int i = -1;
int x = 0;
char ch;
#if BAR_DWMBLOCKS_PATCH
statussig = -1;
#else
statuscmdn = 0;
#endif // BAR_DWMBLOCKS_PATCH
while (text[++i]) {
if ((unsigned char)text[i] < ' ') {
#if BAR_STATUSCOLORS_PATCH
if (text[i] < 17)
continue;
#endif // BAR_STATUSCOLORS_PATCH
ch = text[i];
text[i] = '\0';
#if BAR_STATUS2D_PATCH && !BAR_STATUSCOLORS_PATCH
x += status2dtextlength(text);
#else
x += TEXTWM(text) - lrpad;
#endif // BAR_STATUS2D_PATCH
text[i] = ch;
text += i+1;
i = -1;
#if BAR_DWMBLOCKS_PATCH
if (x >= rel_x && statussig != -1)
break;
statussig = ch;
#else
if (x >= rel_x)
break;
if (ch <= LENGTH(statuscmds))
statuscmdn = ch;
#endif // BAR_DWMBLOCKS_PATCH
}
}
#if BAR_DWMBLOCKS_PATCH
if (statussig == -1)
statussig = 0;
#endif // BAR_DWMBLOCKS_PATCH
return ClkStatusText;
}
void
copyvalidchars(char *text, char *rawtext)
{
int i = -1, j = 0;
while (rawtext[++i]) {
if ((unsigned char)rawtext[i] >= ' ') {
text[j++] = rawtext[i];
}
}
text[j] = '\0';
}

12
patch/bar_statuscmd.h Normal file
View File

@@ -0,0 +1,12 @@
static int click_statuscmd(Bar *bar, Arg *arg, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int click_statuscmd_es(Bar *bar, Arg *arg, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int click_statuscmd_text(Arg *arg, int rel_x, char *text);
static void copyvalidchars(char *text, char *rawtext);
typedef struct {
const char *cmd;
int id;
} StatusCmd;

102
patch/bar_statuscolors.c Normal file
View File

@@ -0,0 +1,102 @@
int
width_statuscolors(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return textw_wosc(rawstext);
#else
return textw_wosc(stext);
#endif // BAR_STATUSCMD_PATCH
}
#if BAR_EXTRASTATUS_PATCH
int
width_statuscolors_es(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return textw_wosc(rawestext);
#else
return textw_wosc(estext);
#endif // BAR_STATUSCMD_PATCH
}
#endif // BAR_EXTRASTATUS_PATCH
int
draw_statuscolors(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return draw_wosc(bar, a, rawstext);
#else
return draw_wosc(bar, a, stext);
#endif // BAR_STATUSCMD_PATCH
}
#if BAR_EXTRASTATUS_PATCH
int
draw_statuscolors_es(Bar *bar, BarArg *a)
{
#if BAR_STATUSCMD_PATCH
return draw_wosc(bar, a, rawestext);
#else
return draw_wosc(bar, a, estext);
#endif // BAR_STATUSCMD_PATCH
}
#endif // BAR_EXTRASTATUS_PATCH
#if !BAR_STATUSCMD_PATCH
int
click_statuscolors(Bar *bar, Arg *arg, BarArg *a)
{
return ClkStatusText;
}
#endif // BAR_STATUSCMD_PATCH
int
textw_wosc(char *s)
{
char *ts = s;
char *tp = s;
int sw = 0;
char ctmp;
while (1) {
if ((unsigned int)*ts > LENGTH(colors)) {
ts++;
continue;
}
ctmp = *ts;
*ts = '\0';
sw += drw_fontset_getwidth(drw, tp, True);
*ts = ctmp;
if (ctmp == '\0')
break;
tp = ++ts;
}
return sw;
}
int
draw_wosc(Bar *bar, BarArg *a, char *s)
{
char *ts = s;
char *tp = s;
int tx = 0;
char ctmp;
while (1) {
if ((unsigned int)*ts > LENGTH(colors)) {
ts++;
continue;
}
ctmp = *ts;
*ts = '\0';
drw_text(drw, a->x + tx, a->y, a->w - tx, a->h, 0, tp, 0, True);
tx += TEXTW(tp) - lrpad;
if (ctmp == '\0')
break;
drw_setscheme(drw, scheme[(unsigned int)(ctmp-1)]);
*ts = ctmp;
tp = ++ts;
}
return 1;
}

13
patch/bar_statuscolors.h Normal file
View File

@@ -0,0 +1,13 @@
static int width_statuscolors(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int width_statuscolors_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
static int draw_statuscolors(Bar *bar, BarArg *a);
#if BAR_EXTRASTATUS_PATCH
static int draw_statuscolors_es(Bar *bar, BarArg *a);
#endif // BAR_EXTRASTATUS_PATCH
#if !BAR_STATUSCMD_PATCH
static int click_statuscolors(Bar *bar, Arg *arg, BarArg *a);
#endif // BAR_STATUSCMD_PATCH
static int textw_wosc(char *s);
static int draw_wosc(Bar *bar, BarArg *a, char *s);

202
patch/bar_systray.c Normal file
View File

@@ -0,0 +1,202 @@
static Systray *systray = NULL;
static unsigned long systrayorientation = _NET_SYSTEM_TRAY_ORIENTATION_HORZ;
int
width_systray(Bar *bar, BarArg *a)
{
unsigned int w = 0;
Client *i;
if (!systray)
return 1;
if (showsystray) {
for (i = systray->icons; i; w += i->w + systrayspacing, i = i->next);
if (!w)
XMoveWindow(dpy, systray->win, -systray->h, bar->by);
}
return w ? w + lrpad - systrayspacing : 0;
}
int
draw_systray(Bar *bar, BarArg *a)
{
if (!showsystray)
return 0;
XSetWindowAttributes wa;
XWindowChanges wc;
Client *i;
unsigned int w;
if (!systray) {
/* init systray */
if (!(systray = (Systray *)calloc(1, sizeof(Systray))))
die("fatal: could not malloc() %u bytes\n", sizeof(Systray));
wa.override_redirect = True;
wa.event_mask = ButtonPressMask|ExposureMask;
wa.border_pixel = 0;
systray->h = MIN(a->h, drw->fonts->h);
#if BAR_ALPHA_PATCH
wa.background_pixel = 0;
wa.colormap = cmap;
systray->win = XCreateWindow(dpy, root, bar->bx + a->x + lrpad / 2, -systray->h, MAX(a->w + 40, 1), systray->h, 0, depth,
InputOutput, visual,
CWOverrideRedirect|CWBorderPixel|CWBackPixel|CWColormap|CWEventMask, &wa); // CWBackPixmap
#else
wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
systray->win = XCreateSimpleWindow(dpy, root, bar->bx + a->x + lrpad / 2, -systray->h, MIN(a->w, 1), systray->h, 0, 0, scheme[SchemeNorm][ColBg].pixel);
XChangeWindowAttributes(dpy, systray->win, CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWEventMask, &wa);
#endif // BAR_ALPHA_PATCH
XSelectInput(dpy, systray->win, SubstructureNotifyMask);
XChangeProperty(dpy, systray->win, netatom[NetSystemTrayOrientation], XA_CARDINAL, 32,
PropModeReplace, (unsigned char *)&systrayorientation, 1);
#if BAR_ALPHA_PATCH
XChangeProperty(dpy, systray->win, netatom[NetSystemTrayVisual], XA_VISUALID, 32,
PropModeReplace, (unsigned char *)&visual->visualid, 1);
#endif // BAR_ALPHA_PATCH
XChangeProperty(dpy, systray->win, netatom[NetWMWindowType], XA_ATOM, 32,
PropModeReplace, (unsigned char *)&netatom[NetWMWindowTypeDock], 1);
XMapRaised(dpy, systray->win);
XSetSelectionOwner(dpy, netatom[NetSystemTray], systray->win, CurrentTime);
if (XGetSelectionOwner(dpy, netatom[NetSystemTray]) == systray->win) {
sendevent(root, xatom[Manager], StructureNotifyMask, CurrentTime, netatom[NetSystemTray], systray->win, 0, 0);
XSync(dpy, False);
} else {
fprintf(stderr, "dwm: unable to obtain system tray.\n");
free(systray);
systray = NULL;
return 0;
}
}
systray->bar = bar;
wc.stack_mode = Above;
wc.sibling = bar->win;
XConfigureWindow(dpy, systray->win, CWSibling|CWStackMode, &wc);
drw_setscheme(drw, scheme[SchemeNorm]);
for (w = 0, i = systray->icons; i; i = i->next) {
#if BAR_ALPHA_PATCH
wa.background_pixel = 0;
#else
wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
#endif // BAR_ALPHA_PATCH
XChangeWindowAttributes(dpy, i->win, CWBackPixel, &wa);
XMapRaised(dpy, i->win);
i->x = w;
XMoveResizeWindow(dpy, i->win, i->x, 0, i->w, i->h);
w += i->w;
if (i->next)
w += systrayspacing;
if (i->mon != bar->mon)
i->mon = bar->mon;
}
XMoveResizeWindow(dpy, systray->win, bar->bx + a->x + lrpad / 2, (w ? bar->by + a->y + (a->h - systray->h) / 2: -systray->h), MAX(w, 1), systray->h);
return w;
}
int
click_systray(Bar *bar, Arg *arg, BarArg *a)
{
return -1;
}
void
removesystrayicon(Client *i)
{
Client **ii;
if (!showsystray || !i)
return;
for (ii = &systray->icons; *ii && *ii != i; ii = &(*ii)->next);
if (ii)
*ii = i->next;
XReparentWindow(dpy, i->win, root, 0, 0);
free(i);
drawbarwin(systray->bar);
}
void
resizerequest(XEvent *e)
{
XResizeRequestEvent *ev = &e->xresizerequest;
Client *i;
if ((i = wintosystrayicon(ev->window))) {
updatesystrayicongeom(i, ev->width, ev->height);
drawbarwin(systray->bar);
}
}
void
updatesystrayicongeom(Client *i, int w, int h)
{
if (!systray)
return;
int icon_height = systray->h;
if (i) {
i->h = icon_height;
if (w == h)
i->w = icon_height;
else if (h == icon_height)
i->w = w;
else
i->w = (int) ((float)icon_height * ((float)w / (float)h));
applysizehints(i, &(i->x), &(i->y), &(i->w), &(i->h), False);
/* force icons into the systray dimensions if they don't want to */
if (i->h > icon_height) {
if (i->w == i->h)
i->w = icon_height;
else
i->w = (int) ((float)icon_height * ((float)i->w / (float)i->h));
i->h = icon_height;
}
if (i->w > 2 * icon_height)
i->w = icon_height;
}
}
void
updatesystrayiconstate(Client *i, XPropertyEvent *ev)
{
long flags;
int code = 0;
if (!showsystray || !systray || !i || ev->atom != xatom[XembedInfo] ||
!(flags = getatomprop(i, xatom[XembedInfo], xatom[XembedInfo])))
return;
if (flags & XEMBED_MAPPED && !i->tags) {
i->tags = 1;
code = XEMBED_WINDOW_ACTIVATE;
XMapRaised(dpy, i->win);
setclientstate(i, NormalState);
}
else if (!(flags & XEMBED_MAPPED) && i->tags) {
i->tags = 0;
code = XEMBED_WINDOW_DEACTIVATE;
XUnmapWindow(dpy, i->win);
setclientstate(i, WithdrawnState);
}
else
return;
sendevent(i->win, xatom[Xembed], StructureNotifyMask, CurrentTime, code, 0,
systray->win, XEMBED_EMBEDDED_VERSION);
}
Client *
wintosystrayicon(Window w)
{
if (!systray)
return NULL;
Client *i = NULL;
if (!showsystray || !w)
return i;
for (i = systray->icons; i && i->win != w; i = i->next);
return i;
}

41
patch/bar_systray.h Normal file
View File

@@ -0,0 +1,41 @@
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
/* XEMBED messages */
#define XEMBED_EMBEDDED_NOTIFY 0
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_FOCUS_IN 4
#define XEMBED_MODALITY_ON 10
#define XEMBED_MAPPED (1 << 0)
#define XEMBED_WINDOW_ACTIVATE 1
#define XEMBED_WINDOW_DEACTIVATE 2
#define VERSION_MAJOR 0
#define VERSION_MINOR 0
#define XEMBED_EMBEDDED_VERSION (VERSION_MAJOR << 16) | VERSION_MINOR
/* enums */
enum { Manager, Xembed, XembedInfo, XLast }; /* Xembed atoms */
typedef struct Systray Systray;
struct Systray {
Window win;
Client *icons;
Bar *bar;
int h;
};
/* bar integration */
static int width_systray(Bar *bar, BarArg *a);
static int draw_systray(Bar *bar, BarArg *a);
static int click_systray(Bar *bar, Arg *arg, BarArg *a);
/* function declarations */
static void removesystrayicon(Client *i);
static void resizerequest(XEvent *e);
static void updatesystrayicongeom(Client *i, int w, int h);
static void updatesystrayiconstate(Client *i, XPropertyEvent *ev);
static Client *wintosystrayicon(Window w);

258
patch/bar_tabgroups.c Normal file
View File

@@ -0,0 +1,258 @@
/* Bartabgroups properties, you can override these in your config.h if you want. */
#ifndef BARTAB_BORDERS
#define BARTAB_BORDERS 1 // 0 = off, 1 = on
#endif
#ifndef BARTAB_SHOWFLOATING
#define BARTAB_SHOWFLOATING 0 // whether to show titles for floating windows, hidden clients are always shown
#endif
#ifndef BARTAB_STACKWEIGHT
#define BARTAB_STACKWEIGHT 1 // stack weight compared to hidden and floating window titles
#endif
#ifndef BARTAB_HIDDENWEIGHT
#define BARTAB_HIDDENWEIGHT 1 // hidden window title weight
#endif
#ifndef BARTAB_FLOATWEIGHT
#define BARTAB_FLOATWEIGHT 1 // floating window title weight, set to 0 to not show floating windows
#endif
int
width_bartabgroups(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_bartabgroups(Bar *bar, BarArg *a)
{
drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1);
return bartabcalculate(bar->mon, a->x, a->w, -1, bartabdraw, NULL, a);
}
int
click_bartabgroups(Bar *bar, Arg *arg, BarArg *a)
{
bartabcalculate(bar->mon, 0, a->w, a->x, bartabclick, arg, a);
return ClkWinTitle;
}
void
bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *a)
{
if (!c)
return;
int i, nclienttags = 0, nviewtags = 0;
int tpad = lrpad / 2;
#if BAR_WINICON_PATCH
int ipad = c->icon ? c->icw + ICONSPACING : 0;
#endif // BAR_WINICON_PATCH
#if BAR_CENTEREDWINDOWNAME_PATCH
int cpad = 0;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
int tx = x;
int tw = w;
drw_setscheme(drw, scheme[
m->sel == c
#ifdef HIDDEN
&& HIDDEN(c)
? SchemeHidSel
: HIDDEN(c)
? SchemeHidNorm
: m->sel == c
#endif
? SchemeSel
: groupactive
? SchemeTitleSel
: SchemeTitleNorm
]);
if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small
tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
#if BAR_WINICON_PATCH && BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) + ipad < w)
cpad = (w - TEXTW(c->name) - ipad) / 2;
#elif BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) < w)
cpad = (w - TEXTW(c->name)) / 2;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h);
#if BAR_CENTEREDWINDOWNAME_PATCH
/* Apply center padding, if any */
tx += cpad;
tw -= cpad;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
tx += tpad;
tw -= lrpad;
#if BAR_WINICON_PATCH
if (ipad) {
drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon);
tx += ipad;
tw -= ipad;
}
#endif // BAR_WINICON_PATCH
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed);
if (BARTAB_BORDERS) {
XSetForeground(drw->dpy, drw->gc, scheme[SchemeSel][ColBorder].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, 1, a->h);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= a->w ? 1 : 0), a->y, 1, a->h);
}
/* Optional tags icons */
for (i = 0; i < NUMTAGS; i++) {
if ((m->tagset[m->seltags] >> i) & 1)
nviewtags++;
if ((c->tags >> i) & 1)
nclienttags++;
}
if (TAGSINDICATOR == 2 || nclienttags > 1 || nviewtags > 1)
drawindicator(m, c, 1, x, a->y, w, a->h, 0, 0, 0, INDICATOR_RIGHT_TAGS);
}
#ifndef HIDDEN
#define HIDDEN(C) 0
#endif
void
bartabclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg)
{
if (passx >= x && passx <= x + w)
arg->v = c;
}
int
bartabcalculate(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
) {
Client *c;
int
i, clientsnmaster = 0, clientsnstack = 0, clientsnfloating = 0, clientsnhidden = 0,
masteractive = 0, fulllayout = 0,
x = offx, w, r, num = 0, den, tgactive;
for (i = 0; i < LENGTH(bartabmonfns); i++)
if (m ->lt[m->sellt]->arrange == bartabmonfns[i]) {
fulllayout = 1;
break;
}
for (i = 0, c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c)) {
clientsnhidden++;
continue;
}
if (c->isfloating) {
clientsnfloating++;
continue;
}
if (m->sel == c)
masteractive = i < m->nmaster;
if (i < m->nmaster)
clientsnmaster++;
else
clientsnstack++;
i++;
}
if (clientsnmaster + clientsnstack + clientsnfloating + clientsnhidden == 0)
return 0;
tgactive = 1;
num = tabw;
/* floating mode */
if ((fulllayout && BARTAB_FLOATWEIGHT) || clientsnmaster + clientsnstack == 0 || !m->lt[m->sellt]->arrange) {
den = clientsnmaster + clientsnstack + clientsnfloating + clientsnhidden;
r = num % den;
w = num / den;
for (c = m->clients, i = 0; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg);
x += w + (i < r ? 1 : 0);
i++;
}
/* no master and stack mode, e.g. monocole, grid layouts, fibonacci */
} else if (fulllayout) {
den = clientsnmaster + clientsnstack + clientsnhidden;
r = num % den;
w = num / den;
for (c = m->clients, i = 0; c; c = c->next) {
if (!ISVISIBLE(c) || (c->isfloating && !HIDDEN(c)))
continue;
tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg);
x += w + (i < r ? 1 : 0);
i++;
}
/* tiled mode */
} else {
den = clientsnmaster;
c = m->clients;
i = 0;
if (den) {
if (clientsnstack + clientsnfloating * BARTAB_FLOATWEIGHT + clientsnhidden) {
tgactive = masteractive;
num = tabw * m->mfact;
}
r = num % den;
w = num / den;
for (; c && i < m->nmaster; c = c->next) { // tiled master
if (!ISVISIBLE(c) || c->isfloating || HIDDEN(c))
continue;
tabfn(m, c, passx, x, w + (i < r ? 1 : 0), tgactive, arg, barg);
x += w + (i < r ? 1 : 0);
i++;
}
tgactive = !tgactive;
num = tabw - num;
}
den = clientsnstack * BARTAB_STACKWEIGHT + clientsnfloating * BARTAB_FLOATWEIGHT + clientsnhidden * BARTAB_HIDDENWEIGHT;
if (!den)
return 1;
r = num % den;
w = num / den;
#if BARTAB_STACKWEIGHT
for (; c; c = c->next) { // tiled stack
if (!ISVISIBLE(c) || HIDDEN(c) || c->isfloating)
continue;
tabfn(m, c, passx, x, w * BARTAB_STACKWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg);
x += w * BARTAB_STACKWEIGHT + (i - m->nmaster < r ? 1 : 0);
i++;
}
#endif // BARTAB_STACKWEIGHT
#if BARTAB_HIDDENWEIGHT
for (c = m->clients; c; c = c->next) { // hidden windows
if (!ISVISIBLE(c) || !HIDDEN(c))
continue;
tabfn(m, c, passx, x, w * BARTAB_HIDDENWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg);
x += w * BARTAB_HIDDENWEIGHT + (i - m->nmaster < r ? 1 : 0);
i++;
}
#endif // BARTAB_HIDDENWEIGHT
#if BARTAB_FLOATWEIGHT
for (c = m->clients; c; c = c->next) { // floating windows
if (!ISVISIBLE(c) || HIDDEN(c) || !c->isfloating)
continue;
tabfn(m, c, passx, x, w * BARTAB_FLOATWEIGHT + (i - m->nmaster < r ? 1 : 0), tgactive, arg, barg);
x += w * BARTAB_FLOATWEIGHT + (i - m->nmaster < r ? 1 : 0);
i++;
}
#endif // BARTAB_FLOATWEIGHT
}
return 1;
}

8
patch/bar_tabgroups.h Normal file
View File

@@ -0,0 +1,8 @@
static int width_bartabgroups(Bar *bar, BarArg *a);
static int draw_bartabgroups(Bar *bar, BarArg *a);
static int click_bartabgroups(Bar *bar, Arg *arg, BarArg *a);
static void bartabdraw(Monitor *m, Client *c, int unused, int x, int w, int groupactive, Arg *arg, BarArg *barg);
static void bartabclick(Monitor *m, Client *c, int passx, int x, int w, int unused, Arg *arg, BarArg *barg);
static int bartabcalculate(Monitor *m, int offx, int w, int passx, void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg), Arg *arg, BarArg *barg);

150
patch/bar_taggrid.c Normal file
View File

@@ -0,0 +1,150 @@
int
width_taggrid(Bar *bar, BarArg *a)
{
return (a->h / 2) * (NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0)) + lrpad;
}
int
draw_taggrid(Bar *bar, BarArg *a)
{
unsigned int x, y, h, max_x = 0, columns, occ = 0;
int invert, i,j, k;
Client *c;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags;
max_x = x = a->x + lrpad / 2;
h = a->h / tagrows - 1;
y = a->y;
columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0);
/* Firstly we will fill the borders of squares */
XSetForeground(drw->dpy, drw->gc, scheme[SchemeTagsNorm][ColBg].pixel);
XFillRectangle(dpy, drw->drawable, drw->gc, x, y, h*columns + 1, a->h);
/* We will draw NUMTAGS squares in tagraws raws. */
for (j = 0, i = 0; j < tagrows; j++) {
x = a->x + lrpad / 2;
for (k = 0; k < columns; k++, i++) {
if (i < NUMTAGS) {
invert = bar->mon->tagset[bar->mon->seltags] & 1 << i ? 0 : 1;
/* Select active color for current square */
XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeTagsSel][ColBg].pixel :
scheme[SchemeTagsNorm][ColFg].pixel);
XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h-1);
/* Mark square if tag has client */
if (occ & 1 << i) {
XSetForeground(drw->dpy, drw->gc, !invert ? scheme[SchemeTagsSel][ColFg].pixel :
scheme[SchemeTagsNorm][ColBg].pixel);
XFillRectangle(dpy, drw->drawable, drw->gc, x + 1, y + 1,
h / 2, h / 2);
}
} else {
XSetForeground(drw->dpy, drw->gc, scheme[SchemeTagsNorm][ColBg].pixel);
XFillRectangle(dpy, drw->drawable, drw->gc, x+1, y+1, h-1, h);
}
x += h;
if (x > max_x) {
max_x = x;
}
}
y += h;
}
return 1;
}
int
click_taggrid(Bar *bar, Arg *arg, BarArg *a)
{
unsigned int i, h, columns;
h = a->h / tagrows - 1;
columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0);
i = (a->x - lrpad / 2) / h + columns * (a->y / h);
if (i >= NUMTAGS) {
i = NUMTAGS - 1;
}
arg->ui = 1 << i;
return ClkTagBar;
}
void
switchtag(const Arg *arg)
{
unsigned int columns;
unsigned int new_tagset = 0;
unsigned int pos, i;
int col, row;
Arg new_arg;
columns = NUMTAGS / tagrows + ((NUMTAGS % tagrows > 0) ? 1 : 0);
for (i = 0; i < NUMTAGS; ++i) {
if (!(selmon->tagset[selmon->seltags] & 1 << i)) {
continue;
}
pos = i;
row = pos / columns;
col = pos % columns;
if (arg->ui & SWITCHTAG_UP) { /* UP */
row --;
if (row < 0) {
row = tagrows - 1;
}
do {
pos = row * columns + col;
row --;
} while (pos >= NUMTAGS);
}
if (arg->ui & SWITCHTAG_DOWN) { /* DOWN */
row ++;
if (row >= tagrows) {
row = 0;
}
pos = row * columns + col;
if (pos >= NUMTAGS) {
row = 0;
}
pos = row * columns + col;
}
if (arg->ui & SWITCHTAG_LEFT) { /* LEFT */
col --;
if (col < 0) {
col = columns - 1;
}
do {
pos = row * columns + col;
col --;
} while (pos >= NUMTAGS);
}
if (arg->ui & SWITCHTAG_RIGHT) { /* RIGHT */
col ++;
if (col >= columns) {
col = 0;
}
pos = row * columns + col;
if (pos >= NUMTAGS) {
col = 0;
pos = row * columns + col;
}
}
new_tagset |= 1 << pos;
}
new_arg.ui = new_tagset;
if (arg->ui & SWITCHTAG_TOGGLETAG) {
toggletag(&new_arg);
}
if (arg->ui & SWITCHTAG_TAG) {
tag(&new_arg);
}
if (arg->ui & SWITCHTAG_VIEW) {
view (&new_arg);
}
if (arg->ui & SWITCHTAG_TOGGLEVIEW) {
toggleview (&new_arg);
}
}

5
patch/bar_taggrid.h Normal file
View File

@@ -0,0 +1,5 @@
static int width_taggrid(Bar *bar, BarArg *a);
static int draw_taggrid(Bar *bar, BarArg *a);
static int click_taggrid(Bar *bar, Arg *arg, BarArg *a);
static void switchtag(const Arg *arg);

21
patch/bar_tagicons.c Normal file
View File

@@ -0,0 +1,21 @@
char *
tagicon(Monitor *m, int tag)
{
#if BAR_ALTTAGSDECORATION_PATCH
Client *c;
#endif // BAR_ALTTAGSDECORATION_PATCH
int tagindex = tag + NUMTAGS * m->num;
if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS]))
tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]);
#if BAR_ALTTAGSDECORATION_PATCH
for (c = m->clients; c && (!(c->tags & 1 << tag) || HIDDEN(c)); c = c->next);
if (c)
return tagicons[ALT_TAGS_DECORATION][tagindex];
#endif // BAR_ALTTAGSDECORATION_PATCH
#if BAR_ALTERNATIVE_TAGS_PATCH
if (m->alttag)
return tagicons[ALTERNATIVE_TAGS][tagindex];
#endif // BAR_ALTERNATIVE_TAGS_PATCH
return tagicons[DEFAULT_TAGS][tagindex];
}

8
patch/bar_tagicons.h Normal file
View File

@@ -0,0 +1,8 @@
enum {
DEFAULT_TAGS,
ALTERNATIVE_TAGS,
ALT_TAGS_DECORATION,
};
static char * tagicon(Monitor *m, int tag);

91
patch/bar_taglabels.c Normal file
View File

@@ -0,0 +1,91 @@
int
width_taglabels(Bar *bar, BarArg *a)
{
int w, i;
Client *c;
Monitor *m = bar->mon;
char *icon;
unsigned int occ = 0;
for (c = m->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
for (w = 0, i = 0; i < NUMTAGS; i++) {
m->taglabel[i][0] = '\0';
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
icon = tagicon(m, i);
XClassHint ch = { NULL, NULL };
for (c = m->clients; c; c = c->next) {
if (c->tags & (1 << i)) {
XGetClassHint(dpy, c->win, &ch);
break;
}
}
if (ch.res_class) {
if (lcaselbl)
ch.res_class[0] = tolower(ch.res_class[0]);
snprintf(m->taglabel[i], 64, ptagf, icon, ch.res_class);
} else
snprintf(m->taglabel[i], 64, etagf, icon);
w += TEXTW(m->taglabel[i]);
}
return w;
}
int
draw_taglabels(Bar *bar, BarArg *a)
{
int invert = 0;
int w, x = a->x;
unsigned int i, occ = 0, urg = 0;
Client *c;
Monitor *m = bar->mon;
for (c = m->clients; c; c = c->next)
if (c->isurgent)
urg |= c->tags;
for (i = 0; i < NUMTAGS; i++) {
/* do not draw vacant tags */
if (!m->taglabel[i][0])
continue;
drw_setscheme(drw, scheme[
m->tagset[m->seltags] & 1 << i
? SchemeTagsSel
: urg & 1 << i
? SchemeUrg
: SchemeTagsNorm
]);
w = TEXTW(m->taglabel[i]);
drw_text(drw, x, a->y, w, a->h, lrpad / 2, m->taglabel[i], invert, False);
drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype);
#if BAR_UNDERLINETAGS_PATCH
if (ulineall || m->tagset[m->seltags] & 1 << i)
drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0);
#endif // BAR_UNDERLINETAGS_PATCH
x += w;
}
return 1;
}
int
click_taglabels(Bar *bar, Arg *arg, BarArg *a)
{
int i = 0, x = lrpad / 2;
Monitor *m = bar->mon;
do {
if (!m->taglabel[i][0])
continue;
x += TEXTW(m->taglabel[i]);
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
arg->ui = 1 << i;
}
return ClkTagBar;
}

5
patch/bar_taglabels.h Normal file
View File

@@ -0,0 +1,5 @@
#include <ctype.h> /* for making tab label lowercase, very tiny standard library */
static int width_taglabels(Bar *bar, BarArg *a);
static int draw_taglabels(Bar *bar, BarArg *a);
static int click_taglabels(Bar *bar, Arg *arg, BarArg *a);

112
patch/bar_tagpreview.c Normal file
View File

@@ -0,0 +1,112 @@
#include <Imlib2.h>
void
createpreview(Monitor *m)
{
if (m->tagwin) {
XMoveResizeWindow(
dpy, m->tagwin,
m->mx,
m->bar->by + bh,
m->mw / scalepreview,
m->mh / scalepreview
);
return;
}
XSetWindowAttributes wa = {
.override_redirect = True,
#if BAR_ALPHA_PATCH
.background_pixel = 0,
.border_pixel = 0,
.colormap = cmap,
#else
.background_pixmap = ParentRelative,
#endif // BAR_ALPHA_PATCH
.event_mask = ButtonPressMask|ExposureMask
};
m->tagwin = XCreateWindow(dpy, root, m->wx, m->bar->by + bh, m->mw / scalepreview, m->mh / scalepreview, 0,
#if BAR_ALPHA_PATCH
depth, CopyFromParent, visual,
CWOverrideRedirect|CWBackPixel|CWBorderPixel|CWColormap|CWEventMask, &wa
#else
DefaultDepth(dpy, screen), CopyFromParent, DefaultVisual(dpy, screen),
CWOverrideRedirect|CWBackPixmap|CWEventMask, &wa
#endif // BAR_ALPHA_PATCH
);
XDefineCursor(dpy, m->tagwin, cursor[CurNormal]->cursor);
XMapRaised(dpy, m->tagwin);
XUnmapWindow(dpy, m->tagwin);
}
void
hidetagpreview(Monitor *m)
{
m->previewshow = 0;
XUnmapWindow(dpy, m->tagwin);
}
void
showtagpreview(int tag, int x, int y)
{
Monitor *m = selmon;
if (!m->tagwin)
return;
if (m->tagmap[tag]) {
XSetWindowBackgroundPixmap(dpy, m->tagwin, m->tagmap[tag]);
XCopyArea(dpy, m->tagmap[tag], m->tagwin, drw->gc, 0, 0, m->mw / scalepreview, m->mh / scalepreview, 0, 0);
XMoveWindow(dpy, m->tagwin, x, y);
XSync(dpy, False);
XMapWindow(dpy, m->tagwin);
} else
XUnmapWindow(dpy, m->tagwin);
}
void
tagpreviewswitchtag(void)
{
int i;
unsigned int occ = 0;
Client *c;
Imlib_Image image;
Monitor *m = selmon;
if (!m->tagwin)
createpreview(m);
for (c = m->clients; c; c = c->next)
occ |= c->tags;
for (i = 0; i < NUMTAGS; i++) {
if (m->tagset[m->seltags] & 1 << i) {
if (m->tagmap[i] != 0) {
XFreePixmap(dpy, m->tagmap[i]);
m->tagmap[i] = 0;
}
if (occ & 1 << i) {
image = imlib_create_image(sw, sh);
imlib_context_set_image(image);
imlib_context_set_display(dpy);
#if BAR_ALPHA_PATCH
imlib_image_set_has_alpha(1);
imlib_context_set_blend(0);
imlib_context_set_visual(visual);
#else
imlib_context_set_visual(DefaultVisual(dpy, screen));
#endif // BAR_ALPHA_PATCH
imlib_context_set_drawable(root);
imlib_copy_drawable_to_image(0, m->mx, m->my, m->mw ,m->mh, 0, 0, 1);
#if BAR_ALPHA_PATCH
m->tagmap[i] = XCreatePixmap(dpy, m->tagwin, m->mw / scalepreview, m->mh / scalepreview, depth);
#else
m->tagmap[i] = XCreatePixmap(dpy, m->tagwin, m->mw / scalepreview, m->mh / scalepreview, DefaultDepth(dpy, screen));
#endif // BAR_ALPHA_PATCH
imlib_context_set_drawable(m->tagmap[i]);
imlib_render_image_part_on_drawable_at_size(0, 0, m->mw, m->mh, 0, 0, m->mw / scalepreview, m->mh / scalepreview);
imlib_free_image();
}
}
}
}

4
patch/bar_tagpreview.h Normal file
View File

@@ -0,0 +1,4 @@
static void createpreview(Monitor *m);
static void hidetagpreview(Monitor *m);
static void showtagpreview(int tag, int x, int y);
static void tagpreviewswitchtag(void);

146
patch/bar_tags.c Normal file
View File

@@ -0,0 +1,146 @@
int
width_tags(Bar *bar, BarArg *a)
{
int w, i;
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
for (w = 0, i = 0; i < NUMTAGS; i++) {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
w += TEXTW(tagicon(bar->mon, i));
}
return w;
}
int
draw_tags(Bar *bar, BarArg *a)
{
int invert;
int w, x = a->x;
unsigned int i, occ = 0, urg = 0;
char *icon;
Client *c;
Monitor *m = bar->mon;
for (c = m->clients; c; c = c->next) {
#if BAR_HIDEVACANTTAGS_PATCH
occ |= c->tags == 255 ? 0 : c->tags;
#else
occ |= c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
if (c->isurgent)
urg |= c->tags;
}
for (i = 0; i < NUMTAGS; i++) {
#if BAR_HIDEVACANTTAGS_PATCH
/* do not draw vacant tags */
if (!(occ & 1 << i || m->tagset[m->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
icon = tagicon(bar->mon, i);
invert = 0;
w = TEXTW(icon);
drw_setscheme(drw, scheme[
m->tagset[m->seltags] & 1 << i
? SchemeTagsSel
: urg & 1 << i
? SchemeUrg
: SchemeTagsNorm
]);
drw_text(drw, x, a->y, w, a->h, lrpad / 2, icon, invert, False);
drawindicator(m, NULL, occ, x, a->y, w, a->h, i, -1, invert, tagindicatortype);
#if BAR_UNDERLINETAGS_PATCH
if (ulineall || m->tagset[m->seltags] & 1 << i)
drw_rect(drw, x + ulinepad, bh - ulinestroke - ulinevoffset, w - (ulinepad * 2), ulinestroke, 1, 0);
#endif // BAR_UNDERLINETAGS_PATCH
x += w;
}
return 1;
}
int
click_tags(Bar *bar, Arg *arg, BarArg *a)
{
int i = 0, x = 0;
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
do {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
x += TEXTW(tagicon(bar->mon, i));
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
arg->ui = 1 << i;
}
return ClkTagBar;
}
int
hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev)
{
#if BAR_TAGPREVIEW_PATCH
int i = 0, x = lrpad / 2;
int px, py;
Monitor *m = bar->mon;
#if VANITYGAPS_PATCH
int ov = gappov;
int oh = gappoh;
#else
int ov = 0;
int oh = 0;
#endif // VANITYGAPS_PATCH
#if BAR_HIDEVACANTTAGS_PATCH
Client *c;
unsigned int occ = 0;
for (c = bar->mon->clients; c; c = c->next)
occ |= c->tags == 255 ? 0 : c->tags;
#endif // BAR_HIDEVACANTTAGS_PATCH
do {
#if BAR_HIDEVACANTTAGS_PATCH
if (!(occ & 1 << i || bar->mon->tagset[bar->mon->seltags] & 1 << i))
continue;
#endif // BAR_HIDEVACANTTAGS_PATCH
x += TEXTW(tagicon(bar->mon, i));
} while (a->x >= x && ++i < NUMTAGS);
if (i < NUMTAGS) {
if ((i + 1) != selmon->previewshow && !(selmon->tagset[selmon->seltags] & 1 << i)) {
if (bar->by > m->my + m->mh / 2) // bottom bar
py = bar->by - m->mh / scalepreview - oh;
else // top bar
py = bar->by + bar->bh + oh;
px = bar->bx + ev->x - m->mw / scalepreview / 2;
if (px + m->mw / scalepreview > m->mx + m->mw)
px = m->wx + m->ww - m->mw / scalepreview - ov;
else if (px < bar->bx)
px = m->wx + ov;
selmon->previewshow = i + 1;
showtagpreview(i, px, py);
} else if (selmon->tagset[selmon->seltags] & 1 << i) {
hidetagpreview(selmon);
}
} else if (selmon->previewshow != 0) {
hidetagpreview(selmon);
}
#endif // BAR_TAGPREVIEW_PATCH
return 1;
}

4
patch/bar_tags.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_tags(Bar *bar, BarArg *a);
static int draw_tags(Bar *bar, BarArg *a);
static int click_tags(Bar *bar, Arg *arg, BarArg *a);
static int hover_tags(Bar *bar, BarArg *a, XMotionEvent *ev);

69
patch/bar_vtcolors.c Normal file
View File

@@ -0,0 +1,69 @@
void
get_vt_colors(void)
{
char *cfs[3] = {
"/sys/module/vt/parameters/default_red",
"/sys/module/vt/parameters/default_grn",
"/sys/module/vt/parameters/default_blu",
};
char vtcs[16][8];
char tk[] = ",";
char cl[64];
char *tp = NULL;
FILE *fp;
size_t r;
int i, c, n, len;
for (i = 0; i < 16; i++)
strcpy(vtcs[i], "#000000");
for (i = 0, r = 0; i < 3; i++) {
if ((fp = fopen(cfs[i], "r")) == NULL)
continue;
while ((cl[r] = fgetc(fp)) != EOF && cl[r] != '\n')
r++;
cl[r] = '\0';
for (c = 0, tp = cl, n = 0; c < 16; c++, tp++) {
if ((r = strcspn(tp, tk)) == -1)
break;
for (n = 0; r && *tp >= 48 && *tp < 58; r--, tp++)
n = n * 10 - 48 + *tp;
vtcs[c][i * 2 + 1] = n / 16 < 10 ? n / 16 + 48 : n / 16 + 87;
vtcs[c][i * 2 + 2] = n % 16 < 10 ? n % 16 + 48 : n % 16 + 87;
}
fclose(fp);
}
len = LENGTH(colors);
if (len > LENGTH(color_ptrs))
len = LENGTH(color_ptrs);
for (i = 0; i < len; i++) {
for (c = 0; c < ColCount; c++) {
n = color_ptrs[i][c];
if (n > -1 && strlen(colors[i][c]) >= strlen(vtcs[n]))
memcpy(colors[i][c], vtcs[n], 7);
}
}
}
int get_luminance(char *r)
{
char *c = r;
int n[3] = {0};
int i = 0;
while (*c) {
if (*c >= 48 && *c < 58)
n[i / 2] = n[i / 2] * 16 - 48 + *c;
else if (*c >= 65 && *c < 71)
n[i / 2] = n[i / 2] * 16 - 55 + *c;
else if (*c >= 97 && *c < 103)
n[i / 2] = n[i / 2] * 16 - 87 + *c;
else
i--;
i++;
c++;
}
return (0.299 * n[0] + 0.587 * n[1] + 0.114 * n[2]) / 2.55;
}

3
patch/bar_vtcolors.h Normal file
View File

@@ -0,0 +1,3 @@
static void get_vt_colors(void);
static int get_luminance(char *rgb);

145
patch/bar_winicon.c Normal file
View File

@@ -0,0 +1,145 @@
static uint32_t prealpha(uint32_t p) {
uint8_t a = p >> 24u;
uint32_t rb = (a * (p & 0xFF00FFu)) >> 8u;
uint32_t g = (a * (p & 0x00FF00u)) >> 8u;
return (rb & 0xFF00FFu) | (g & 0x00FF00u) | (a << 24u);
}
Picture
geticonprop(Window win, unsigned int *picw, unsigned int *pich)
{
int format;
unsigned long n, extra, *p = NULL;
Atom real;
if (XGetWindowProperty(dpy, win, netatom[NetWMIcon], 0L, LONG_MAX, False, AnyPropertyType,
&real, &format, &n, &extra, (unsigned char **)&p) != Success)
return None;
if (n == 0 || format != 32) { XFree(p); return None; }
unsigned long *bstp = NULL;
uint32_t w, h, sz;
{
unsigned long *i; const unsigned long *end = p + n;
uint32_t bstd = UINT32_MAX, d, m;
for (i = p; i < end - 1; i += sz) {
if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
if ((sz = w * h) > end - i) break;
if ((m = w > h ? w : h) >= ICONSIZE && (d = m - ICONSIZE) < bstd) { bstd = d; bstp = i; }
}
if (!bstp) {
for (i = p; i < end - 1; i += sz) {
if ((w = *i++) >= 16384 || (h = *i++) >= 16384) { XFree(p); return None; }
if ((sz = w * h) > end - i) break;
if ((d = ICONSIZE - (w > h ? w : h)) < bstd) { bstd = d; bstp = i; }
}
}
if (!bstp) { XFree(p); return None; }
}
if ((w = *(bstp - 2)) == 0 || (h = *(bstp - 1)) == 0) { XFree(p); return None; }
uint32_t icw, ich;
if (w <= h) {
ich = ICONSIZE; icw = w * ICONSIZE / h;
if (icw == 0) icw = 1;
}
else {
icw = ICONSIZE; ich = h * ICONSIZE / w;
if (ich == 0) ich = 1;
}
*picw = icw; *pich = ich;
uint32_t i, *bstp32 = (uint32_t *)bstp;
for (sz = w * h, i = 0; i < sz; ++i) bstp32[i] = prealpha(bstp[i]);
Picture ret = drw_picture_create_resized(drw, (char *)bstp, w, h, icw, ich);
XFree(p);
return ret;
}
Picture
drw_picture_create_resized(Drw *drw, char *src, unsigned int srcw, unsigned int srch, unsigned int dstw, unsigned int dsth) {
Pixmap pm;
Picture pic;
GC gc;
if (srcw <= (dstw << 1u) && srch <= (dsth << 1u)) {
XImage img = {
srcw, srch, 0, ZPixmap, src,
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
32, 0, 32,
0, 0, 0
};
XInitImage(&img);
pm = XCreatePixmap(drw->dpy, drw->root, srcw, srch, 32);
gc = XCreateGC(drw->dpy, pm, 0, NULL);
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, srcw, srch);
XFreeGC(drw->dpy, gc);
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
XFreePixmap(drw->dpy, pm);
XRenderSetPictureFilter(drw->dpy, pic, FilterBilinear, NULL, 0);
XTransform xf;
xf.matrix[0][0] = (srcw << 16u) / dstw; xf.matrix[0][1] = 0; xf.matrix[0][2] = 0;
xf.matrix[1][0] = 0; xf.matrix[1][1] = (srch << 16u) / dsth; xf.matrix[1][2] = 0;
xf.matrix[2][0] = 0; xf.matrix[2][1] = 0; xf.matrix[2][2] = 65536;
XRenderSetPictureTransform(drw->dpy, pic, &xf);
} else {
Imlib_Image origin = imlib_create_image_using_data(srcw, srch, (DATA32 *)src);
if (!origin) return None;
imlib_context_set_image(origin);
imlib_image_set_has_alpha(1);
Imlib_Image scaled = imlib_create_cropped_scaled_image(0, 0, srcw, srch, dstw, dsth);
imlib_free_image_and_decache();
if (!scaled) return None;
imlib_context_set_image(scaled);
imlib_image_set_has_alpha(1);
XImage img = {
dstw, dsth, 0, ZPixmap, (char *)imlib_image_get_data_for_reading_only(),
ImageByteOrder(drw->dpy), BitmapUnit(drw->dpy), BitmapBitOrder(drw->dpy), 32,
32, 0, 32,
0, 0, 0
};
XInitImage(&img);
pm = XCreatePixmap(drw->dpy, drw->root, dstw, dsth, 32);
gc = XCreateGC(drw->dpy, pm, 0, NULL);
XPutImage(drw->dpy, pm, gc, &img, 0, 0, 0, 0, dstw, dsth);
imlib_free_image_and_decache();
XFreeGC(drw->dpy, gc);
pic = XRenderCreatePicture(drw->dpy, pm, XRenderFindStandardFormat(drw->dpy, PictStandardARGB32), 0, NULL);
XFreePixmap(drw->dpy, pm);
}
return pic;
}
void
drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic)
{
if (!drw)
return;
XRenderComposite(drw->dpy, PictOpOver, pic, None, drw->picture, 0, 0, 0, 0, x, y, w, h);
}
void
freeicon(Client *c)
{
if (c->icon) {
XRenderFreePicture(dpy, c->icon);
c->icon = None;
}
}
void
updateicon(Client *c)
{
freeicon(c);
c->icon = geticonprop(c->win, &c->icw, &c->ich);
}

9
patch/bar_winicon.h Normal file
View File

@@ -0,0 +1,9 @@
#include <Imlib2.h>
#include <limits.h>
#include <stdint.h>
static Picture drw_picture_create_resized(Drw *drw, char *src, unsigned int src_w, unsigned int src_h, unsigned int dst_w, unsigned int dst_h);
static void drw_pic(Drw *drw, int x, int y, unsigned int w, unsigned int h, Picture pic);
static Picture geticonprop(Window w, unsigned int *icw, unsigned int *ich);
static void freeicon(Client *c);
static void updateicon(Client *c);

88
patch/bar_wintitle.c Normal file
View File

@@ -0,0 +1,88 @@
int
width_wintitle(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_wintitle(Bar *bar, BarArg *a)
{
#if BAR_TITLE_LEFT_PAD_PATCH && BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad;
#elif BAR_TITLE_LEFT_PAD_PATCH
int x = a->x + lrpad / 2, w = a->w - lrpad / 2;
#elif BAR_TITLE_RIGHT_PAD_PATCH
int x = a->x, w = a->w - lrpad / 2;
#else
int x = a->x, w = a->w;
#endif // BAR_TITLE_LEFT_PAD_PATCH | BAR_TITLE_RIGHT_PAD_PATCH
Monitor *m = bar->mon;
Client *c = m->sel;
if (!c) {
drw_setscheme(drw, scheme[SchemeTitleNorm]);
drw_rect(drw, x, a->y, w, a->h, 1, 1);
return 0;
}
int tpad = lrpad / 2;
#if BAR_WINICON_PATCH
int ipad = c->icon ? c->icw + ICONSPACING : 0;
#endif // BAR_WINICON_PATCH
#if BAR_CENTEREDWINDOWNAME_PATCH
int cpad = 0;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
int tx = x;
int tw = w;
drw_setscheme(drw, scheme[m == selmon ? SchemeTitleSel : SchemeTitleNorm]);
#if BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH
XSetErrorHandler(xerrordummy);
#endif // BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH
if (w <= TEXTW("A") - lrpad + tpad) // reduce text padding if wintitle is too small
tpad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2);
#if BAR_WINICON_PATCH && BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) + ipad < w)
cpad = (w - TEXTW(c->name) - ipad) / 2;
#elif BAR_CENTEREDWINDOWNAME_PATCH
else if (TEXTW(c->name) < w)
cpad = (w - TEXTW(c->name)) / 2;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
XSetForeground(drw->dpy, drw->gc, drw->scheme[ColBg].pixel);
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, a->y, w, a->h);
#if BAR_CENTEREDWINDOWNAME_PATCH
/* Apply center padding, if any */
tx += cpad;
tw -= cpad;
#endif // BAR_CENTEREDWINDOWNAME_PATCH
tx += tpad;
tw -= lrpad;
#if BAR_WINICON_PATCH
if (ipad) {
drw_pic(drw, tx, a->y + (a->h - c->ich) / 2, c->icw, c->ich, c->icon);
tx += ipad;
tw -= ipad;
}
#endif // BAR_WINICON_PATCH
drw_text(drw, tx, a->y, tw, a->h, 0, c->name, 0, False);
#if BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH
XSync(dpy, False);
XSetErrorHandler(xerror);
#endif // BAR_IGNORE_XFT_ERRORS_WHEN_DRAWING_TEXT_PATCH
drawstateindicator(m, c, 1, x, a->y, w, a->h, 0, 0, c->isfixed);
return 1;
}
int
click_wintitle(Bar *bar, Arg *arg, BarArg *a)
{
return ClkWinTitle;
}

4
patch/bar_wintitle.h Normal file
View File

@@ -0,0 +1,4 @@
static int width_wintitle(Bar *bar, BarArg *a);
static int draw_wintitle(Bar *bar, BarArg *a);
static int click_wintitle(Bar *bar, Arg *arg, BarArg *a);

View File

@@ -0,0 +1,46 @@
int
width_wintitle_floating(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_wintitle_floating(Bar *bar, BarArg *a)
{
drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1);
return calc_wintitle_floating(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a);
}
int
click_wintitle_floating(Bar *bar, Arg *arg, BarArg *a)
{
calc_wintitle_floating(bar->mon, 0, a->w, a->x, flextitleclick, arg, a);
return ClkWinTitle;
}
int
calc_wintitle_floating(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
) {
Client *c;
int clientsnfloating = 0, w, r;
int groupactive = GRP_FLOAT;
for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c) || HIDDEN(c))
continue;
if (c->isfloating)
clientsnfloating++;
}
if (!clientsnfloating)
return 0;
w = tabw / clientsnfloating;
r = tabw % clientsnfloating;
c = flextitledrawarea(m, m->clients, offx, r, w, clientsnfloating, SCHEMEFOR(GRP_FLOAT), 0, 0, 1, passx, tabfn, arg, barg);
return 1;
}

View File

@@ -0,0 +1,9 @@
static int width_wintitle_floating(Bar *bar, BarArg *a);
static int draw_wintitle_floating(Bar *bar, BarArg *a);
static int click_wintitle_floating(Bar *bar, Arg *arg, BarArg *a);
static int calc_wintitle_floating(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
);

View File

@@ -0,0 +1,46 @@
int
width_wintitle_hidden(Bar *bar, BarArg *a)
{
return a->w;
}
int
draw_wintitle_hidden(Bar *bar, BarArg *a)
{
drw_rect(drw, a->x, a->y, a->w, a->h, 1, 1);
return calc_wintitle_hidden(bar->mon, a->x, a->w, -1, flextitledraw, NULL, a);
}
int
click_wintitle_hidden(Bar *bar, Arg *arg, BarArg *a)
{
calc_wintitle_hidden(bar->mon, 0, a->w, a->x, flextitleclick, arg, a);
return ClkWinTitle;
}
int
calc_wintitle_hidden(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
) {
Client *c;
int clientsnhidden = 0, w, r;
int groupactive = GRP_HIDDEN;
for (c = m->clients; c; c = c->next) {
if (!ISVISIBLE(c))
continue;
if (HIDDEN(c))
clientsnhidden++;
}
if (!clientsnhidden)
return 0;
w = tabw / clientsnhidden;
r = tabw % clientsnhidden;
c = flextitledrawarea(m, m->clients, offx, r, w, clientsnhidden, SCHEMEFOR(GRP_HIDDEN), 0, 1, 0, passx, tabfn, arg, barg);
return 1;
}

View File

@@ -0,0 +1,9 @@
static int width_wintitle_hidden(Bar *bar, BarArg *a);
static int draw_wintitle_hidden(Bar *bar, BarArg *a);
static int click_wintitle_hidden(Bar *bar, Arg *arg, BarArg *a);
static int calc_wintitle_hidden(
Monitor *m, int offx, int tabw, int passx,
void(*tabfn)(Monitor *, Client *, int, int, int, int, Arg *arg, BarArg *barg),
Arg *arg, BarArg *barg
);

View File

@@ -0,0 +1,94 @@
void
hide(Client *c) {
Client *n;
if (!c || HIDDEN(c))
return;
Window w = c->win;
static XWindowAttributes ra, ca;
// more or less taken directly from blackbox's hide() function
XGrabServer(dpy);
XGetWindowAttributes(dpy, root, &ra);
XGetWindowAttributes(dpy, w, &ca);
// prevent UnmapNotify events
XSelectInput(dpy, root, ra.your_event_mask & ~SubstructureNotifyMask);
XSelectInput(dpy, w, ca.your_event_mask & ~StructureNotifyMask);
XUnmapWindow(dpy, w);
setclientstate(c, IconicState);
XSelectInput(dpy, root, ra.your_event_mask);
XSelectInput(dpy, w, ca.your_event_mask);
XUngrabServer(dpy);
if (c->isfloating || !c->mon->lt[c->mon->sellt]->arrange) {
for (n = c->snext; n && (!ISVISIBLE(n) || HIDDEN(n)); n = n->snext);
if (!n)
for (n = c->mon->stack; n && (!ISVISIBLE(n) || HIDDEN(n)); n = n->snext);
} else {
n = nexttiled(c);
if (!n)
n = prevtiled(c);
}
focus(n);
arrange(c->mon);
}
void
show(Client *c)
{
if (!c || !HIDDEN(c))
return;
XMapWindow(dpy, c->win);
setclientstate(c, NormalState);
arrange(c->mon);
}
void
togglewin(const Arg *arg)
{
Client *c = (Client*)arg->v;
if (!c)
return;
if (c == selmon->sel)
hide(c);
else {
if (HIDDEN(c))
show(c);
focus(c);
restack(c->mon);
}
}
Client *
prevtiled(Client *c)
{
Client *p, *i;
for (p = NULL, i = c->mon->clients; c && i != c; i = i->next)
if (ISVISIBLE(i) && !HIDDEN(i))
p = i;
return p;
}
void
showhideclient(const Arg *arg)
{
Client *c = (Client*)arg->v;
if (!c)
c = selmon->sel;
if (!c)
return;
#if WARP_PATCH
force_warp = 1;
#endif // WARP_PATCH
if (HIDDEN(c)) {
show(c);
focus(c);
restack(c->mon);
} else {
hide(c);
}
}

View File

@@ -0,0 +1,6 @@
static void hide(Client *c);
static void show(Client *c);
static void togglewin(const Arg *arg);
static Client * prevtiled(Client *c);
static void showhideclient(const Arg *arg);

24
patch/cfacts.c Normal file
View File

@@ -0,0 +1,24 @@
void
setcfact(const Arg *arg)
{
float f;
Client *c;
c = selmon->sel;
if (!arg || !c || !selmon->lt[selmon->sellt]->arrange)
return;
if (!arg->f)
f = 1.0;
else if (arg->f > 4.0) // set fact absolutely
f = arg->f - 4.0;
else
f = arg->f + c->cfact;
if (f < 0.25)
f = 0.25;
else if (f > 4.0)
f = 4.0;
c->cfact = f;
arrange(selmon);
}

2
patch/cfacts.h Normal file
View File

@@ -0,0 +1,2 @@
static void setcfact(const Arg *arg);

6
patch/cmdcustomize.c Normal file
View File

@@ -0,0 +1,6 @@
char*
help(void)
{
return "usage: dwm [-hv] [-fn font] [-nb color] [-nf color] [-sb color] [-sf color]\n[-df font] [-dnf color] [-dnb color] [-dsf color] [-dsb color]\n";
}

2
patch/cmdcustomize.h Normal file
View File

@@ -0,0 +1,2 @@
static char* help();

39
patch/combo.c Normal file
View File

@@ -0,0 +1,39 @@
static int combo = 0;
#if !BAR_HOLDBAR_PATCH
void
keyrelease(XEvent *e)
{
combo = 0;
}
#endif // !BAR_HOLDBAR_PATCH
void
combotag(const Arg *arg)
{
if (selmon->sel && arg->ui & TAGMASK) {
#if SWITCHTAG_PATCH
if (selmon->sel->switchtag)
selmon->sel->switchtag = 0;
#endif // SWITCHTAG_PATCH
if (combo) {
selmon->sel->tags |= arg->ui & TAGMASK;
} else {
combo = 1;
selmon->sel->tags = arg->ui & TAGMASK;
}
arrange(selmon);
focus(NULL);
}
}
void
comboview(const Arg *arg)
{
if (combo) {
view(&((Arg) { .ui = selmon->tagset[selmon->seltags] | (arg->ui & TAGMASK) }));
} else {
combo = 1;
view(arg);
}
}

6
patch/combo.h Normal file
View File

@@ -0,0 +1,6 @@
#if !BAR_HOLDBAR_PATCH
static void keyrelease(XEvent *e);
#endif // !BAR_HOLDBAR_PATCH
static void combotag(const Arg *arg);
static void comboview(const Arg *arg);

37
patch/cool_autostart.c Normal file
View File

@@ -0,0 +1,37 @@
/* 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;
struct sigaction sa;
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();
/* Restore SIGCHLD sighandler to default before spawning a program */
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
sa.sa_handler = SIG_DFL;
sigaction(SIGCHLD, &sa, NULL);
execvp(*p, (char *const *)p);
fprintf(stderr, "dwm: execvp %s\n", *p);
perror(" failed");
_exit(EXIT_FAILURE);
}
/* skip arguments */
while (*++p);
}
}

2
patch/cool_autostart.h Normal file
View File

@@ -0,0 +1,2 @@
static void autostart_exec(void);

10
patch/cyclelayouts.c Normal file
View File

@@ -0,0 +1,10 @@
void
cyclelayout(const Arg *arg)
{
int i;
int num_layouts = LENGTH(layouts);
for (i = 0; i < num_layouts && &layouts[i] != selmon->lt[selmon->sellt]; i++);
i += arg->i;
setlayout(&((Arg) { .v = &layouts[(i % num_layouts + num_layouts) % num_layouts] })); // modulo
}

2
patch/cyclelayouts.h Normal file
View File

@@ -0,0 +1,2 @@
static void cyclelayout(const Arg *arg);

39
patch/decorationhints.c Normal file
View File

@@ -0,0 +1,39 @@
static Atom motifatom;
void
updatemotifhints(Client *c)
{
Atom real;
int format;
unsigned char *p = NULL;
unsigned long n, extra;
unsigned long *motif;
int width, height;
if (!decorhints)
return;
if (XGetWindowProperty(dpy, c->win, motifatom, 0L, 5L, False, motifatom,
&real, &format, &n, &extra, &p) == Success && p != NULL) {
motif = (unsigned long*)p;
if (motif[MWM_HINTS_FLAGS_FIELD] & MWM_HINTS_DECORATIONS) {
width = WIDTH(c);
height = HEIGHT(c);
if (motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_ALL ||
motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_BORDER ||
motif[MWM_HINTS_DECORATIONS_FIELD] & MWM_DECOR_TITLE)
#if SETBORDERPX_PATCH
c->bw = c->oldbw = c->mon->borderpx;
#else
c->bw = c->oldbw = borderpx;
#endif // SETBORDERPX_PATCH
else
c->bw = c->oldbw = 0;
resize(c, c->x, c->y, width - (2*c->bw), height - (2*c->bw), 0);
}
XFree(p);
}
}

9
patch/decorationhints.h Normal file
View File

@@ -0,0 +1,9 @@
#define MWM_HINTS_FLAGS_FIELD 0
#define MWM_HINTS_DECORATIONS_FIELD 2
#define MWM_HINTS_DECORATIONS (1 << 1)
#define MWM_DECOR_ALL (1 << 0)
#define MWM_DECOR_BORDER (1 << 1)
#define MWM_DECOR_TITLE (1 << 3)
static void updatemotifhints(Client *c);

31
patch/distributetags.c Normal file
View File

@@ -0,0 +1,31 @@
void
distributetags(const Arg *arg)
{
Client *c;
unsigned int ui = 1;
int i = 0;
#if TAGSYNC_PATCH
Monitor *origselmon = selmon;
for (selmon = mons; selmon; selmon = selmon->next) {
#endif // TAGSYNC_PATCH
for (c = selmon->clients; c; c = c->next) {
if (HIDDEN(c))
continue;
if (!(c->tags & TAGMASK))
continue;
c->tags = (ui << i) & TAGMASK;
i = (i + 1) % NUMTAGS;
}
#if TAGSYNC_PATCH
}
selmon = origselmon;
arrange(NULL);
focus(NULL);
#else
arrange(selmon);
focus(NULL);
#endif // TAGSYNC_PATCH
}

2
patch/distributetags.h Normal file
View File

@@ -0,0 +1,2 @@
static void distributetags(const Arg *arg);

83
patch/dragcfact.c Normal file
View File

@@ -0,0 +1,83 @@
void
dragcfact(const Arg *arg)
{
int prev_x, prev_y, dist_x, dist_y;
float fact;
Client *c;
XEvent ev;
Time lasttime = 0;
if (!(c = selmon->sel))
return;
if (c->isfloating) {
resizemouse(arg);
return;
}
#if !FAKEFULLSCREEN_PATCH
#if FAKEFULLSCREEN_CLIENT_PATCH
if (c->isfullscreen && !c->fakefullscreen) /* no support resizing fullscreen windows by mouse */
return;
#else
if (c->isfullscreen) /* no support resizing fullscreen windows by mouse */
return;
#endif // FAKEFULLSCREEN_CLIENT_PATCH
#endif // !FAKEFULLSCREEN_PATCH
restack(selmon);
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[CurIronCross]->cursor, CurrentTime) != GrabSuccess)
return;
#if WARP_PATCH
ignore_warp = 1;
#endif // WARP_PATCH
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
prev_x = prev_y = -999999;
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;
if (prev_x == -999999) {
prev_x = ev.xmotion.x_root;
prev_y = ev.xmotion.y_root;
}
dist_x = ev.xmotion.x - prev_x;
dist_y = ev.xmotion.y - prev_y;
if (abs(dist_x) > abs(dist_y)) {
fact = (float) 4.0 * dist_x / c->mon->ww;
} else {
fact = (float) -4.0 * dist_y / c->mon->wh;
}
if (fact)
setcfact(&((Arg) { .f = fact }));
prev_x = ev.xmotion.x;
prev_y = ev.xmotion.y;
break;
}
} while (ev.type != ButtonRelease);
#if WARP_PATCH
ignore_warp = 0;
#endif // WARP_PATCH
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}

2
patch/dragcfact.h Normal file
View File

@@ -0,0 +1,2 @@
static void dragcfact(const Arg *arg);

232
patch/dragmfact.c Normal file
View File

@@ -0,0 +1,232 @@
void
dragmfact(const Arg *arg)
{
unsigned int n;
int py, px; // pointer coordinates
int ax, ay, aw, ah; // area position, width and height
int center = 0, horizontal = 0, mirror = 0, fixed = 0; // layout configuration
double fact;
Monitor *m;
XEvent ev;
Time lasttime = 0;
m = selmon;
#if VANITYGAPS_PATCH
int oh, ov, ih, iv;
getgaps(m, &oh, &ov, &ih, &iv, &n);
#else
Client *c;
for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
#endif // VANITYGAPS_PATCH
ax = m->wx;
ay = m->wy;
ah = m->wh;
aw = m->ww;
if (!n)
return;
#if FLEXTILE_DELUXE_LAYOUT
else if (m->lt[m->sellt]->arrange == &flextile) {
int layout = m->ltaxis[LAYOUT];
if (layout < 0) {
mirror = 1;
layout *= -1;
}
if (layout > FLOATING_MASTER) {
layout -= FLOATING_MASTER;
fixed = 1;
}
if (layout == SPLIT_HORIZONTAL || layout == SPLIT_HORIZONTAL_DUAL_STACK)
horizontal = 1;
else if (layout == SPLIT_CENTERED_VERTICAL && (fixed || n - m->nmaster > 1))
center = 1;
else if (layout == FLOATING_MASTER) {
center = 1;
if (aw < ah)
horizontal = 1;
}
else if (layout == SPLIT_CENTERED_HORIZONTAL) {
if (fixed || n - m->nmaster > 1)
center = 1;
horizontal = 1;
}
}
#endif // FLEXTILE_DELUXE_LAYOUT
#if CENTEREDMASTER_LAYOUT
else if (m->lt[m->sellt]->arrange == &centeredmaster && (fixed || n - m->nmaster > 1))
center = 1;
#endif // CENTEREDMASTER_LAYOUT
#if CENTEREDFLOATINGMASTER_LAYOUT
else if (m->lt[m->sellt]->arrange == &centeredfloatingmaster)
center = 1;
#endif // CENTEREDFLOATINGMASTER_LAYOUT
#if BSTACK_LAYOUT
else if (m->lt[m->sellt]->arrange == &bstack)
horizontal = 1;
#endif // BSTACK_LAYOUT
#if BSTACKHORIZ_LAYOUT
else if (m->lt[m->sellt]->arrange == &bstackhoriz)
horizontal = 1;
#endif // BSTACKHORIZ_LAYOUT
/* do not allow mfact to be modified under certain conditions */
if (!m->lt[m->sellt]->arrange // floating layout
|| (!fixed && m->nmaster && n <= m->nmaster) // no master
#if MONOCLE_LAYOUT
|| m->lt[m->sellt]->arrange == &monocle
#endif // MONOCLE_LAYOUT
#if GRIDMODE_LAYOUT
|| m->lt[m->sellt]->arrange == &grid
#endif // GRIDMODE_LAYOUT
#if HORIZGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &horizgrid
#endif // HORIZGRID_LAYOUT
#if GAPPLESSGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &gaplessgrid
#endif // GAPPLESSGRID_LAYOUT
#if NROWGRID_LAYOUT
|| m->lt[m->sellt]->arrange == &nrowgrid
#endif // NROWGRID_LAYOUT
#if FLEXTILE_DELUXE_LAYOUT
|| (m->lt[m->sellt]->arrange == &flextile && m->ltaxis[LAYOUT] == NO_SPLIT)
#endif // FLEXTILE_DELUXE_LAYOUT
)
return;
#if VANITYGAPS_PATCH
ay += oh;
ax += ov;
aw -= 2*ov;
ah -= 2*oh;
#endif // VANITYGAPS_PATCH
if (center) {
if (horizontal) {
px = ax + aw / 2;
#if VANITYGAPS_PATCH
py = ay + ah / 2 + (ah - 2*ih) * (m->mfact / 2.0) + ih / 2;
#else
py = ay + ah / 2 + ah * m->mfact / 2.0;
#endif // VANITYGAPS_PATCH
} else { // vertical split
#if VANITYGAPS_PATCH
px = ax + aw / 2 + (aw - 2*iv) * m->mfact / 2.0 + iv / 2;
#else
px = ax + aw / 2 + aw * m->mfact / 2.0;
#endif // VANITYGAPS_PATCH
py = ay + ah / 2;
}
} else if (horizontal) {
px = ax + aw / 2;
if (mirror)
#if VANITYGAPS_PATCH
py = ay + (ah - ih) * (1.0 - m->mfact) + ih / 2;
#else
py = ay + (ah * (1.0 - m->mfact));
#endif // VANITYGAPS_PATCH
else
#if VANITYGAPS_PATCH
py = ay + ((ah - ih) * m->mfact) + ih / 2;
#else
py = ay + (ah * m->mfact);
#endif // VANITYGAPS_PATCH
} else { // vertical split
if (mirror)
#if VANITYGAPS_PATCH
px = ax + (aw - iv) * (1.0 - m->mfact) + iv / 2;
#else
px = ax + (aw * m->mfact);
#endif // VANITYGAPS_PATCH
else
#if VANITYGAPS_PATCH
px = ax + ((aw - iv) * m->mfact) + iv / 2;
#else
px = ax + (aw * m->mfact);
#endif // VANITYGAPS_PATCH
py = ay + ah / 2;
}
if (XGrabPointer(dpy, root, False, MOUSEMASK, GrabModeAsync, GrabModeAsync,
None, cursor[horizontal ? CurResizeVertArrow : CurResizeHorzArrow]->cursor, CurrentTime) != GrabSuccess)
return;
#if WARP_PATCH
ignore_warp = 1;
#endif // WARP_PATCH
XWarpPointer(dpy, None, root, 0, 0, 0, 0, px, py);
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 / 40))
continue;
if (lasttime != 0) {
px = ev.xmotion.x;
py = ev.xmotion.y;
}
lasttime = ev.xmotion.time;
#if VANITYGAPS_PATCH
if (center)
if (horizontal)
if (py - ay > ah / 2)
fact = (double) 1.0 - (ay + ah - py - ih / 2) * 2 / (double) (ah - 2*ih);
else
fact = (double) 1.0 - (py - ay - ih / 2) * 2 / (double) (ah - 2*ih);
else
if (px - ax > aw / 2)
fact = (double) 1.0 - (ax + aw - px - iv / 2) * 2 / (double) (aw - 2*iv);
else
fact = (double) 1.0 - (px - ax - iv / 2) * 2 / (double) (aw - 2*iv);
else
if (horizontal)
fact = (double) (py - ay - ih / 2) / (double) (ah - ih);
else
fact = (double) (px - ax - iv / 2) / (double) (aw - iv);
#else
if (center)
if (horizontal)
if (py - ay > ah / 2)
fact = (double) 1.0 - (ay + ah - py) * 2 / (double) ah;
else
fact = (double) 1.0 - (py - ay) * 2 / (double) ah;
else
if (px - ax > aw / 2)
fact = (double) 1.0 - (ax + aw - px) * 2 / (double) aw;
else
fact = (double) 1.0 - (px - ax) * 2 / (double) aw;
else
if (horizontal)
fact = (double) (py - ay) / (double) ah;
else
fact = (double) (px - ax) / (double) aw;
#endif // VANITYGAPS_PATCH
if (!center && mirror)
fact = 1.0 - fact;
setmfact(&((Arg) { .f = 1.0 + fact }));
px = ev.xmotion.x;
py = ev.xmotion.y;
break;
}
} while (ev.type != ButtonRelease);
#if WARP_PATCH
ignore_warp = 0;
#endif // WARP_PATCH
XUngrabPointer(dpy, CurrentTime);
while (XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}

2
patch/dragmfact.h Normal file
View File

@@ -0,0 +1,2 @@
static void dragmfact(const Arg *arg);

136
patch/dwmc Executable file
View File

@@ -0,0 +1,136 @@
#!/usr/bin/env bash
signal() {
xsetroot -name "fsignal:$*"
}
case $# in
1)
case $1 in
focusurgent) ;&
mirrorlayout) ;&
mpdcontrol) ;&
nametag) ;&
pushdown) ;&
pushup) ;&
self_restart) ;&
setlayout) ;&
setcfact) ;&
showhideclient) ;&
switchcol) ;&
view) ;&
viewall) ;&
viewtoleft) ;&
viewtoright) ;&
tagtoleft) ;&
tagtoright) ;&
tagandviewtoleft) ;&
tagandviewtoright) ;&
transfer) ;&
transferall) ;&
togglealttag) ;&
togglebar) ;&
toggletopbar) ;&
togglefloating) ;&
togglefullscreen) ;&
fullscreen) ;&
togglefakefullscreen) ;&
togglesticky) ;&
togglehorizontalmax) ;&
toggleverticalmax) ;&
togglemax) ;&
togglegaps) ;&
defaultgaps) ;&
unfloatvisible) ;&
winview) ;&
xrdb) ;&
zoom) ;&
killclient) ;&
quit)
signal $1
;;
*)
echo "Unknown command ($1) or missing one argument."
exit 1
;;
esac
;;
2)
case $1 in
cyclelayout) ;&
explace) ;&
moveplace) ;&
mpdchange) ;&
setkeymode) ;&
switchtag) ;&
togglescratch) ;&
view)
signal $1 ui $2
;;
viewex) ;&
toggleviewex) ;&
tagallmon) ;&
tagswapmon) ;&
tagex) ;&
toggletagex) ;&
setborderpx) ;&
setgaps) ;&
setlayoutex) ;&
setlayoutaxisex) ;&
swapfocus) ;&
focusstack) ;&
pushstack) ;&
inplacerotate) ;&
rotatestack) ;&
rotatelayoutaxis) ;&
incnmaster) ;&
incnstack) ;&
incrgaps) ;&
incrigaps) ;&
incrogaps) ;&
incrihgaps) ;&
incrivgaps) ;&
incrohgaps) ;&
incrovgaps) ;&
movestack) ;&
shiftview) ;&
shiftviewclients) ;&
focusmon) ;&
tagmon)
signal $1 i $2
;;
setcfact) ;&
setmfact)
signal $1 f $2
;;
floatpos)
signal $1 v $2
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac
;;
5)
case $1 in
setgaps)
# Expects "setgaps oh ov ih iv" where -1 means to keep existing values
[ $2 = -1 ] && oh=128 || oh=$2
[ $3 = -1 ] && ov=128 || ov=$3
[ $4 = -1 ] && ih=128 || ih=$4
[ $5 = -1 ] && iv=128 || iv=$5
signal $1 i $(((oh << 24) + (ov << 16) + (ih << 8) + iv))
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac
;;
*)
echo "Unknown command ($1) or too many arguments"
exit 1
;;
esac

103
patch/dwmc.c Normal file
View File

@@ -0,0 +1,103 @@
void
setlayoutex(const Arg *arg)
{
setlayout(&((Arg) { .v = &layouts[arg->i] }));
}
void
viewex(const Arg *arg)
{
view(&((Arg) { .ui = 1 << arg->ui }));
}
void
viewallex(const Arg *arg)
{
#if SCRATCHPADS_PATCH && !RENAMED_SCRATCHPADS_PATCH
view(&((Arg){.ui = ~SPTAGMASK}));
#else
view(&((Arg){.ui = ~0}));
#endif // SCRATCHPADS_PATCH
}
void
toggleviewex(const Arg *arg)
{
toggleview(&((Arg) { .ui = 1 << arg->ui }));
}
void
tagex(const Arg *arg)
{
tag(&((Arg) { .ui = 1 << arg->ui }));
}
void
toggletagex(const Arg *arg)
{
toggletag(&((Arg) { .ui = 1 << arg->ui }));
}
void
tagallex(const Arg *arg)
{
#if SCRATCHPADS_PATCH && !RENAMED_SCRATCHPADS_PATCH
tag(&((Arg){.ui = ~SPTAGMASK}));
#else
tag(&((Arg){.ui = ~0}));
#endif // SCRATCHPADS_PATCH
}
int
fake_signal(void)
{
char fsignal[256];
char indicator[9] = "fsignal:";
char str_sig[50];
char param[16];
int i, len_str_sig, n, paramn;
size_t len_fsignal, len_indicator = strlen(indicator);
Arg arg;
// Get root name property
if (gettextprop(root, XA_WM_NAME, fsignal, sizeof(fsignal))) {
len_fsignal = strlen(fsignal);
// Check if this is indeed a fake signal
if (len_indicator > len_fsignal ? 0 : strncmp(indicator, fsignal, len_indicator) == 0) {
paramn = sscanf(fsignal+len_indicator, "%s%n%s%n", str_sig, &len_str_sig, param, &n);
if (paramn == 1) arg = (Arg) {0};
else if (paramn > 2) return 1;
else if (strncmp(param, "i", n - len_str_sig) == 0)
#if IPC_PATCH
sscanf(fsignal + len_indicator + n, "%li", &(arg.i));
#else
sscanf(fsignal + len_indicator + n, "%i", &(arg.i));
#endif // IPC_PATCH
else if (strncmp(param, "ui", n - len_str_sig) == 0)
#if IPC_PATCH
sscanf(fsignal + len_indicator + n, "%lu", &(arg.ui));
#else
sscanf(fsignal + len_indicator + n, "%u", &(arg.ui));
#endif // IPC_PATCH
else if (strncmp(param, "f", n - len_str_sig) == 0)
sscanf(fsignal + len_indicator + n, "%f", &(arg.f));
else if (strncmp(param, "v", n - len_str_sig) == 0)
arg.v = &(fsignal[len_indicator + n + 1]);
else return 1;
// Check if a signal was found, and if so handle it
for (i = 0; i < LENGTH(signals); i++)
if (strncmp(str_sig, signals[i].sig, len_str_sig) == 0 && signals[i].func)
signals[i].func(&(arg));
// A fake signal was sent
return 1;
}
}
// No fake signal was sent, so proceed with update
return 0;
}

14
patch/dwmc.h Normal file
View File

@@ -0,0 +1,14 @@
typedef struct {
const char * sig;
void (*func)(const Arg *);
} Signal;
static void setlayoutex(const Arg *arg);
static void viewex(const Arg *arg);
static void viewallex(const Arg *arg);
static void toggleviewex(const Arg *arg);
static void tagex(const Arg *arg);
static void toggletagex(const Arg *arg);
static void tagallex(const Arg *arg);
static int fake_signal(void);

196
patch/exresize.c Normal file
View File

@@ -0,0 +1,196 @@
#define EXPAND_LEFT (1 << 0)
#define EXPAND_RIGHT (1 << 2)
#define EXPAND_UP (1 << 4)
#define EXPAND_DOWN (1 << 6)
#define IS_SET(q, w) ((q & w) != 0)
#define IS_FORCED(q, w) IS_SET((q << 1), w)
#define EXPANDALL (EXPAND_LEFT | EXPAND_RIGHT | EXPAND_UP | EXPAND_DOWN)
#define UNEXPAND (EXPANDALL << 1) // Force all directions to 0
#define FORCE_EXPANDALL ~0 // Force expand in all directions
void
exresize(const Arg *arg)
{
Client *c;
int x, y, nx, ny, nw, nh;
c = selmon->sel;
if (!c || !arg) return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
togglefloating(NULL);
if (c->expandmask != 0)
expand(UNEXPAND);
x = ((int *)arg->v)[0];
y = ((int *)arg->v)[1];
nw = MIN(selmon->ww - c->bw*2, c->w + x);
nh = MIN(selmon->wh - c->bw*2, c->h + y);
nx = c->x - x/2;
ny = c->y - y/2;
if (!((abs(c->x + c->w/2 - (selmon->wx + selmon->ww/2)) < snap))) {
if ((nw == selmon->ww) ||
(nx < selmon->wx) ||
(abs(selmon->wx - c->x) < snap))
nx = selmon->wx;
else if ((nx+nw > (selmon->wx + selmon->ww)) ||
(abs((selmon->wx + selmon->ww) - (c->x + c->w)) < snap))
nx = (selmon->wx + selmon->ww) - nw - c->bw*2;
} else
nx = selmon->wx + selmon->ww/2 - nw/2;
if (!((abs(c->y + c->h/2 - (selmon->wy + selmon->wh/2)) < snap))) {
if ((nh == selmon->wh) ||
(ny < selmon->wy) ||
(abs(selmon->wy - c->y) < snap))
ny = selmon->wy;
else if ((ny+nh > (selmon->wy + selmon->wh)) ||
(abs((selmon->wy + selmon->wh) - (c->y + c->h)) < snap))
ny = (selmon->wy + selmon->wh) - nh - c->bw*2;
} else
ny = selmon->wy + selmon->wh/2 - nh/2;
resizeclient(c, nx, ny, MAX(nw, 32), MAX(nh, 32));
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
}
void
explace(const Arg *arg)
{
Client *c;
int nx, ny;
c = selmon->sel;
if (!c || (arg->ui >= 9)) return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
togglefloating(NULL);
nx = (arg->ui % 3) - 1;
ny = (arg->ui / 3) - 1;
if (nx < 0) nx = selmon->wx;
else if (nx > 0) nx = selmon->wx + selmon->ww - c->w - c->bw*2;
else nx = selmon->wx + selmon->ww/2 - c->w/2;
if (ny < 0) ny = selmon->wy;
else if (ny > 0) ny = selmon->wy + selmon->wh - c->h - c->bw*2;
else ny = selmon->wy + selmon->wh/2 - c->h/2;
resize(c, nx, ny, c->w, c->h, True);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
}
int
calculate_expand(unsigned char mask, unsigned char curmask,
unsigned char *newmask, unsigned char key,
int *reset_value, int new_reset_value,
int max_value, int old_value)
{
if (IS_SET(key, mask) ||
(IS_SET(key, curmask) && (!IS_SET(key, mask) && IS_FORCED(key, mask))) ||
(!IS_SET(key, curmask) && (IS_SET(key, mask) && IS_FORCED(key, mask)))) {
if (IS_SET(key, mask) && (!IS_SET(key,curmask) || IS_FORCED(key,mask))) {
if (!IS_SET(key, curmask))
*reset_value = new_reset_value;
*newmask |= key;
return max_value;
} else if ((IS_SET(key,curmask) && IS_SET(key, mask)) ||
(!IS_SET(key, mask) && IS_FORCED(key, mask))) {
*newmask &= ~key;
return *reset_value;
} else {
*newmask &= ~key;
return old_value;
}
} else
return new_reset_value;
}
void
expand(unsigned char mask)
{
XEvent ev;
int nx1, ny1, nx2, ny2;
#if SETBORDERPX_PATCH
int bp = selmon->borderpx;
#else
int bp = borderpx;
#endif // SETBORDERPX_PATCH
unsigned char curmask;
unsigned char newmask;
if (!selmon->sel || selmon->sel->isfixed)
return;
XRaiseWindow(dpy, selmon->sel->win);
newmask = curmask = selmon->sel->expandmask;
if (curmask == 0) {
if(!selmon->lt[selmon->sellt]->arrange || selmon->sel->isfloating)
selmon->sel->wasfloating = 1;
else {
togglefloating(NULL);
selmon->sel->wasfloating = 0;
}
}
nx1 = calculate_expand(mask, curmask, &newmask,
EXPAND_LEFT, &selmon->sel->expandx1,
selmon->sel->x,
selmon->wx,
selmon->sel->oldx);
nx2 = calculate_expand(mask, curmask, &newmask,
EXPAND_RIGHT, &selmon->sel->expandx2,
selmon->sel->x + selmon->sel->w,
selmon->wx + selmon->ww - 2*bp,
selmon->sel->oldw + selmon->sel->x);
ny1 = calculate_expand(mask, curmask, &newmask,
EXPAND_UP, &selmon->sel->expandy1,
selmon->sel->y,
selmon->wy,
selmon->sel->oldy);
ny2 = calculate_expand(mask, curmask, &newmask,
EXPAND_DOWN, &selmon->sel->expandy2,
selmon->sel->y + selmon->sel->h,
selmon->wy + selmon->wh - 2*bp,
selmon->sel->oldh + selmon->sel->y);
resizeclient(selmon->sel, nx1, ny1, MAX(nx2-nx1, 32), MAX(ny2-ny1, 32));
if ((newmask == 0) && (!selmon->sel->wasfloating))
togglefloating(NULL);
selmon->sel->expandmask = newmask;
drawbar(selmon);
while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
}
void
togglemaximize(const Arg *arg)
{
if (arg->i > 0) expand(FORCE_EXPANDALL);
else if (arg->i < 0) expand(UNEXPAND);
else expand(EXPANDALL);
}
void
toggleverticalexpand(const Arg *arg)
{
if (arg->i < 0) expand(EXPAND_DOWN);
else if (arg->i > 0) expand(EXPAND_UP);
else expand(EXPAND_DOWN | EXPAND_UP);
}
void
togglehorizontalexpand(const Arg *arg)
{
if (arg->i < 0) expand(EXPAND_LEFT);
else if (arg->i > 0) expand(EXPAND_RIGHT);
else expand(EXPAND_LEFT | EXPAND_RIGHT);
}

9
patch/exresize.h Normal file
View File

@@ -0,0 +1,9 @@
enum { EX_NW, EX_N, EX_NE, EX_W, EX_C, EX_E, EX_SW, EX_S, EX_SE };
void expand(unsigned char mask);
void togglemaximize(const Arg *arg);
void toggleverticalexpand(const Arg *arg);
void togglehorizontalexpand(const Arg *arg);
void exresize(const Arg *arg);
void explace(const Arg *arg);

View File

@@ -0,0 +1,19 @@
void
togglefakefullscreen(const Arg *arg)
{
Client *c = selmon->sel;
if (!c)
return;
if (c->fakefullscreen != 1 && c->isfullscreen) { // exit fullscreen --> fake fullscreen
c->fakefullscreen = 2;
setfullscreen(c, 0);
} else if (c->fakefullscreen == 1) {
setfullscreen(c, 0);
c->fakefullscreen = 0;
} else {
c->fakefullscreen = 1;
setfullscreen(c, 1);
}
}

View File

@@ -0,0 +1,2 @@
static void togglefakefullscreen(const Arg *arg);

195
patch/floatpos.c Normal file
View File

@@ -0,0 +1,195 @@
void
floatpos(const Arg *arg)
{
Client *c = selmon->sel;
if (!c || (selmon->lt[selmon->sellt]->arrange && !c->isfloating))
return;
setfloatpos(c, (char *)arg->v);
resizeclient(c, c->x, c->y, c->w, c->h);
#if !FOCUSONCLICK_PATCH
XRaiseWindow(dpy, c->win);
XWarpPointer(dpy, None, c->win, 0, 0, 0, 0, c->w/2, c->h/2);
#endif // FOCUSONCLICK_PATCH
}
void
setfloatpos(Client *c, const char *floatpos)
{
char xCh, yCh, wCh, hCh;
int x, y, w, h, wx, ww, wy, wh;
#if FLOATPOS_RESPECT_GAPS_PATCH && VANITYGAPS_PATCH
int oh, ov, ih, iv;
unsigned int n;
#endif // FLOATPOS_RESPECT_GAPS_PATCH | VANITYGAPS_PATCH
if (!c || !floatpos)
return;
if (selmon->lt[selmon->sellt]->arrange && !c->isfloating)
return;
switch(sscanf(floatpos, "%d%c %d%c %d%c %d%c", &x, &xCh, &y, &yCh, &w, &wCh, &h, &hCh)) {
case 4:
if (xCh == 'w' || xCh == 'W') {
w = x; wCh = xCh;
h = y; hCh = yCh;
x = -1; xCh = 'C';
y = -1; yCh = 'C';
} else if (xCh == 'p' || xCh == 'P') {
w = x; wCh = xCh;
h = y; hCh = yCh;
x = 0; xCh = 'G';
y = 0; yCh = 'G';
} else if (xCh == 'm' || xCh == 'M') {
getrootptr(&x, &y);
} else {
w = 0; wCh = 0;
h = 0; hCh = 0;
}
break;
case 8:
if (xCh == 'm' || xCh == 'M')
getrootptr(&x, &y);
break;
default:
return;
}
#if FLOATPOS_RESPECT_GAPS_PATCH && VANITYGAPS_PATCH
getgaps(c->mon, &oh, &ov, &ih, &iv, &n);
wx = c->mon->wx + ov;
wy = c->mon->wy + oh;
ww = c->mon->ww - 2*ov;
wh = c->mon->wh - 2*oh;
#else
wx = c->mon->wx;
wy = c->mon->wy;
ww = c->mon->ww;
wh = c->mon->wh;
#endif // FLOATPOS_RESPECT_GAPS_PATCH | VANITYGAPS_PATCH
getfloatpos(x, xCh, w, wCh, wx, ww, c->x, c->w, c->bw, floatposgrid_x, &c->x, &c->w);
getfloatpos(y, yCh, h, hCh, wy, wh, c->y, c->h, c->bw, floatposgrid_y, &c->y, &c->h);
}
/* p - position, s - size, cp and cs represents current position and size */
void
getfloatpos(int pos, char pCh, int size, char sCh, int min_p, int max_s, int cp, int cs, int cbw, int defgrid, int *out_p, int *out_s)
{
int abs_p, abs_s, i, delta, rest;
abs_p = pCh == 'A' || pCh == 'a';
abs_s = sCh == 'A' || sCh == 'a';
cs += 2*cbw;
switch(pCh) {
case 'A': // absolute position
cp = pos;
break;
case 'a': // absolute relative position
cp += pos;
break;
case 'y':
case 'x': // client relative position
cp = MIN(cp + pos, min_p + max_s);
break;
case 'Y':
case 'X': // client position relative to monitor
cp = min_p + MIN(pos, max_s);
break;
case 'S': // fixed client position (sticky)
case 'C': // fixed client position (center)
case 'Z': // fixed client right-hand position (position + size)
if (pos == -1)
break;
pos = MAX(MIN(pos, max_s), 0);
if (pCh == 'Z')
cs = abs((cp + cs) - (min_p + pos));
else if (pCh == 'C')
cs = abs((cp + cs / 2) - (min_p + pos));
else
cs = abs(cp - (min_p + pos));
cp = min_p + pos;
sCh = 0; // size determined by position, override defined size
break;
case 'G': // grid
if (pos <= 0)
pos = defgrid; // default configurable
if (size == 0 || pos < 2 || (sCh != 'p' && sCh != 'P'))
break;
delta = (max_s - cs) / (pos - 1);
rest = max_s - cs - delta * (pos - 1);
if (sCh == 'P') {
if (size < 1 || size > pos)
break;
cp = min_p + delta * (size - 1);
} else {
for (i = 0; i < pos && cp >= min_p + delta * i + (i > pos - rest ? i + rest - pos + 1 : 0); i++);
cp = min_p + delta * (MAX(MIN(i + size, pos), 1) - 1) + (i > pos - rest ? i + rest - pos + 1 : 0);
}
break;
}
switch(sCh) {
case 'A': // absolute size
cs = size;
break;
case 'a': // absolute relative size
cs = MAX(1, cs + size);
break;
case '%': // client size percentage in relation to monitor window area size
if (size <= 0)
break;
size = max_s * MIN(size, 100) / 100;
/* falls through */
case 'h':
case 'w': // size relative to client
if (sCh == 'w' || sCh == 'h') {
if (size == 0)
break;
size += cs;
}
/* falls through */
case 'H':
case 'W': // normal size, position takes precedence
if (pCh == 'S' && cp + size > min_p + max_s)
size = min_p + max_s - cp;
else if (size > max_s)
size = max_s;
if (pCh == 'C') { // fixed client center, expand or contract client
delta = size - cs;
if (delta < 0 || (cp - delta / 2 + size <= min_p + max_s))
cp -= delta / 2;
else if (cp - delta / 2 < min_p)
cp = min_p;
else if (delta)
cp = min_p + max_s;
} else if (pCh == 'Z')
cp -= size - cs;
cs = size;
break;
}
if (pCh == '%') // client mid-point position in relation to monitor window area size
cp = min_p + max_s * MAX(MIN(pos, 100), 0) / 100 - (cs) / 2;
if (pCh == 'm' || pCh == 'M')
cp = pos - cs / 2;
if (!abs_p && cp < min_p)
cp = min_p;
if (cp + cs > min_p + max_s && !(abs_p && abs_s)) {
if (abs_p || cp == min_p)
cs = min_p + max_s - cp;
else
cp = min_p + max_s - cs;
}
*out_p = cp;
*out_s = MAX(cs - 2*cbw, 1);
}

Some files were not shown because too many files have changed in this diff Show More