@ -0,0 +1,50 @@ | |||||
static const Rule rules[] = { | |||||
/* xprop(1): | |||||
* WM_CLASS(STRING) = instance, class | |||||
* WM_NAME(STRING) = title | |||||
* WM_WINDOW_ROLE(STRING) = role | |||||
* _NET_WM_WINDOW_TYPE(ATOM) = wintype | |||||
*/ | |||||
RULE(.class = "discord", .tags = 1 << 8) | |||||
RULE(.class = "firefoxdeveloperedition", .tags = 1 << 1) | |||||
RULE(.class = "Brave-browser", .tags = 1 << 1) | |||||
RULE(.class = "firefox", .tags = 1 << 1) | |||||
RULE(.class = "tabbed-surf", .tags = 1 << 1) | |||||
RULE(.class = "bitwarden", .tags = 1 << 6) | |||||
RULE(.class = "QtPass", .tags = 1 << 6) | |||||
RULE(.class = "qtpass", .tags = 1 << 6) | |||||
RULE(.class = "Bitwarden", .tags = 1 << 6) | |||||
RULE(.class = "Mailspring", .tags = 1 << 7) | |||||
RULE(.class = "Thunderbird", .tags = 1 << 7) | |||||
RULE(.class = "st-256color", .tags = 1 << 0, .isfloating=0) | |||||
RULE(.class = "Tor Browser", .tags = 1 << 1) | |||||
RULE(.class = "Chromium", .tags = 1 << 1) | |||||
RULE(.class = "TelegramDesktop", .tags = 1 << 8) | |||||
RULE(.class = "whatsapp-nativefier-d52542", .tags = 1 << 8) | |||||
RULE(.class = "Sublime_Text", .tags = 1 << 2) | |||||
RULE(.class = "code-oss", .tags = 1 << 2) | |||||
RULE(.class = "jetbrains-idea", .tags = 1 << 2) | |||||
RULE(.class = "Nemo", .isfloating = 1, .floatpos="50% 50% 1200W 800H") | |||||
RULE(.class = "Spotify", .tags = 1 << 9) | |||||
RULE(.instance = "spterm", .tags = SPTAG(0), .isfloating = 1) | |||||
RULE(.class = "spfeh", .tags = SPTAG(1), .isfloating = 1) | |||||
RULE(.instance = "spmutt", .tags = SPTAG(2), .isfloating = 1) | |||||
RULE(.instance = "spfile", .tags = SPTAG(3), .isfloating = 1) | |||||
RULE(.instance = "spmusic", .tags = SPTAG(4), .isfloating = 1) | |||||
RULE(.instance = "spcal", .tags = SPTAG(5), .isfloating = 1) | |||||
/* Terminal Window Rules */ | |||||
RULE(.class = "ranger", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H") | |||||
RULE(.class = "lf", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H") | |||||
RULE(.class = "vim", 0, .isfloating = 1, .floatpos="50% 50% 1000W 700H") | |||||
RULE(.class = "stpulse", 0, .isfloating = 1, .floatpos="50% 50% 800W 560H") | |||||
RULE(.class = "mpv", 0, .isfloating = 1, .floatpos="100% 1% 600W 350H") | |||||
RULE(.instance = "sxiv", 0, .isfloating = 1, .floatpos="100% 1% 600W 350H") | |||||
RULE(.class = "neomutt-send", 0, .isfloating = 1, .floatpos="50% 50% 1000W 700H") | |||||
//RULE(.class = "Zathura", 0, .isfloating = 1, .floatpos="100% 50% 700W 1000H") | |||||
//RULE(.class = "Surf", 0, .isfloating = 1, .floatpos="100% 100% 800W 1200H") | |||||
RULE(.class = "weather", 0, .isfloating = 1, .floatpos="50% 50% 1200W 800H") | |||||
RULE(.class = "center", 0, .isfloating = 1, .floatpos="50% 50% 1000W 600H") | |||||
RULE(.class = "htop", 0, .isfloating = 1, .floatpos="50% 50% 1200W 600H") | |||||
RULE(.title = "SimCrop", 0, .isfloating = 1, .floatpos="50% 50% 800W 500H") | |||||
}; |
@ -0,0 +1,58 @@ | |||||
# Prerequisites | |||||
*.d | |||||
# Object files | |||||
*.o | |||||
*.ko | |||||
*.obj | |||||
*.elf | |||||
# Linker output | |||||
*.ilk | |||||
*.map | |||||
*.exp | |||||
# Precompiled Headers | |||||
*.gch | |||||
*.pch | |||||
# Libraries | |||||
*.lib | |||||
*.a | |||||
*.la | |||||
*.lo | |||||
# Shared objects (inc. Windows DLLs) | |||||
*.dll | |||||
*.so | |||||
*.so.* | |||||
*.dylib | |||||
# Executables | |||||
*.exe | |||||
*.out | |||||
*.app | |||||
*.i*86 | |||||
*.x86_64 | |||||
*.hex | |||||
# Debug files | |||||
*.dSYM/ | |||||
*.su | |||||
*.idb | |||||
*.pdb | |||||
# Kernel Module Compile Results | |||||
*.mod* | |||||
*.cmd | |||||
.tmp_versions/ | |||||
modules.order | |||||
Module.symvers | |||||
Mkfile.old | |||||
dkms.conf | |||||
dwm | |||||
dwm-msg | |||||
*.orig | |||||
*.rej |
@ -0,0 +1,33 @@ | |||||
/* See LICENSE file for copyright and license details. */ | |||||
#include <X11/XF86keysym.h> | |||||
/* appearance */ | |||||
static const int rmaster = 0; /* 1 = master at right*/ | |||||
static const unsigned int systraypinning = 0; /* 0: sloppy systray follows selected monitor, >0: pin systray to monitor X */ | |||||
static const unsigned int systrayspacing = 2; /* systray spacing */ | |||||
static const int systraypinningfailfirst = 1; /* 1: if pinning fails, display systray on the first monitor, False: display systray on the last monitor*/ | |||||
static const int showsystray = 1; /* 0 means no systray */ | |||||
static const int tag_padding = 0; | |||||
static const int vertpad = 0; /* vertical padding of bar */ | |||||
static const int sidepad = 0; /* horizontal padding of bar */ | |||||
/* tagging */ | |||||
static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"}; | |||||
//static const char *alttags[] = { "", "", "", ""}; | |||||
/* layout(s) */ | |||||
static const float mfact = 0.5; /* factor of master area size [0.05..0.95] */ | |||||
static const int nmaster = 1; /* number of clients in master area */ | |||||
static const int resizehints = 0; /* 1 means respect size hints in tiled resizals */ | |||||
static const Layout layouts[] = { | |||||
/* symbol arrange function */ | |||||
{ "鉶", tile }, /* first entry is default */ | |||||
/* { "", dwindle }, */ | |||||
{ "ﱖ", grid }, | |||||
{ "", centeredmaster }, | |||||
{ "", centeredfloatingmaster }, | |||||
{ "[M]", monocle }, | |||||
{ "[D]", deck }, | |||||
{ NULL, NULL }, | |||||
}; |
@ -0,0 +1,24 @@ | |||||
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); | |||||
} |
@ -0,0 +1 @@ | |||||
static void aspectresize(const Arg *arg); |
@ -0,0 +1,42 @@ | |||||
void | |||||
attachx(Client *c) | |||||
{ | |||||
#if ATTACHABOVE_PATCH | |||||
Client *at; | |||||
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 | |||||
Client *at; | |||||
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 | |||||
Client *at; | |||||
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) | |||||
} |
@ -0,0 +1 @@ | |||||
static void attachx(Client *c); |
@ -1 +1 @@ | |||||
static void runautostart(void); | |||||
static void runautostart(void); |
@ -0,0 +1,42 @@ | |||||
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); | |||||
} | |||||
} |
@ -0,0 +1,3 @@ | |||||
#define OPAQUE 0xffU | |||||
static void xinitvisual(); |
@ -0,0 +1,6 @@ | |||||
void | |||||
togglealttag() | |||||
{ | |||||
selmon->alttag = !selmon->alttag; | |||||
drawbar(selmon); | |||||
} |
@ -0,0 +1 @@ | |||||
static void togglealttag(); |
@ -0,0 +1,82 @@ | |||||
void | |||||
managealtbar(Window win, XWindowAttributes *wa) | |||||
{ | |||||
Monitor *m; | |||||
Bar *bar; | |||||
int i; | |||||
if (!(m = recttomon(wa->x, wa->y, wa->width, wa->height))) | |||||
return; | |||||
for (i = 0, bar = m->bar; bar && bar->win && bar->next; bar = bar->next, ++i); // find last bar | |||||
if (!bar) { | |||||
bar = m->bar = ecalloc(1, sizeof(Bar)); | |||||
bar->topbar = topbar; | |||||
} else if (bar && bar->win) { | |||||
bar->next = ecalloc(1, sizeof(Bar)); | |||||
bar->next->topbar = !bar->topbar; | |||||
bar = bar->next; | |||||
} | |||||
bar->external = 1; | |||||
bar->showbar = 1; | |||||
bar->mon = m; | |||||
bar->idx = i; | |||||
bar->borderpx = 0; | |||||
bar->win = win; | |||||
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, wa->width, 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; | |||||
if (!m) | |||||
return; | |||||
for (bar = m->bar; bar && bar->win; bar = bar->next) | |||||
if (bar->win == w) { | |||||
bar->win = 0; | |||||
bar->by = 0; | |||||
bar->bh = 0; | |||||
break; | |||||
} | |||||
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; | |||||
} |
@ -0,0 +1,4 @@ | |||||
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); |
@ -0,0 +1,79 @@ | |||||
int | |||||
width_awesomebar(Bar *bar, BarArg *a) | |||||
{ | |||||
return a->w; | |||||
} | |||||
int | |||||
draw_awesomebar(Bar *bar, BarArg *a) | |||||
{ | |||||
int n = 0, scm, remainder = 0, tabw, pad; | |||||
unsigned int i; | |||||
#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) | |||||
scm = SchemeTitleSel; | |||||
else if (HIDDEN(c)) | |||||
scm = SchemeHid; | |||||
else | |||||
scm = SchemeTitleNorm; | |||||
pad = lrpad / 2; | |||||
#if BAR_CENTEREDWINDOWNAME_PATCH | |||||
if (TEXTW(c->name) < tabw) | |||||
pad = (tabw - TEXTW(c->name) + lrpad) / 2; | |||||
#endif // BAR_CENTEREDWINDOWNAME_PATCH | |||||
drw_setscheme(drw, scheme[scm]); | |||||
drw_text(drw, x, a->y, tabw + (i < remainder ? 1 : 0), a->h, pad, 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; | |||||
} |
@ -0,0 +1,3 @@ | |||||
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); |
@ -1,2 +1,2 @@ | |||||
static int getdwmblockspid(); | static int getdwmblockspid(); | ||||
static void sigdwmblocks(const Arg *arg); | |||||
static void sigdwmblocks(const Arg *arg); |
@ -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); | |||||
} |
@ -0,0 +1,6 @@ | |||||
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); |
@ -0,0 +1,70 @@ | |||||
int | |||||
width_fancybar(Bar *bar, BarArg *a) | |||||
{ | |||||
return a->w; | |||||
} | |||||
int | |||||
draw_fancybar(Bar *bar, BarArg *a) | |||||
{ | |||||
int ftw, mw, ew = 0, n = 0; | |||||
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) { | |||||
ftw = TEXTW(m->sel->name); | |||||
mw = (ftw >= w || n == 1) ? 0 : (w - ftw) / (n - 1); | |||||
i = 0; | |||||
for (c = m->clients; c; c = c->next) { | |||||
if (!ISVISIBLE(c) || c == m->sel) | |||||
continue; | |||||
ftw = TEXTW(c->name); | |||||
if (ftw < mw) | |||||
ew += (mw - ftw); | |||||
else | |||||
i++; | |||||
} | |||||
if (i > 0) | |||||
mw += ew / i; | |||||
for (c = m->clients; c; c = c->next) { | |||||
if (!ISVISIBLE(c)) | |||||
continue; | |||||
ftw = MIN(m->sel == c ? w : mw, TEXTW(c->name)); | |||||
drw_setscheme(drw, scheme[m->sel == c ? SchemeTitleSel : SchemeTitleNorm]); | |||||
if (ftw > 0) /* trap special handling of 0 in drw_text */ | |||||
drw_text(drw, x, a->y, ftw, a->h, lrpad / 2, c->name, 0, False); | |||||
drawstateindicator(c->mon, c, 1, x, a->y, ftw, a->h, 0, 0, c->isfixed); | |||||
x += ftw; | |||||
w -= ftw; | |||||
} | |||||
} | |||||
return n; | |||||
} | |||||
int | |||||
click_fancybar(Bar *bar, Arg *arg, BarArg *a) | |||||
{ | |||||
return ClkWinTitle; | |||||
} | |||||
@ -0,0 +1,3 @@ | |||||
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); |
@ -0,0 +1,436 @@ | |||||
/* 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 == ¢eredmaster) | |||||
return (activegroup ? SchemeFlexActTTB : SchemeFlexInaTTB); | |||||
#endif // CENTEREDMASTER_LAYOUT | |||||
#if CENTEREDFLOATINGMASTER_LAYOUT | |||||
if (m->lt[m->sellt]->arrange == ¢eredfloatingmaster) | |||||
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 SchemeHid; | |||||
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 *barg) | |||||
{ | |||||
if (!c) | |||||
return; | |||||
int i, nclienttags = 0, nviewtags = 0, pad = lrpad / 2; | |||||
int clientscheme = ( | |||||
c == selmon->sel | |||||
? getselschemefor(tabscheme) | |||||
: HIDDEN(c) | |||||
? SchemeHid | |||||
: c->isurgent | |||||
? SchemeUrg | |||||
: tabscheme | |||||
); | |||||
drw_setscheme(drw, scheme[clientscheme]); | |||||
XSetWindowBorder(dpy, c->win, scheme[clientscheme][ColBorder].pixel); | |||||
if (w <= TEXTW("A") - lrpad + pad) // reduce text padding if wintitle is too small | |||||
pad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2); | |||||
#if BAR_CENTEREDWINDOWNAME_PATCH | |||||
else if (TEXTW(c->name) < w) | |||||
pad = (w - TEXTW(c->name) + lrpad) / 2; | |||||
#endif // BAR_CENTEREDWINDOWNAME_PATCH | |||||
drw_text(drw, x, barg->y, w, barg->h, pad, c->name, 0, False); | |||||
drawstateindicator(m, c, 1, x + 2, barg->y, w, barg->h, 0, 0, 0); | |||||
if (FLEXWINTITLE_BORDERS) { | |||||
XSetForeground(drw->dpy, drw->gc, scheme[SchemeSel][ColBorder].pixel); | |||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, barg->y, 1, barg->h); | |||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= barg->w ? 1 : 0), barg->y, 1, barg->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, barg->y, w, barg->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 == ¢eredmaster && (fixed || n - m->nmaster > 1)) | |||||
center = 1; | |||||
#endif // CENTEREDMASTER_LAYOUT | |||||
#if CENTEREDFLOATINGMASTER_LAYOUT | |||||
else if (m->lt[m->sellt]->arrange == ¢eredfloatingmaster) | |||||
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; | |||||
} |
@ -0,0 +1,10 @@ | |||||
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); |
@ -0,0 +1,37 @@ | |||||
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); | |||||
} | |||||
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); | |||||
arrange(selmon); | |||||
} | |||||
#if COMBO_PATCH | |||||
combo = 0; | |||||
#endif // COMBO_PATCH | |||||
} |
@ -0,0 +1,2 @@ | |||||
static void keyrelease(XEvent *e); | |||||
static void holdbar(const Arg *arg); |
@ -0,0 +1,121 @@ | |||||
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; | |||||
} |
@ -0,0 +1,11 @@ | |||||
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); |
@ -0,0 +1,106 @@ | |||||
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; | |||||
} |
@ -0,0 +1,3 @@ | |||||
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); |
@ -1,3 +1,9 @@ | |||||
static int width_status(Bar *bar, BarArg *a); | 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); | static int draw_status(Bar *bar, BarArg *a); | ||||
static int click_status(Bar *bar, Arg *arg, 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); |
@ -1,4 +1,13 @@ | |||||
static int width_status2d(Bar *bar, BarArg *a); | 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); | 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 drawstatusbar(BarArg *a, char *text); | ||||
static int status2dtextlength(char *stext); | |||||
static int status2dtextlength(char *stext); |
@ -0,0 +1,17 @@ | |||||
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; | |||||
} |
@ -0,0 +1,3 @@ | |||||
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); |
@ -1,3 +1,6 @@ | |||||
static int click_statuscmd(Bar *bar, Arg *arg, BarArg *a); | 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 int click_statuscmd_text(Arg *arg, int rel_x, char *text); | ||||
static void copyvalidchars(char *text, char *rawtext); | |||||
static void copyvalidchars(char *text, char *rawtext); |
@ -0,0 +1,23 @@ | |||||
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; | |||||
} |
@ -0,0 +1,220 @@ | |||||
/* 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 *barg) | |||||
{ | |||||
if (!c) | |||||
return; | |||||
int i, nclienttags = 0, nviewtags = 0, pad = lrpad / 2; | |||||
drw_setscheme(drw, scheme[ | |||||
m->sel == c | |||||
? SchemeSel | |||||
#ifdef HIDDEN | |||||
: HIDDEN(c) | |||||
? SchemeHid | |||||
#endif | |||||
: groupactive | |||||
? SchemeTitleSel | |||||
: SchemeTitleNorm | |||||
]); | |||||
if (w <= TEXTW("A") - lrpad + pad) // reduce text padding if wintitle is too small | |||||
pad = (w - TEXTW("A") + lrpad < 0 ? 0 : (w - TEXTW("A") + lrpad) / 2); | |||||
#if BAR_CENTEREDWINDOWNAME_PATCH | |||||
else if (TEXTW(c->name) < w) | |||||
pad = (w - TEXTW(c->name) + lrpad) / 2; | |||||
#endif // BAR_CENTEREDWINDOWNAME_PATCH | |||||
drw_text(drw, x, barg->y, w, barg->h, pad, c->name, 0, False); | |||||
drawstateindicator(m, c, 1, x, barg->y, w, barg->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, barg->y, 1, barg->h); | |||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x + w - (x + w >= barg->w ? 1 : 0), barg->y, 1, barg->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, barg->y, w, barg->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; | |||||
} |
@ -0,0 +1,7 @@ | |||||
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); |
@ -0,0 +1,149 @@ | |||||
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); | |||||
} | |||||
} |
@ -0,0 +1,4 @@ | |||||
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); |
@ -1,8 +1,20 @@ | |||||
char * | char * | ||||
tagicon(Monitor *m, int tag) | tagicon(Monitor *m, int tag) | ||||
{ | { | ||||
#if BAR_ALTTAGSDECORATION_PATCH | |||||
Client *c; | |||||
#endif // BAR_ALTTAGSDECORATION_PATCH | |||||
int tagindex = tag + NUMTAGS * m->index; | int tagindex = tag + NUMTAGS * m->index; | ||||
if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) | if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) | ||||
tagindex = 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]; | return tagicons[DEFAULT_TAGS][tagindex]; | ||||
} | |||||
} |
@ -1,3 +1,3 @@ | |||||
static int width_tags(Bar *bar, BarArg *a); | static int width_tags(Bar *bar, BarArg *a); | ||||
static int draw_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 click_tags(Bar *bar, Arg *arg, BarArg *a); |
@ -0,0 +1,68 @@ | |||||
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; | |||||
} |
@ -0,0 +1,2 @@ | |||||
static void get_vt_colors(void); | |||||
static int get_luminance(char *rgb); |
@ -0,0 +1,51 @@ | |||||
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; | |||||
int pad = lrpad / 2; | |||||
if (!m->sel) { | |||||
drw_setscheme(drw, scheme[SchemeTitleNorm]); | |||||
drw_rect(drw, x, a->y, w, a->h, 1, 1); | |||||
return 0; | |||||
} | |||||
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 BAR_CENTEREDWINDOWNAME_PATCH | |||||
if (TEXTW(m->sel->name) < w) | |||||
pad = (w - TEXTW(m->sel->name) + lrpad) / 2; | |||||
#endif // BAR_CENTEREDWINDOWNAME_PATCH | |||||
drw_text(drw, x, a->y, w, a->h, pad, m->sel->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, m->sel, 1, x, a->y, w, a->h, 0, 0, m->sel->isfixed); | |||||
return 1; | |||||
} | |||||
int | |||||
click_wintitle(Bar *bar, Arg *arg, BarArg *a) | |||||
{ | |||||
return ClkWinTitle; | |||||
} | |||||
@ -0,0 +1,3 @@ | |||||
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); |
@ -0,0 +1,45 @@ | |||||
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; | |||||
} |
@ -0,0 +1,8 @@ | |||||
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 | |||||
); |
@ -0,0 +1,45 @@ | |||||
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; | |||||
} |
@ -0,0 +1,8 @@ | |||||
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 | |||||
); |
@ -0,0 +1,93 @@ | |||||
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); | |||||
} | |||||
} |
@ -0,0 +1,5 @@ | |||||
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); |
@ -0,0 +1,23 @@ | |||||
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); | |||||
} |
@ -0,0 +1 @@ | |||||
static void setcfact(const Arg *arg); |
@ -0,0 +1,5 @@ | |||||
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"; | |||||
} |
@ -0,0 +1 @@ | |||||
static char* help(); |
@ -1,3 +1,5 @@ | |||||
#if !BAR_HOLDBAR_PATCH | |||||
static void keyrelease(XEvent *e); | static void keyrelease(XEvent *e); | ||||
#endif // !BAR_HOLDBAR_PATCH | |||||
static void combotag(const Arg *arg); | static void combotag(const Arg *arg); | ||||
static void comboview(const Arg *arg); | |||||
static void comboview(const Arg *arg); |
@ -0,0 +1,28 @@ | |||||
/* dwm will keep pid's of processes from autostart array and kill them at quit */ | |||||
static pid_t *autostart_pids; | |||||
static size_t autostart_len; | |||||
/* execute command from autostart array */ | |||||
static void | |||||
autostart_exec() | |||||
{ | |||||
const char *const *p; | |||||
size_t i = 0; | |||||
/* count entries */ | |||||
for (p = autostart; *p; autostart_len++, p++) | |||||
while (*++p); | |||||
autostart_pids = malloc(autostart_len * sizeof(pid_t)); | |||||
for (p = autostart; *p; i++, p++) { | |||||
if ((autostart_pids[i] = fork()) == 0) { | |||||
setsid(); | |||||
execvp(*p, (char *const *)p); | |||||
fprintf(stderr, "dwm: execvp %s\n", *p); | |||||
perror(" failed"); | |||||
_exit(EXIT_FAILURE); | |||||
} | |||||
/* skip arguments */ | |||||
while (*++p); | |||||
} | |||||
} |
@ -0,0 +1 @@ | |||||
static void autostart_exec(void); |
@ -1 +1 @@ | |||||
static void cyclelayout(const Arg *arg); | |||||
static void cyclelayout(const Arg *arg); |
@ -0,0 +1,38 @@ | |||||
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); | |||||
} | |||||
} |
@ -0,0 +1,8 @@ | |||||
#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); |
@ -0,0 +1,82 @@ | |||||
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)); | |||||
} |
@ -0,0 +1 @@ | |||||
static void dragcfact(const Arg *arg); |
@ -0,0 +1,231 @@ | |||||
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 == ¢eredmaster && (fixed || n - m->nmaster > 1)) | |||||
center = 1; | |||||
#endif // CENTEREDMASTER_LAYOUT | |||||
#if CENTEREDFLOATINGMASTER_LAYOUT | |||||
else if (m->lt[m->sellt]->arrange == ¢eredfloatingmaster) | |||||
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)); | |||||
} |
@ -0,0 +1 @@ | |||||
static void dragmfact(const Arg *arg); |
@ -0,0 +1,129 @@ | |||||
#!/usr/bin/env bash | |||||
signal() { | |||||
xsetroot -name "fsignal:$*" | |||||
} | |||||
case $# in | |||||
1) | |||||
case $1 in | |||||
focusurgent) ;& | |||||
mirrorlayout) ;& | |||||
mpdcontrol) ;& | |||||
pushdown) ;& | |||||
pushup) ;& | |||||
self_restart) ;& | |||||
setlayout) ;& | |||||
setcfact) ;& | |||||
switchcol) ;& | |||||
view) ;& | |||||
viewall) ;& | |||||
viewtoleft) ;& | |||||
viewtoright) ;& | |||||
tagtoleft) ;& | |||||
tagtoright) ;& | |||||
tagandviewtoleft) ;& | |||||
tagandviewtoright) ;& | |||||
transfer) ;& | |||||
transferall) ;& | |||||
togglealttag) ;& | |||||
togglebar) ;& | |||||
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 | |||||
;; | |||||
*) | |||||
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 |
@ -0,0 +1,100 @@ | |||||
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 | |||||
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 | |||||
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 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; | |||||
} |
@ -0,0 +1,13 @@ | |||||
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); |
@ -0,0 +1,195 @@ | |||||
#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); | |||||
} |
@ -0,0 +1,8 @@ | |||||
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); |
@ -0,0 +1,18 @@ | |||||
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); | |||||
} | |||||
} |
@ -0,0 +1 @@ | |||||
static void togglefakefullscreen(const Arg *arg); |
@ -1,3 +1,3 @@ | |||||
static void floatpos(const Arg *arg); | static void floatpos(const Arg *arg); | ||||
static void setfloatpos(Client *c, const char *floatpos); | static void setfloatpos(Client *c, const char *floatpos); | ||||
static 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); | |||||
static 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); |
@ -0,0 +1,73 @@ | |||||
void | |||||
tagtoleft(const Arg *arg) | |||||
{ | |||||
if (selmon->sel != NULL | |||||
&& __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] > 1) { | |||||
selmon->sel->tags >>= 1; | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
} | |||||
void | |||||
tagtoright(const Arg *arg) | |||||
{ | |||||
if (selmon->sel != NULL | |||||
&& __builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { | |||||
selmon->sel->tags <<= 1; | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
} | |||||
void | |||||
viewtoleft(const Arg *arg) | |||||
{ | |||||
if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] > 1) { | |||||
selmon->seltags ^= 1; /* toggle sel tagset */ | |||||
selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] >> 1; | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
} | |||||
void | |||||
viewtoright(const Arg *arg) | |||||
{ | |||||
if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { | |||||
selmon->seltags ^= 1; /* toggle sel tagset */ | |||||
selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] << 1; | |||||
focus(NULL); | |||||
arrange(selmon); | |||||
} | |||||
} | |||||
void | |||||
tagandviewtoleft(const Arg *arg) | |||||
{ | |||||
if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] > 1) { | |||||
selmon->sel->tags >>= 1; | |||||
selmon->seltags ^= 1; /* toggle sel tagset */ | |||||
selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] >> 1; | |||||
focus(selmon->sel); | |||||
arrange(selmon); | |||||
} | |||||
} | |||||
void | |||||
tagandviewtoright(const Arg *arg) | |||||
{ | |||||
if (__builtin_popcount(selmon->tagset[selmon->seltags] & TAGMASK) == 1 | |||||
&& selmon->tagset[selmon->seltags] & (TAGMASK >> 1)) { | |||||
selmon->sel->tags <<= 1; | |||||
selmon->seltags ^= 1; /* toggle sel tagset */ | |||||
selmon->tagset[selmon->seltags] = selmon->tagset[selmon->seltags ^ 1] << 1; | |||||
focus(selmon->sel); | |||||
arrange(selmon); | |||||
} | |||||
} |
@ -0,0 +1,6 @@ | |||||
static void tagtoleft(const Arg *arg); | |||||
static void tagtoright(const Arg *arg); | |||||
static void viewtoleft(const Arg *arg); | |||||
static void viewtoright(const Arg *arg); | |||||
static void tagandviewtoleft(const Arg *arg); | |||||
static void tagandviewtoright(const Arg *arg); |
@ -0,0 +1,65 @@ | |||||
void | |||||
focusdir(const Arg *arg) | |||||
{ | |||||
Client *s = selmon->sel, *f = NULL, *c, *next; | |||||
if (!s) | |||||
return; | |||||
unsigned int score = -1; | |||||
unsigned int client_score; | |||||
int dist; | |||||
int dirweight = 20; | |||||
int isfloating = s->isfloating; | |||||
next = s->next; | |||||
if (!next) | |||||
next = s->mon->clients; | |||||
for (c = next; c != s; c = next) { | |||||
next = c->next; | |||||
if (!next) | |||||
next = s->mon->clients; | |||||
if (!ISVISIBLE(c) || c->isfloating != isfloating) // || HIDDEN(c) | |||||
continue; | |||||
switch (arg->i) { | |||||
case 0: // left | |||||
dist = s->x - c->x - c->w; | |||||
client_score = | |||||
dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + | |||||
abs(s->y - c->y); | |||||
break; | |||||
case 1: // right | |||||
dist = c->x - s->x - s->w; | |||||
client_score = | |||||
dirweight * MIN(abs(dist), abs(dist + s->mon->ww)) + | |||||
abs(c->y - s->y); | |||||
break; | |||||
case 2: // up | |||||
dist = s->y - c->y - c->h; | |||||
client_score = | |||||
dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + | |||||
abs(s->x - c->x); | |||||
break; | |||||
default: | |||||
case 3: // down | |||||
dist = c->y - s->y - s->h; | |||||
client_score = | |||||
dirweight * MIN(abs(dist), abs(dist + s->mon->wh)) + | |||||
abs(c->x - s->x); | |||||
break; | |||||
} | |||||
if (((arg->i == 0 || arg->i == 2) && client_score <= score) || client_score < score) { | |||||
score = client_score; | |||||
f = c; | |||||
} | |||||
} | |||||
if (f && f != s) { | |||||
focus(f); | |||||
restack(f->mon); | |||||
} | |||||
} |
@ -0,0 +1 @@ | |||||
static void focusdir(const Arg *arg); |
@ -0,0 +1,13 @@ | |||||
void | |||||
focusmaster(const Arg *arg) | |||||
{ | |||||
Client *c; | |||||
if (selmon->nmaster < 1) | |||||
return; | |||||
c = nexttiled(selmon->clients); | |||||
if (c) | |||||
focus(c); | |||||
} |