From c438eabdc247b2ac773139e8f7f9c5defd632d11 Mon Sep 17 00:00:00 2001 From: bakkeby Date: Fri, 12 Aug 2022 13:47:25 +0200 Subject: [PATCH 1/2] Adding nametag patch --- README.md | 5 ++++ config.def.h | 32 +++++++++++++++++++++++++- patch/dwmc | 1 + patch/include.c | 3 +++ patch/include.h | 3 +++ patch/nametag.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ patch/nametag.h | 1 + patches.def.h | 26 +++++++++++++++++++++ 8 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 patch/nametag.c create mode 100644 patch/nametag.h diff --git a/README.md b/README.md index 42a3b37..dd98d9f 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 ### Changelog: +2022-08-12 - Added the nametag patch + 2022-08-02 - Added the bidi patch 2022-07-05 - Added the tagpreview patch @@ -528,6 +530,9 @@ Browsing patches? There is a [map of patches](https://coggle.it/diagram/X9IiSSM6 - [movestack](https://dwm.suckless.org/patches/movestack/) - allows you to move clients around in the stack and swap them with the master + - [nametag](https://dwm.suckless.org/patches/nametag/) + - allows the names of tags to be changed during runtime + - [netclientliststacking](https://github.com/bakkeby/patches/wiki/netclientliststacking) - adds support for the \_NET\_CLIENT\_LIST\_STACKING atom, needed by certain applications like the Zoom video conferencing application diff --git a/config.def.h b/config.def.h index 7a71119..a65e08d 100644 --- a/config.def.h +++ b/config.def.h @@ -106,6 +106,22 @@ static const unsigned int ulinevoffset = 0; /* how far above the bottom of t static const int ulineall = 0; /* 1 to show underline on all tags, 0 for just the active ones */ #endif // BAR_UNDERLINETAGS_PATCH +#if NAMETAG_PATCH +#if NAMETAG_PREPEND_PATCH +/* The format in which the tag is written when named. E.g. %d: %.12s will write the tag number + * followed the first 12 characters of the given string. You can also just use "%d: %s" here. */ +#define NAMETAG_FORMAT "%d: %.12s" +#else +#define NAMETAG_FORMAT "%s" +#endif // NAMETAG_PREPEND_PATCH +/* The maximum amount of bytes reserved for each tag text. */ +#define MAX_TAGLEN 16 +/* The command to run (via popen). This can be tailored by adding a prompt, passing other command + * line arguments or providing name options. Optionally you can use other dmenu like alternatives + * like rofi -dmenu. */ +#define NAMETAG_COMMAND "dmenu < /dev/null" +#endif // NAMETAG_PATCH + /* Indicators: see patch/bar_indicators.h for options */ static int tagindicatortype = INDICATOR_TOP_LEFT_SQUARE; static int tiledindicatortype = INDICATOR_NONE; @@ -411,7 +427,12 @@ static Sp scratchpads[] = { * until it an icon matches. Similarly if there are two tag icons then it would alternate between * them. This works seamlessly with alternative tags and alttagsdecoration patches. */ -static char *tagicons[][NUMTAGS] = { +#if NAMETAG_PATCH +static char tagicons[][NUMTAGS][MAX_TAGLEN] = +#else +static char *tagicons[][NUMTAGS] = +#endif // NAMETAG_PATCH +{ [DEFAULT_TAGS] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }, [ALTERNATIVE_TAGS] = { "A", "B", "C", "D", "E", "F", "G", "H", "I" }, [ALT_TAGS_DECORATION] = { "<1>", "<2>", "<3>", "<4>", "<5>", "<6>", "<7>", "<8>", "<9>" }, @@ -1140,6 +1161,9 @@ static Key keys[] = { #if BAR_ALTERNATIVE_TAGS_PATCH { MODKEY, XK_n, togglealttag, {0} }, #endif // BAR_ALTERNATIVE_TAGS_PATCH + #if NAMETAG_PATCH + { MODKEY|ShiftMask, XK_n, nametag, {0} }, + #endif // NAMETAG_PATCH #if BAR_TAGGRID_PATCH { MODKEY|ControlMask, XK_Up, switchtag, { .ui = SWITCHTAG_UP | SWITCHTAG_VIEW } }, { MODKEY|ControlMask, XK_Down, switchtag, { .ui = SWITCHTAG_DOWN | SWITCHTAG_VIEW } }, @@ -1410,6 +1434,9 @@ static Signal signals[] = { #if MOVEPLACE_PATCH { "moveplace", moveplace }, #endif // MOVEPLACE_PATCH + #if NAMETAG_PATCH + { "nametag", nametag }, + #endif // NAMETAG_PATCH #if EXRESIZE_PATCH { "explace", explace }, { "togglehorizontalexpand", togglehorizontalexpand }, @@ -1624,6 +1651,9 @@ static IPCCommand ipccommands[] = { #if MOVERESIZE_PATCH IPCCOMMAND( moveresize, 1, {ARG_TYPE_STR} ), #endif // MOVERESIZE_PATCH + #if NAMETAG_PATCH + IPCCOMMAND( nametag, 1, {ARG_TYPE_NONE} ), + #endif // NAMETAG_PATCH #if RIODRAW_PATCH IPCCOMMAND( rioresize, 1, {ARG_TYPE_NONE} ), #endif // RIODRAW_PATCH diff --git a/patch/dwmc b/patch/dwmc index 9536367..763927c 100755 --- a/patch/dwmc +++ b/patch/dwmc @@ -10,6 +10,7 @@ case $# in focusurgent) ;& mirrorlayout) ;& mpdcontrol) ;& + nametag) ;& pushdown) ;& pushup) ;& self_restart) ;& diff --git a/patch/include.c b/patch/include.c index 33232cf..4263f45 100644 --- a/patch/include.c +++ b/patch/include.c @@ -193,6 +193,9 @@ #if MOVESTACK_PATCH #include "movestack.c" #endif +#if NAMETAG_PATCH +#include "nametag.c" +#endif #if NO_MOD_BUTTONS_PATCH #include "nomodbuttons.c" #endif diff --git a/patch/include.h b/patch/include.h index 2a78292..65e0eda 100644 --- a/patch/include.h +++ b/patch/include.h @@ -192,6 +192,9 @@ #if MOVESTACK_PATCH #include "movestack.h" #endif +#if NAMETAG_PATCH +#include "nametag.h" +#endif #if NO_MOD_BUTTONS_PATCH #include "nomodbuttons.h" #endif diff --git a/patch/nametag.c b/patch/nametag.c new file mode 100644 index 0000000..2b7b038 --- /dev/null +++ b/patch/nametag.c @@ -0,0 +1,61 @@ +void +nametag(const Arg *arg) +{ + char *p, name[MAX_TAGLEN]; + FILE *f; + int i, group; + int tagindex; + Monitor *m = selmon; + #if BAR_ALTTAGSDECORATION_PATCH + Client *c; + int occ = 0; + + for (c = m->clients; c; c = c->next) + occ |= c->tags == 255 ? 0 : c->tags; + #endif // BAR_ALTTAGSDECORATION_PATCH + + errno = 0; // popen(3p) says on failure it "may" set errno + if (!(f = popen(NAMETAG_COMMAND, "r"))) { + fprintf(stderr, "dwm: popen command failed%s%s\n", errno ? ": " : "", errno ? strerror(errno) : ""); + return; + } + + if (!(p = fgets(name, MAX_TAGLEN, f)) && (i = errno) && ferror(f)) + fprintf(stderr, "dwm: fgets failed: %s\n", strerror(i)); + + pclose(f); + + if (!p) + return; + if ((p = strchr(name, '\n'))) + *p = '\0'; + + for (i = 0; i < NUMTAGS; i++) { + if (m->tagset[m->seltags] & (1 << i)) { + + tagindex = i + NUMTAGS * m->num; + if (tagindex >= LENGTH(tagicons[DEFAULT_TAGS])) + tagindex = tagindex % LENGTH(tagicons[DEFAULT_TAGS]); + + #if BAR_ALTTAGSDECORATION_PATCH + if (occ & 1 << i) + group = ALT_TAGS_DECORATION; + else + #endif // BAR_ALTTAGSDECORATION_PATCH + #if BAR_ALTERNATIVE_TAGS_PATCH + if (m->alttag) + group = ALTERNATIVE_TAGS; + else + #endif // BAR_ALTERNATIVE_TAGS_PATCH + group = DEFAULT_TAGS; + + #if NAMETAG_PREPEND_PATCH + if (snprintf(tagicons[group][i], MAX_TAGLEN, NAMETAG_FORMAT, i+1, name) < 0) + fprintf(stderr, "nametag: if statement to avoid -Wformat-truncation= warnings\n"); + #else + snprintf(tagicons[group][i], MAX_TAGLEN, NAMETAG_FORMAT, name); + #endif // NAMETAG_PREPEND_PATCH + } + } + drawbars(); +} diff --git a/patch/nametag.h b/patch/nametag.h new file mode 100644 index 0000000..3e632be --- /dev/null +++ b/patch/nametag.h @@ -0,0 +1 @@ +static void nametag(const Arg *arg); diff --git a/patches.def.h b/patches.def.h index 2338139..158da7b 100644 --- a/patches.def.h +++ b/patches.def.h @@ -782,6 +782,32 @@ */ #define MOVESTACK_PATCH 0 +/* This patch allows you to change the names of tags during runtime. + * + * This is a bespoke version implemented specifically in relation to tagicons, which is integrated + * into dwm-flexipatch. By default it uses dmenu to retrieve the new name, but this can be + * customised via config along with the maximum text length and the format string. + * + * Special behaviour: + * - if more than one tag is selected then the name change applies to all selected tags + * - if tagicons is configured to have unique tags per monitor then the change only applies + * for the current monitor + * - the name change applies to the tag set that is active for the current tag: + * * if used in combination with BAR_ALTTAGSDECORATION_PATCH and there are clients on the + * given tag then the name change only applies to the ALT_TAGS_DECORATION tag set + * * if used in combination with the BAR_ALTERNATIVE_TAGS_PATCH and alternative tags are + * shown then the name change only applies to the ALTERNATIVE_TAGS tag set + * * if used in combination with both then BAR_ALTTAGSDECORATION_PATCH takes precedence + * * otherwise the name change applies to the DEFAULT_TAGS tag set + * + * https://dwm.suckless.org/patches/nametag/ + */ +#define NAMETAG_PATCH 0 + +/* Variant of the above which prepends the tag number to the given string. + * The toggle does nothing on its own and need to be enabled in combination with the above. */ +#define NAMETAG_PREPEND_PATCH 0 + /* Adds support for the _NET_CLIENT_LIST_STACKING atom, needed by certain applications like the * Zoom video conferencing application. * https://github.com/bakkeby/patches/wiki/netclientliststacking/ From 2d34596ad0a93860225b2b318d8f2d57e0e50f64 Mon Sep 17 00:00:00 2001 From: bakkeby Date: Fri, 12 Aug 2022 15:01:05 +0200 Subject: [PATCH 2/2] Bump to 44adafe. Make floating windows spawn within the monitor's window area This is a follow-up on this thread: https://lists.suckless.org/hackers/2208/18462.html The orginal code had constraints such that if a window's starting attributes (position and size) were to place the window outside of the edges of the monitor, then the window would be moved into view at the closest monitor edge. There was an exception to this where if a top bar is used then the window should not obscure the bar if present, which meant to place the window within the window area instead. The proposed change here makes it the general rule that floating windows should spawn within the window area rather than within the monitor area. This makes it simple and consistent with no exceptions and it makes the intention of the code clear. This has the benefit of making the behaviour consistent regardless of whether the user is using a top bar or a bottom bar. Additionally this will have an effect on patches that modify the size of the window area. For example if the insets patch is used to reserve space on the left hand side of the monitor for a dock or a vertical bar then new floating clients will not obscure that area. Ref. https://git.suckless.org/dwm/commit/44adafe0069e73aa03a3829d7bb39591cd8b3f1d.html --- README.md | 2 +- dwm.c | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index dd98d9f..d773157 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This dwm 6.3 (e0dee91, 2022-08-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.3 (44adafe, 2022-08-11) 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 diff --git a/dwm.c b/dwm.c index 9a73159..8beafff 100644 --- a/dwm.c +++ b/dwm.c @@ -2465,14 +2465,12 @@ manage(Window w, XWindowAttributes *wa) #endif // SWALLOW_PATCH } - if (c->x + WIDTH(c) > c->mon->mx + c->mon->mw) - c->x = c->mon->mx + c->mon->mw - WIDTH(c); - if (c->y + HEIGHT(c) > c->mon->my + c->mon->mh) - c->y = c->mon->my + c->mon->mh - HEIGHT(c); - c->x = MAX(c->x, c->mon->mx); - /* only fix client y-offset, if the client center might cover the bar */ - c->y = MAX(c->y, ((!c->mon->bar || c->mon->bar->by == c->mon->my) && (c->x + (c->w / 2) >= c->mon->wx) - && (c->x + (c->w / 2) < c->mon->wx + c->mon->ww)) ? bh : c->mon->my); + if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) + c->x = c->mon->wx + c->mon->ww - WIDTH(c); + if (c->y + HEIGHT(c) > c->mon->wy + c->mon->wh) + c->y = c->mon->wy + c->mon->wh - HEIGHT(c); + c->x = MAX(c->x, c->mon->wx); + c->y = MAX(c->y, c->mon->wy); wc.border_width = c->bw; XConfigureWindow(dpy, w, CWBorderWidth, &wc);