Compare commits

...

10 Commits

Author SHA1 Message Date
iokanto
fd6db40464 Fix and improve BAR_WINTITLEACTIONS_PATCH (#442)
Introduced an unhideall function that can be used to reveal all hidden client in the current view.

Added a change to unmanage to avoid changing the window state from IconicState to WithdrawnState when the window manager stops managing windows (which happens when restarting).

Previously a hidden window would disappear when restarting dwm because:
   - when hidden the window would be unmapped and having the window state of IconicState
   - when restarting the window would remain unmapped while the window state would become WithdrawnState
   - which would prevent the window from being picked up by the scan function when the window manager starts
2025-03-02 18:28:13 +01:00
bakkeby
25134d69a9 Adding the xresources patch 2025-02-25 09:34:05 +01:00
bakkeby
8a3da062d7 Adding the borderrule patch 2024-10-30 21:48:29 +01:00
bakkeby
281977c542 Avoid unsigned integer underflow in drw_text()
ref.
https://git.suckless.org/dwm/commit/cfb8627a80a334f200f68c2c8f3e384313ebbaf5.html
2024-10-30 21:06:16 +01:00
bakkeby
38950399fe util.c: output function might override errno and thus affect perror()
Original patch by Raymond Cole with some modifications, thanks!

ref.
https://git.suckless.org/dwm/commit/fcb2476b693ca4c40ad32c7119e27bbeb856865c.html
2024-10-29 22:21:11 +01:00
bakkeby
8ae6f04654 sync drw.{c,h} from dmenu
- drw: minor improvement to the nomatches cache
- overhaul utf8decoding and render invalid utf8 sequences as U+FFFD.

Thanks NRK for these improvements!

ref.
https://git.suckless.org/dwm/commit/8933ebcf50024f4378a78e556b1ac08091197206.html#h0-1
2024-10-29 22:15:32 +01:00
bakkeby
36cbcf53a2 IPC: do not bail on events from unknown file descriptors ref. #433
The natural cycle for dwm-msg is that:
   - the client registers
   - the client sends a message
   - a response is sent back
   - the client deregisters

There is a race condition such that a new client may end up with the same
file descriptor as another command that is deregistering, resulting in a
message to come through from a file descriptor that is not registered.

The handling of this situation is that the IPC patch will log:

   Got event from unknown fd 7, ptr 0x7, u32 7, u64 7 with events 17

before gracefully stopping (exiting) dwm.

The consequence of the error itself seems benign and the proposal here is
to allow dwm to keep running despite not being able to process the dwm-msg
command successfully.
2024-08-01 14:56:48 +02:00
bakkeby
f4258747be Swallow + noborder compatibility changes ref. #430 2024-07-14 14:27:11 +02:00
bakkeby
3bc91e187c Removing debug print statement 2024-07-14 14:26:45 +02:00
bakkeby
f67b8be209 status2d: make sure to terminate the copied text with a NULL character 2024-07-12 19:22:24 +02:00
17 changed files with 398 additions and 104 deletions

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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

View File

@@ -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)]);

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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],

View File

@@ -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
View 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
View 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);

View File

@@ -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
View File

@@ -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);
}

1
util.h
View File

@@ -7,6 +7,7 @@
#define MIN(A, B) ((A) < (B) ? (A) : (B))
#endif
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
#define LENGTH(X) (sizeof (X) / sizeof (X)[0])
#ifdef _DEBUG
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)