Compare commits
10 Commits
df75e113a9
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd6db40464 | ||
|
|
25134d69a9 | ||
|
|
8a3da062d7 | ||
|
|
281977c542 | ||
|
|
38950399fe | ||
|
|
8ae6f04654 | ||
|
|
36cbcf53a2 | ||
|
|
f4258747be | ||
|
|
3bc91e187c | ||
|
|
f67b8be209 |
12
README.md
12
README.md
@@ -1,4 +1,4 @@
|
||||
This dwm 6.5 (5687f46, 2024-06-08) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0).
|
||||
This dwm 6.5 (cfb8627, 2024-10-28) side project has a different take on dwm patching. It uses preprocessor directives to decide whether or not to include a patch during build time. Essentially this means that this build, for better or worse, contains both the patched _and_ the original code. The aim being that you can select which patches to include and the build will contain that code and nothing more. Due to the complexity of some of the patches dwm-flexipatch has diverged from mainstream dwm by making some core patches non-optional for maintenance reasons. For the classic dwm-flexipatch build refer to branch [dwm-flexipatch-1.0](https://github.com/bakkeby/dwm-flexipatch/tree/dwm-flexipatch-1.0).
|
||||
|
||||
For example to include the `alpha` patch then you would only need to flip this setting from 0 to 1 in [patches.h](https://github.com/bakkeby/dwm-flexipatch/blob/master/patches.def.h):
|
||||
```c
|
||||
@@ -19,6 +19,10 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
|
||||
|
||||
### Changelog:
|
||||
|
||||
2025-02-25 - Added the xresources patch
|
||||
|
||||
2024-10-30 - Added the border rule patch
|
||||
|
||||
2024-07-11 - Added variant of the launcher patch
|
||||
|
||||
2024-01-31 - Added the placedir patch
|
||||
@@ -314,6 +318,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
|
||||
- [bidi](https://dwm.suckless.org/patches/bidi/)
|
||||
- adds proper support for Right-To-Left (RTL) languages (such as Farsi, Arabic or Hebrew)
|
||||
|
||||
- [borderrule](https://dwm.suckless.org/patches/borderrule/)
|
||||
- adds a client rule option to set border width on a per client basis
|
||||
|
||||
- [center](https://dwm.suckless.org/patches/center/)
|
||||
- adds an iscentered rule to automatically center clients on the current monitor
|
||||
|
||||
@@ -882,6 +889,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6
|
||||
- [xrdb](http://dwm.suckless.org/patches/xrdb/)
|
||||
- allows dwm to read colors from xrdb (.Xresources) during runtime
|
||||
|
||||
- [xresources](https://dwm.suckless.org/patches/xresources/)
|
||||
- allows dwm to read strings, integers and float values from xrdb (.Xresources) during runtime
|
||||
|
||||
- [zoomfloating](https://www.reddit.com/r/suckless/comments/ie5fe3/zoomfloating_my_own_simple_original_patch/)
|
||||
- a simple patch that allows floating windows to be zoomed into the master stack position
|
||||
|
||||
|
||||
115
config.def.h
115
config.def.h
@@ -906,6 +906,108 @@ static const Key on_empty_keys[] = {
|
||||
};
|
||||
#endif // ON_EMPTY_KEYS_PATCH
|
||||
|
||||
#if XRESOURCES_PATCH
|
||||
/*
|
||||
* Xresources preferences to load at startup.
|
||||
*
|
||||
* Name Type Address
|
||||
* ------------------------------------------------
|
||||
* "nmaster" INTEGER &nmaster
|
||||
* "mfact" FLOAT &mfact
|
||||
* "color1" STRING &color1
|
||||
*
|
||||
* In the Xresources file setting resources shoud be prefixed with "dwm.", e.g.
|
||||
*
|
||||
* dwm.nmaster: 1
|
||||
* dwm.mfact: 0.50
|
||||
* dwm.color1: #FA6EFA
|
||||
*
|
||||
* Note that the const qualifier must be removed from the variables if you plan on
|
||||
* overriding them with values from Xresources. While resources can be reloaded
|
||||
* using the xrdb function some changes may only take effect following a restart.
|
||||
*/
|
||||
ResourcePref resources[] = {
|
||||
/* Resource name Type Address */
|
||||
{ "normfgcolor", STRING, &normfgcolor },
|
||||
{ "normbgcolor", STRING, &normbgcolor },
|
||||
{ "normbordercolor", STRING, &normbordercolor },
|
||||
{ "normfloatcolor", STRING, &normfloatcolor },
|
||||
{ "selfgcolor", STRING, &selfgcolor },
|
||||
{ "selbgcolor", STRING, &selbgcolor },
|
||||
{ "selbordercolor", STRING, &selbordercolor },
|
||||
{ "selfloatcolor", STRING, &selfloatcolor },
|
||||
{ "titlenormfgcolor", STRING, &titlenormfgcolor },
|
||||
{ "titlenormbgcolor", STRING, &titlenormbgcolor },
|
||||
{ "titlenormbordercolor", STRING, &titlenormbordercolor },
|
||||
{ "titlenormfloatcolor", STRING, &titlenormfloatcolor },
|
||||
{ "titleselfgcolor", STRING, &titleselfgcolor },
|
||||
{ "titleselbgcolor", STRING, &titleselbgcolor },
|
||||
{ "titleselbordercolor", STRING, &titleselbordercolor },
|
||||
{ "titleselfloatcolor", STRING, &titleselfloatcolor },
|
||||
{ "tagsnormfgcolor", STRING, &tagsnormfgcolor },
|
||||
{ "tagsnormbgcolor", STRING, &tagsnormbgcolor },
|
||||
{ "tagsnormbordercolor", STRING, &tagsnormbordercolor },
|
||||
{ "tagsnormfloatcolor", STRING, &tagsnormfloatcolor },
|
||||
{ "tagsselfgcolor", STRING, &tagsselfgcolor },
|
||||
{ "tagsselbgcolor", STRING, &tagsselbgcolor },
|
||||
{ "tagsselbordercolor", STRING, &tagsselbordercolor },
|
||||
{ "tagsselfloatcolor", STRING, &tagsselfloatcolor },
|
||||
{ "hidnormfgcolor", STRING, &hidnormfgcolor },
|
||||
{ "hidnormbgcolor", STRING, &hidnormbgcolor },
|
||||
{ "hidselfgcolor", STRING, &hidselfgcolor },
|
||||
{ "hidselbgcolor", STRING, &hidselbgcolor },
|
||||
{ "urgfgcolor", STRING, &urgfgcolor },
|
||||
{ "urgbgcolor", STRING, &urgbgcolor },
|
||||
{ "urgbordercolor", STRING, &urgbordercolor },
|
||||
{ "urgfloatcolor", STRING, &urgfloatcolor },
|
||||
#if RENAMED_SCRATCHPADS_PATCH
|
||||
{ "scratchselfgcolor", STRING, &scratchselfgcolor },
|
||||
{ "scratchselbgcolor", STRING, &scratchselbgcolor },
|
||||
{ "scratchselbordercolor", STRING, &scratchselbordercolor },
|
||||
{ "scratchselfloatcolor", STRING, &scratchselfloatcolor },
|
||||
{ "scratchnormfgcolor", STRING, &scratchnormfgcolor },
|
||||
{ "scratchnormbgcolor", STRING, &scratchnormbgcolor },
|
||||
{ "scratchnormbordercolor", STRING, &scratchnormbordercolor },
|
||||
{ "scratchnormfloatcolor", STRING, &scratchnormfloatcolor },
|
||||
#endif // RENAMED_SCRATCHPADS_PATCH
|
||||
#if BAR_FLEXWINTITLE_PATCH
|
||||
{ "normTTBbgcolor", STRING, &normTTBbgcolor },
|
||||
{ "normLTRbgcolor", STRING, &normLTRbgcolor },
|
||||
{ "normMONObgcolor", STRING, &normMONObgcolor },
|
||||
{ "normGRIDbgcolor", STRING, &normGRIDbgcolor },
|
||||
{ "normGRD1bgcolor", STRING, &normGRD1bgcolor },
|
||||
{ "normGRD2bgcolor", STRING, &normGRD2bgcolor },
|
||||
{ "normGRDMbgcolor", STRING, &normGRDMbgcolor },
|
||||
{ "normHGRDbgcolor", STRING, &normHGRDbgcolor },
|
||||
{ "normDWDLbgcolor", STRING, &normDWDLbgcolor },
|
||||
{ "normSPRLbgcolor", STRING, &normSPRLbgcolor },
|
||||
{ "normfloatbgcolor", STRING, &normfloatbgcolor },
|
||||
{ "actTTBbgcolor", STRING, &actTTBbgcolor },
|
||||
{ "actLTRbgcolor", STRING, &actLTRbgcolor },
|
||||
{ "actMONObgcolor", STRING, &actMONObgcolor },
|
||||
{ "actGRIDbgcolor", STRING, &actGRIDbgcolor },
|
||||
{ "actGRD1bgcolor", STRING, &actGRD1bgcolor },
|
||||
{ "actGRD2bgcolor", STRING, &actGRD2bgcolor },
|
||||
{ "actGRDMbgcolor", STRING, &actGRDMbgcolor },
|
||||
{ "actHGRDbgcolor", STRING, &actHGRDbgcolor },
|
||||
{ "actDWDLbgcolor", STRING, &actDWDLbgcolor },
|
||||
{ "actSPRLbgcolor", STRING, &actSPRLbgcolor },
|
||||
{ "actfloatbgcolor", STRING, &actfloatbgcolor },
|
||||
{ "selTTBbgcolor", STRING, &selTTBbgcolor },
|
||||
{ "selLTRbgcolor", STRING, &selLTRbgcolor },
|
||||
{ "selMONObgcolor", STRING, &selMONObgcolor },
|
||||
{ "selGRIDbgcolor", STRING, &selGRIDbgcolor },
|
||||
{ "selGRD1bgcolor", STRING, &selGRD1bgcolor },
|
||||
{ "selGRD2bgcolor", STRING, &selGRD2bgcolor },
|
||||
{ "selGRDMbgcolor", STRING, &selGRDMbgcolor },
|
||||
{ "selHGRDbgcolor", STRING, &selHGRDbgcolor },
|
||||
{ "selDWDLbgcolor", STRING, &selDWDLbgcolor },
|
||||
{ "selSPRLbgcolor", STRING, &selSPRLbgcolor },
|
||||
{ "selfloatbgcolor", STRING, &selfloatbgcolor },
|
||||
#endif // BAR_FLEXWINTITLE_PATCH
|
||||
};
|
||||
#endif // XRESOURCES_PATCH
|
||||
|
||||
static const Key keys[] = {
|
||||
/* modifier key function argument */
|
||||
#if KEYMODES_PATCH
|
||||
@@ -1063,6 +1165,7 @@ static const Key keys[] = {
|
||||
#endif // SHIFTSWAPTAGS_PATCH
|
||||
#if BAR_WINTITLEACTIONS_PATCH
|
||||
{ MODKEY|ControlMask, XK_z, showhideclient, {0} },
|
||||
{ MODKEY|ControlMask, XK_s, unhideall, {0} },
|
||||
#endif // BAR_WINTITLEACTIONS_PATCH
|
||||
{ MODKEY|ShiftMask, XK_c, killclient, {0} },
|
||||
#if KILLUNSEL_PATCH
|
||||
@@ -1084,9 +1187,9 @@ static const Key keys[] = {
|
||||
#if WINVIEW_PATCH
|
||||
{ MODKEY, XK_o, winview, {0} },
|
||||
#endif // WINVIEW_PATCH
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRDB_PATCH || XRESOURCES_PATCH
|
||||
{ MODKEY|ShiftMask, XK_F5, xrdb, {.v = NULL } },
|
||||
#endif // XRDB_PATCH
|
||||
#endif // XRDB_PATCH | XRESOURCES_PATCH
|
||||
{ MODKEY, XK_t, setlayout, {.v = &layouts[0]} },
|
||||
{ MODKEY, XK_f, setlayout, {.v = &layouts[1]} },
|
||||
{ MODKEY, XK_m, setlayout, {.v = &layouts[2]} },
|
||||
@@ -1586,9 +1689,9 @@ static const Signal signals[] = {
|
||||
#if WINVIEW_PATCH
|
||||
{ "winview", winview },
|
||||
#endif // WINVIEW_PATCH
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRDB_PATCH || XRESOURCES_PATCH
|
||||
{ "xrdb", xrdb },
|
||||
#endif // XRDB_PATCH
|
||||
#endif // XRDB_PATCH | XRESOURCES_PATCH
|
||||
#if TAGOTHERMONITOR_PATCH
|
||||
{ "tagnextmonex", tagnextmonex },
|
||||
{ "tagprevmonex", tagprevmonex },
|
||||
@@ -1786,8 +1889,8 @@ static IPCCommand ipccommands[] = {
|
||||
#if WINVIEW_PATCH
|
||||
IPCCOMMAND( winview, 1, {ARG_TYPE_NONE} ),
|
||||
#endif // WINVIEW_PATCH
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRDB_PATCH || XRESOURCES_PATCH
|
||||
IPCCOMMAND( xrdb, 1, {ARG_TYPE_NONE} ),
|
||||
#endif // XRDB_PATCH
|
||||
#endif // XRDB_PATCH | XRESOURCES_PATCH
|
||||
};
|
||||
#endif // IPC_PATCH
|
||||
|
||||
158
drw.c
158
drw.c
@@ -35,12 +35,6 @@ apply_fribidi(const char *str)
|
||||
|
||||
#if !BAR_PANGO_PATCH
|
||||
#define UTF_INVALID 0xFFFD
|
||||
#define UTF_SIZ 4
|
||||
|
||||
static const unsigned char utfbyte[UTF_SIZ + 1] = {0x80, 0, 0xC0, 0xE0, 0xF0};
|
||||
static const unsigned char utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
|
||||
static const long utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
|
||||
static const long utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
|
||||
#endif // BAR_PANGO_PATCH
|
||||
|
||||
#if BAR_POWERLINE_TAGS_PATCH || BAR_POWERLINE_STATUS_PATCH
|
||||
@@ -48,47 +42,39 @@ Clr transcheme[3];
|
||||
#endif // BAR_POWERLINE_TAGS_PATCH | BAR_POWERLINE_STATUS_PATCH
|
||||
|
||||
#if !BAR_PANGO_PATCH
|
||||
static long
|
||||
utf8decodebyte(const char c, size_t *i)
|
||||
static int
|
||||
utf8decode(const char *s_in, long *u, int *err)
|
||||
{
|
||||
for (*i = 0; *i < (UTF_SIZ + 1); ++(*i))
|
||||
if (((unsigned char)c & utfmask[*i]) == utfbyte[*i])
|
||||
return (unsigned char)c & ~utfmask[*i];
|
||||
return 0;
|
||||
}
|
||||
static const unsigned char lens[] = {
|
||||
/* 0XXXX */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
/* 10XXX */ 0, 0, 0, 0, 0, 0, 0, 0, /* invalid */
|
||||
/* 110XX */ 2, 2, 2, 2,
|
||||
/* 1110X */ 3, 3,
|
||||
/* 11110 */ 4,
|
||||
/* 11111 */ 0, /* invalid */
|
||||
};
|
||||
static const unsigned char leading_mask[] = { 0x7F, 0x1F, 0x0F, 0x07 };
|
||||
static const unsigned int overlong[] = { 0x0, 0x80, 0x0800, 0x10000 };
|
||||
|
||||
static size_t
|
||||
utf8validate(long *u, size_t i)
|
||||
{
|
||||
if (!BETWEEN(*u, utfmin[i], utfmax[i]) || BETWEEN(*u, 0xD800, 0xDFFF))
|
||||
const unsigned char *s = (const unsigned char *)s_in;
|
||||
int len = lens[*s >> 3];
|
||||
*u = UTF_INVALID;
|
||||
for (i = 1; *u > utfmax[i]; ++i)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
static size_t
|
||||
utf8decode(const char *c, long *u, size_t clen)
|
||||
{
|
||||
size_t i, j, len, type;
|
||||
long udecoded;
|
||||
|
||||
*u = UTF_INVALID;
|
||||
if (!clen)
|
||||
return 0;
|
||||
udecoded = utf8decodebyte(c[0], &len);
|
||||
if (!BETWEEN(len, 1, UTF_SIZ))
|
||||
*err = 1;
|
||||
if (len == 0)
|
||||
return 1;
|
||||
for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
|
||||
udecoded = (udecoded << 6) | utf8decodebyte(c[i], &type);
|
||||
if (type)
|
||||
return j;
|
||||
}
|
||||
if (j < len)
|
||||
return 0;
|
||||
*u = udecoded;
|
||||
utf8validate(u, len);
|
||||
|
||||
long cp = s[0] & leading_mask[len - 1];
|
||||
for (int i = 1; i < len; ++i) {
|
||||
if (s[i] == '\0' || (s[i] & 0xC0) != 0x80)
|
||||
return i;
|
||||
cp = (cp << 6) | (s[i] & 0x3F);
|
||||
}
|
||||
/* out of range, surrogate, overlong encoding */
|
||||
if (cp > 0x10FFFF || (cp >> 11) == 0x1B || cp < overlong[len - 1])
|
||||
return len;
|
||||
|
||||
*err = 0;
|
||||
*u = cp;
|
||||
return len;
|
||||
}
|
||||
#endif // BAR_PANGO_PATCH
|
||||
@@ -450,6 +436,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
if (w < lpad)
|
||||
return x + w;
|
||||
#if BAR_ALPHA_PATCH
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
#else
|
||||
@@ -500,29 +488,32 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
|
||||
return x + (render ? w : 0);
|
||||
#else
|
||||
char buf[1024];
|
||||
int ty;
|
||||
unsigned int ew;
|
||||
int ty, ellipsis_x = 0;
|
||||
unsigned int tmpw, ew, ellipsis_w = 0, ellipsis_len, hash, h0, h1;
|
||||
XftDraw *d = NULL;
|
||||
Fnt *usedfont, *curfont, *nextfont;
|
||||
size_t i, len;
|
||||
int utf8strlen, utf8charlen, render = x || y || w || h;
|
||||
int utf8strlen, utf8charlen, utf8err, render = x || y || w || h;
|
||||
long utf8codepoint = 0;
|
||||
const char *utf8str;
|
||||
FcCharSet *fccharset;
|
||||
FcPattern *fcpattern;
|
||||
FcPattern *match;
|
||||
XftResult result;
|
||||
int charexists = 0;
|
||||
int charexists = 0, overflow = 0;
|
||||
/* keep track of a couple codepoints for which we have no match. */
|
||||
static unsigned int nomatches[128], ellipsis_width, invalid_width;
|
||||
static const char invalid[] = "<EFBFBD>";
|
||||
|
||||
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
|
||||
if (!drw || (render && (!drw->scheme || !w)) || !text || !drw->fonts)
|
||||
return 0;
|
||||
|
||||
if (!render) {
|
||||
w = ~w;
|
||||
w = invert ? invert : ~invert;
|
||||
} else {
|
||||
XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
|
||||
XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
|
||||
if (w < lpad)
|
||||
return x + w;
|
||||
#if BAR_ALPHA_PATCH
|
||||
d = XftDrawCreate(drw->dpy, drw->drawable, drw->visual, drw->cmap);
|
||||
#else
|
||||
@@ -535,18 +526,40 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
}
|
||||
|
||||
usedfont = drw->fonts;
|
||||
if (!ellipsis_width && render)
|
||||
ellipsis_width = drw_fontset_getwidth(drw, "...", markup);
|
||||
if (!invalid_width && render)
|
||||
invalid_width = drw_fontset_getwidth(drw, invalid, markup);
|
||||
while (1) {
|
||||
utf8strlen = 0;
|
||||
ew = ellipsis_len = utf8err = utf8charlen = utf8strlen = 0;
|
||||
utf8str = text;
|
||||
nextfont = NULL;
|
||||
while (*text) {
|
||||
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
|
||||
utf8charlen = utf8decode(text, &utf8codepoint, &utf8err);
|
||||
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
|
||||
charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
|
||||
if (charexists) {
|
||||
if (curfont == usedfont) {
|
||||
utf8strlen += utf8charlen;
|
||||
drw_font_getexts(curfont, text, utf8charlen, &tmpw, NULL);
|
||||
if (ew + ellipsis_width <= w) {
|
||||
/* keep track where the ellipsis still fits */
|
||||
ellipsis_x = x + ew;
|
||||
ellipsis_w = w - ew;
|
||||
ellipsis_len = utf8strlen;
|
||||
}
|
||||
|
||||
if (ew + tmpw > w) {
|
||||
overflow = 1;
|
||||
/* called from drw_fontset_getwidth_clamp():
|
||||
* it wants the width AFTER the overflow
|
||||
*/
|
||||
if (!render)
|
||||
x += tmpw;
|
||||
else
|
||||
utf8strlen = ellipsis_len;
|
||||
} else if (curfont == usedfont) {
|
||||
text += utf8charlen;
|
||||
utf8strlen += utf8err ? 0 : utf8charlen;
|
||||
ew += utf8err ? 0 : tmpw;
|
||||
} else {
|
||||
nextfont = curfont;
|
||||
}
|
||||
@@ -554,36 +567,31 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
}
|
||||
}
|
||||
|
||||
if (!charexists || nextfont)
|
||||
if (overflow || !charexists || nextfont || utf8err)
|
||||
break;
|
||||
else
|
||||
charexists = 0;
|
||||
}
|
||||
|
||||
if (utf8strlen) {
|
||||
drw_font_getexts(usedfont, utf8str, utf8strlen, &ew, NULL);
|
||||
/* shorten text if necessary */
|
||||
for (len = MIN(utf8strlen, sizeof(buf) - 1); len && ew > w; drw_font_getexts(usedfont, utf8str, len, &ew, NULL))
|
||||
len--;
|
||||
|
||||
if (len) {
|
||||
memcpy(buf, utf8str, len);
|
||||
buf[len] = '\0';
|
||||
if (len < utf8strlen)
|
||||
for (i = len; i && i > len - 3; buf[--i] = '.')
|
||||
; /* NOP */
|
||||
|
||||
if (render) {
|
||||
ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
|
||||
XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
|
||||
usedfont->xfont, x, ty, (XftChar8 *)buf, len);
|
||||
usedfont->xfont, x, ty, (XftChar8 *)utf8str, utf8strlen);
|
||||
}
|
||||
x += ew;
|
||||
w -= ew;
|
||||
}
|
||||
if (utf8err && (!render || invalid_width < w)) {
|
||||
if (render)
|
||||
drw_text(drw, x, y, w, h, 0, invalid, invert, markup);
|
||||
x += invalid_width;
|
||||
w -= invalid_width;
|
||||
}
|
||||
if (render && overflow)
|
||||
drw_text(drw, ellipsis_x, y, ellipsis_w, h, 0, "...", invert, markup);
|
||||
|
||||
if (!*text) {
|
||||
if (!*text || overflow) {
|
||||
break;
|
||||
} else if (nextfont) {
|
||||
charexists = 0;
|
||||
@@ -593,6 +601,15 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
* character must be drawn. */
|
||||
charexists = 1;
|
||||
|
||||
hash = (unsigned int)utf8codepoint;
|
||||
hash = ((hash >> 16) ^ hash) * 0x21F0AAAD;
|
||||
hash = ((hash >> 15) ^ hash) * 0xD35A2D97;
|
||||
h0 = ((hash >> 15) ^ hash) % LENGTH(nomatches);
|
||||
h1 = (hash >> 17) % LENGTH(nomatches);
|
||||
/* avoid expensive XftFontMatch call when we know we won't find a match */
|
||||
if (nomatches[h0] == utf8codepoint || nomatches[h1] == utf8codepoint)
|
||||
goto no_match;
|
||||
|
||||
fccharset = FcCharSetCreate();
|
||||
FcCharSetAddChar(fccharset, utf8codepoint);
|
||||
|
||||
@@ -623,6 +640,8 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
|
||||
curfont->next = usedfont;
|
||||
} else {
|
||||
xfont_free(usedfont);
|
||||
nomatches[nomatches[h0] ? h1 : h0] = utf8codepoint;
|
||||
no_match:
|
||||
usedfont = drw->fonts;
|
||||
}
|
||||
}
|
||||
@@ -754,4 +773,3 @@ drw_cur_free(Drw *drw, Cur *cursor)
|
||||
XFreeCursor(drw->dpy, cursor->cursor);
|
||||
free(cursor);
|
||||
}
|
||||
|
||||
|
||||
23
dwm.c
23
dwm.c
@@ -101,7 +101,6 @@
|
||||
#else
|
||||
#define ISVISIBLE(C) ((C->tags & C->mon->tagset[C->mon->seltags]))
|
||||
#endif // ATTACHASIDE_PATCH
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define MOUSEMASK (BUTTONMASK|PointerMotionMask)
|
||||
#define WIDTH(X) ((X)->w + 2 * (X)->bw)
|
||||
#define HEIGHT(X) ((X)->h + 2 * (X)->bw)
|
||||
@@ -580,10 +579,17 @@ typedef struct {
|
||||
#if XKB_PATCH
|
||||
int xkb_layout;
|
||||
#endif // XKB_PATCH
|
||||
#if BORDER_RULE_PATCH
|
||||
int bw;
|
||||
#endif // BORDER_RULE_PATCH
|
||||
} Rule;
|
||||
|
||||
#if XKB_PATCH
|
||||
#if BORDER_RULE_PATCH && XKB_PATCH
|
||||
#define RULE(...) { .monitor = -1, .xkb_layout = -1, .bw = -1, __VA_ARGS__ },
|
||||
#elif XKB_PATCH
|
||||
#define RULE(...) { .monitor = -1, .xkb_layout = -1, __VA_ARGS__ },
|
||||
#elif BORDER_RULE_PATCH
|
||||
#define RULE(...) { .monitor = -1, .bw = -1, __VA_ARGS__ },
|
||||
#else
|
||||
#define RULE(...) { .monitor = -1, __VA_ARGS__ },
|
||||
#endif // XKB_PATCH
|
||||
@@ -920,6 +926,10 @@ applyrules(Client *c)
|
||||
#if CENTER_PATCH
|
||||
c->iscentered = r->iscentered;
|
||||
#endif // CENTER_PATCH
|
||||
#if BORDER_RULE_PATCH
|
||||
if (r->bw != -1)
|
||||
c->bw = r->bw;
|
||||
#endif // BORDER_RULE_PATCH
|
||||
#if ISPERMANENT_PATCH
|
||||
c->ispermanent = r->ispermanent;
|
||||
#endif // ISPERMANENT_PATCH
|
||||
@@ -3313,7 +3323,6 @@ run(void)
|
||||
event_fd, events[i].data.ptr, events[i].data.u32,
|
||||
events[i].data.u64);
|
||||
fprintf(stderr, " with events %d\n", events[i].events);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4102,7 +4111,6 @@ spawn(const Arg *arg)
|
||||
if (arg->v == dmenucmd)
|
||||
dmenumon[0] = '0' + selmon->num;
|
||||
#endif // NODMENU_PATCH
|
||||
fprintf(stderr, "spawn running cmd:\n");
|
||||
|
||||
#if RIODRAW_PATCH
|
||||
if ((pid = fork()) == 0)
|
||||
@@ -4564,6 +4572,7 @@ unmanage(Client *c, int destroyed)
|
||||
XSelectInput(dpy, c->win, NoEventMask);
|
||||
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc); /* restore border */
|
||||
XUngrabButton(dpy, AnyButton, AnyModifier, c->win);
|
||||
if (!HIDDEN(c))
|
||||
setclientstate(c, WithdrawnState);
|
||||
XSync(dpy, False);
|
||||
XSetErrorHandler(xerror);
|
||||
@@ -5346,10 +5355,10 @@ main(int argc, char *argv[])
|
||||
die("dwm: cannot get xcb connection\n");
|
||||
#endif // SWALLOW_PATCH
|
||||
checkotherwm();
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRESOURCES_PATCH || XRDB_PATCH
|
||||
XrmInitialize();
|
||||
loadxrdb();
|
||||
#endif // XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
load_xresources();
|
||||
#endif // XRESOURCES_PATCH | XRDB_PATCH
|
||||
#if COOL_AUTOSTART_PATCH
|
||||
autostart_exec();
|
||||
#endif // COOL_AUTOSTART_PATCH
|
||||
|
||||
@@ -96,6 +96,7 @@ drawstatusbar(BarArg *a, char* stext)
|
||||
#else
|
||||
memcpy(text, stext, len);
|
||||
#endif // BAR_STATUSCMD_PATCH
|
||||
text[len] = '\0';
|
||||
|
||||
x += lrpad / 2;
|
||||
drw_setscheme(drw, scheme[LENGTH(colors)]);
|
||||
|
||||
@@ -92,3 +92,15 @@ showhideclient(const Arg *arg)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unhideall(const Arg *arg)
|
||||
{
|
||||
Client *c = NULL;
|
||||
for (c = selmon->clients; c; c = c->next) {
|
||||
if (ISVISIBLE(c)) {
|
||||
XMapWindow(dpy, c->win);
|
||||
setclientstate(c, NormalState);
|
||||
}
|
||||
}
|
||||
arrange(selmon);
|
||||
}
|
||||
|
||||
@@ -3,4 +3,5 @@ static void show(Client *c);
|
||||
static void togglewin(const Arg *arg);
|
||||
static Client * prevtiled(Client *c);
|
||||
static void showhideclient(const Arg *arg);
|
||||
static void unhideall(const Arg *arg);
|
||||
|
||||
|
||||
@@ -346,7 +346,9 @@
|
||||
#if XKB_PATCH
|
||||
#include "xkb.c"
|
||||
#endif
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRESOURCES_PATCH
|
||||
#include "xresources.c"
|
||||
#elif XRDB_PATCH
|
||||
#include "xrdb.c"
|
||||
#endif
|
||||
#if DRAGMFACT_PATCH
|
||||
|
||||
@@ -348,7 +348,9 @@
|
||||
#if XKB_PATCH
|
||||
#include "xkb.h"
|
||||
#endif
|
||||
#if XRDB_PATCH && !BAR_VTCOLORS_PATCH
|
||||
#if XRESOURCES_PATCH
|
||||
#include "xresources.h"
|
||||
#elif XRDB_PATCH
|
||||
#include "xrdb.h"
|
||||
#endif
|
||||
/* Layouts */
|
||||
|
||||
@@ -13,6 +13,9 @@ swallow(Client *p, Client *c)
|
||||
{
|
||||
Client *s;
|
||||
XWindowChanges wc;
|
||||
#if NOBORDER_PATCH
|
||||
int border_padding = 0;
|
||||
#endif // NOBORDER_PATCH
|
||||
|
||||
if (c->noswallow > 0 || c->isterminal)
|
||||
return 0;
|
||||
@@ -46,9 +49,21 @@ swallow(Client *p, Client *c)
|
||||
setfloatinghint(s);
|
||||
#endif // BAR_EWMHTAGS_PATCH
|
||||
|
||||
#if NOBORDER_PATCH
|
||||
wc.border_width = p->bw;
|
||||
if (noborder(p)) {
|
||||
wc.border_width = 0;
|
||||
border_padding = p->bw * 2;
|
||||
}
|
||||
|
||||
XConfigureWindow(dpy, p->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, p->win, s->x, s->y, s->w + border_padding, s->h + border_padding);
|
||||
#else
|
||||
wc.border_width = p->bw;
|
||||
XConfigureWindow(dpy, p->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, p->win, s->x, s->y, s->w, s->h);
|
||||
#endif // NOBORDER_PATCH
|
||||
|
||||
#if !BAR_FLEXWINTITLE_PATCH
|
||||
XSetWindowBorder(dpy, p->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
#endif // BAR_FLEXWINTITLE_PATCH
|
||||
@@ -65,6 +80,9 @@ unswallow(Client *c)
|
||||
{
|
||||
XWindowChanges wc;
|
||||
c->win = c->swallowing->win;
|
||||
#if NOBORDER_PATCH
|
||||
int border_padding = 0;
|
||||
#endif // NOBORDER_PATCH
|
||||
|
||||
free(c->swallowing);
|
||||
c->swallowing = NULL;
|
||||
@@ -80,9 +98,20 @@ unswallow(Client *c)
|
||||
arrange(c->mon);
|
||||
XMapWindow(dpy, c->win);
|
||||
|
||||
#if NOBORDER_PATCH
|
||||
wc.border_width = c->bw;
|
||||
if (noborder(c)) {
|
||||
wc.border_width = 0;
|
||||
border_padding = c->bw * 2;
|
||||
}
|
||||
|
||||
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w + border_padding, c->h + border_padding);
|
||||
#else
|
||||
wc.border_width = c->bw;
|
||||
XConfigureWindow(dpy, c->win, CWBorderWidth, &wc);
|
||||
XMoveResizeWindow(dpy, c->win, c->x, c->y, c->w, c->h);
|
||||
#endif // NOBORDER_PATCH
|
||||
#if !BAR_FLEXWINTITLE_PATCH
|
||||
XSetWindowBorder(dpy, c->win, scheme[SchemeNorm][ColBorder].pixel);
|
||||
#endif // BAR_FLEXWINTITLE_PATCH
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
void
|
||||
loadxrdb()
|
||||
load_xresources()
|
||||
{
|
||||
Display *display;
|
||||
char * resm;
|
||||
@@ -123,7 +123,7 @@ loadxrdb()
|
||||
void
|
||||
xrdb(const Arg *arg)
|
||||
{
|
||||
loadxrdb();
|
||||
load_xresources();
|
||||
int i;
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i],
|
||||
|
||||
@@ -16,7 +16,5 @@
|
||||
} \
|
||||
}
|
||||
|
||||
static void loadxrdb(void);
|
||||
static void load_xresources(void);
|
||||
static void xrdb(const Arg *arg);
|
||||
|
||||
|
||||
|
||||
74
patch/xresources.c
Normal file
74
patch/xresources.c
Normal file
@@ -0,0 +1,74 @@
|
||||
void
|
||||
resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst)
|
||||
{
|
||||
char *sdst = NULL;
|
||||
int *idst = NULL;
|
||||
float *fdst = NULL;
|
||||
|
||||
sdst = dst;
|
||||
idst = dst;
|
||||
fdst = dst;
|
||||
|
||||
char fullname[256];
|
||||
char *type;
|
||||
XrmValue ret;
|
||||
|
||||
snprintf(fullname, sizeof(fullname), "%s.%s", "dwm", name);
|
||||
fullname[sizeof(fullname) - 1] = '\0';
|
||||
|
||||
XrmGetResource(db, fullname, "*", &type, &ret);
|
||||
if (!(ret.addr == NULL || strncmp("String", type, 64)))
|
||||
{
|
||||
switch (rtype) {
|
||||
case STRING:
|
||||
strcpy(sdst, ret.addr);
|
||||
break;
|
||||
case INTEGER:
|
||||
*idst = strtoul(ret.addr, NULL, 10);
|
||||
break;
|
||||
case FLOAT:
|
||||
*fdst = strtof(ret.addr, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
load_xresources(void)
|
||||
{
|
||||
Display *display;
|
||||
char *resm;
|
||||
XrmDatabase db;
|
||||
ResourcePref *p;
|
||||
|
||||
display = XOpenDisplay(NULL);
|
||||
resm = XResourceManagerString(display);
|
||||
if (!resm)
|
||||
return;
|
||||
|
||||
db = XrmGetStringDatabase(resm);
|
||||
for (p = resources; p < resources + LENGTH(resources); p++)
|
||||
resource_load(db, p->name, p->type, p->dst);
|
||||
XCloseDisplay(display);
|
||||
}
|
||||
|
||||
void
|
||||
xrdb(const Arg *arg)
|
||||
{
|
||||
int i;
|
||||
load_xresources();
|
||||
for (i = 0; i < LENGTH(colors); i++)
|
||||
scheme[i] = drw_scm_create(drw, colors[i],
|
||||
#if BAR_ALPHA_PATCH
|
||||
alphas[i],
|
||||
#endif // BAR_ALPHA_PATCH
|
||||
ColCount
|
||||
);
|
||||
#if BAR_SYSTRAY_PATCH && !BAR_ALPHA_PATCH
|
||||
if (systray) {
|
||||
XMoveWindow(dpy, systray->win, -32000, -32000);
|
||||
}
|
||||
#endif // BAR_SYSTRAY_PATCH
|
||||
arrange(NULL);
|
||||
focus(NULL);
|
||||
}
|
||||
18
patch/xresources.h
Normal file
18
patch/xresources.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#include <X11/Xresource.h>
|
||||
|
||||
/* Xresources preferences */
|
||||
enum resource_type {
|
||||
STRING = 0,
|
||||
INTEGER = 1,
|
||||
FLOAT = 2
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
enum resource_type type;
|
||||
void *dst;
|
||||
} ResourcePref;
|
||||
|
||||
static void load_xresources(void);
|
||||
static void resource_load(XrmDatabase db, char *name, enum resource_type rtype, void *dst);
|
||||
static void xrdb(const Arg *arg);
|
||||
@@ -516,6 +516,16 @@
|
||||
*/
|
||||
#define BIDI_PATCH 0
|
||||
|
||||
/* This patch adds a client rule option to allow the border width to be specified on a per
|
||||
* client basis.
|
||||
*
|
||||
* Example rule:
|
||||
* RULE(.class = "Gimp", .bw = 0)
|
||||
*
|
||||
* https://dwm.suckless.org/patches/borderrule/
|
||||
*/
|
||||
#define BORDER_RULE_PATCH 0
|
||||
|
||||
/* This patch adds an iscentered rule to automatically center clients on the current monitor.
|
||||
* This patch takes precedence over centeredwindowname, alwayscenter and fancybar patches.
|
||||
* https://dwm.suckless.org/patches/center/
|
||||
@@ -1423,6 +1433,12 @@
|
||||
*/
|
||||
#define XRDB_PATCH 0
|
||||
|
||||
/* This patch allows for integer, float and string settings to be loaded from Xresources.
|
||||
* Xresources takes precedence over xrdb.
|
||||
* https://dwm.suckless.org/patches/xresources/
|
||||
*/
|
||||
#define XRESOURCES_PATCH 0
|
||||
|
||||
/* Simple patch that allows floating windows to be zoomed into the master stack position.
|
||||
* https://www.reddit.com/r/suckless/comments/ie5fe3/zoomfloating_my_own_simple_original_patch/
|
||||
*/
|
||||
|
||||
10
util.c
10
util.c
@@ -1,4 +1,5 @@
|
||||
/* See LICENSE file for copyright and license details. */
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -10,17 +11,16 @@ void
|
||||
die(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int saved_errno;
|
||||
|
||||
saved_errno = errno;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||
fputc(' ', stderr);
|
||||
perror(NULL);
|
||||
} else {
|
||||
if (fmt[0] && fmt[strlen(fmt)-1] == ':')
|
||||
fprintf(stderr, " %s", strerror(saved_errno));
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user