URI:
       [dwm][patches][betterswallow] add patch for dwm 6.6 - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit 9994c8d76f789e9afb5a3f45e578f3fc1f8bc87c
   DIR parent def4db38eb91ceb524c2467f1852c25099de5d46
  HTML Author: Hubert Głuchowski <fishhh@fishhh.dev>
       Date:   Mon, 22 Dec 2025 17:28:57 +0100
       
       [dwm][patches][betterswallow] add patch for dwm 6.6
       
       Diffstat:
         A dwm.suckless.org/patches/betterswa… |     295 ++++++++++++++++++++++++++++++
         M dwm.suckless.org/patches/betterswa… |       4 +---
       
       2 files changed, 296 insertions(+), 3 deletions(-)
       ---
   DIR diff --git a/dwm.suckless.org/patches/betterswallow/dwm-betterswallow-6.6.diff b/dwm.suckless.org/patches/betterswallow/dwm-betterswallow-6.6.diff
       @@ -0,0 +1,295 @@
       +diff -up -x dwm -x '*.o' -x compile_commands.json dwm-6.6-orig/config.mk dwm-6.6/config.mk
       +--- dwm-6.6-orig/config.mk        2025-12-22 13:50:11.321481527 +0100
       ++++ dwm-6.6/config.mk        2025-12-22 13:51:06.720057380 +0100
       +@@ -25,6 +25,8 @@ FREETYPEINC = /usr/include/freetype2
       + INCS = -I${X11INC} -I${FREETYPEINC}
       + LIBS = -L${X11LIB} -lX11 ${XINERAMALIBS} ${FREETYPELIBS}
       + 
       ++LIBS += -lXRes
       ++
       + # flags
       + CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700L -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS}
       + #CFLAGS   = -g -std=c99 -pedantic -Wall -O0 ${INCS} ${CPPFLAGS}
       +diff -up -x dwm -x '*.o' -x compile_commands.json dwm-6.6-orig/dwm.c dwm-6.6/dwm.c
       +--- dwm-6.6-orig/dwm.c        2025-12-22 13:50:11.322481536 +0100
       ++++ dwm-6.6/dwm.c        2025-12-22 13:52:08.649643404 +0100
       +@@ -40,6 +40,7 @@
       + #include <X11/extensions/Xinerama.h>
       + #endif /* XINERAMA */
       + #include <X11/Xft/Xft.h>
       ++#include <X11/extensions/XRes.h>
       + 
       + #include "drw.h"
       + #include "util.h"
       +@@ -49,7 +50,7 @@
       + #define CLEANMASK(mask)         (mask & ~(numlockmask|LockMask) & (ShiftMask|ControlMask|Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask))
       + #define INTERSECT(x,y,w,h,m)    (MAX(0, MIN((x)+(w),(m)->wx+(m)->ww) - MAX((x),(m)->wx)) \
       +                                * MAX(0, MIN((y)+(h),(m)->wy+(m)->wh) - MAX((y),(m)->wy)))
       +-#define ISVISIBLE(C)            ((C->tags & C->mon->tagset[C->mon->seltags]))
       ++#define ISVISIBLE(C)            (C->swallowed == NULL && (C->tags & C->mon->tagset[C->mon->seltags]))
       + #define MOUSEMASK               (BUTTONMASK|PointerMotionMask)
       + #define WIDTH(X)                ((X)->w + 2 * (X)->bw)
       + #define HEIGHT(X)               ((X)->h + 2 * (X)->bw)
       +@@ -92,6 +93,11 @@ struct Client {
       +         int bw, oldbw;
       +         unsigned int tags;
       +         int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
       ++
       ++        Client *swallower;
       ++        Client *swallowed;
       ++        Client *next_swallowed;
       ++
       +         Client *next;
       +         Client *snext;
       +         Monitor *mon;
       +@@ -140,6 +146,12 @@ typedef struct {
       +         int monitor;
       + } Rule;
       + 
       ++typedef struct SwallowDef {
       ++        pid_t pid;
       ++        Client *swallower;
       ++        struct SwallowDef *next;
       ++} SwallowDef;
       ++
       + /* function declarations */
       + static void applyrules(Client *c);
       + static int applysizehints(Client *c, int *x, int *y, int *w, int *h, int interact);
       +@@ -258,6 +270,8 @@ static void (*handler[LASTEvent]) (XEven
       +         [PropertyNotify] = propertynotify,
       +         [UnmapNotify] = unmapnotify
       + };
       ++static Atom swallow_atom;
       ++static SwallowDef *swallowlist;
       + static Atom wmatom[WMLast], netatom[NetLast];
       + static int running = 1;
       + static Cur *cursor[CurLast];
       +@@ -400,6 +414,69 @@ arrangemon(Monitor *m)
       +                 m->lt[m->sellt]->arrange(m);
       + }
       + 
       ++pid_t
       ++wintopid(Window window) {
       ++  XResClientIdSpec spec;
       ++  spec.client = window;
       ++  spec.mask = XRES_CLIENT_ID_XID;
       ++
       ++  long count;
       ++  XResClientIdValue *output;
       ++  XResQueryClientIds(dpy, 1, &spec, &count, &output);
       ++
       ++  pid_t pid = -1;
       ++
       ++  for (int i = 0; i < count; ++i)
       ++    if (output[i].spec.mask == XRES_CLIENT_ID_PID_MASK) {
       ++      pid = *(pid_t *)output[i].value;
       ++      break;
       ++    }
       ++
       ++  XResClientIdsDestroy(count, output);
       ++
       ++  return pid;
       ++}
       ++
       ++void
       ++copyclientpos(Client *dst, Client *src) {
       ++        dst->bw = src->bw;
       ++        resizeclient(dst, src->x, src->y, src->w, src->h);
       ++        dst->oldx = src->oldx;
       ++        dst->oldy = src->oldy;
       ++        dst->oldw = src->oldw;
       ++        dst->oldh = src->oldh;
       ++        dst->oldbw = src->oldbw;
       ++        dst->oldstate = src->oldstate;
       ++        dst->isfullscreen = src->isfullscreen;
       ++        dst->isfloating = src->isfloating;
       ++        dst->tags = src->tags;
       ++        dst->mon = src->mon;
       ++}
       ++
       ++void
       ++checkswallowed(Client *c) {
       ++        pid_t pid = wintopid(c->win);
       ++
       ++        if(pid < 0) return;
       ++        for(SwallowDef *sd = swallowlist; sd != NULL; sd = sd->next) {
       ++                if(pid == sd->pid) {
       ++                        c->swallower = sd->swallower;
       ++                        copyclientpos(c, sd->swallower);
       ++
       ++                        c->next_swallowed = c->swallower->swallowed;
       ++                        c->swallower->swallowed = c;
       ++
       ++                        c->next = c->swallower->next;
       ++                        c->swallower->next = c;
       ++
       ++                        c->snext = c->swallower->snext;
       ++                        c->swallower->snext = c;
       ++
       ++                        return;
       ++                }
       ++        }
       ++}
       ++
       + void
       + attach(Client *c)
       + {
       +@@ -527,7 +604,15 @@ clientmessage(XEvent *e)
       +         } else if (cme->message_type == netatom[NetActiveWindow]) {
       +                 if (c != selmon->sel && !c->isurgent)
       +                         seturgent(c, 1);
       ++        } else if(cme->message_type == swallow_atom) {
       ++                SwallowDef *node = ecalloc(1, sizeof(SwallowDef));
       ++                node->pid = cme->data.l[0];
       ++                node->swallower = c;
       ++                node->next = swallowlist;
       ++                swallowlist = node;
       ++                return;
       +         }
       ++
       + }
       + 
       + void
       +@@ -714,9 +799,11 @@ drawbar(Monitor *m)
       +         }
       + 
       +         for (c = m->clients; c; c = c->next) {
       +-                occ |= c->tags;
       +-                if (c->isurgent)
       +-                        urg |= c->tags;
       ++                if (!c->swallowed) {
       ++                        occ |= c->tags;
       ++                        if (c->isurgent)
       ++                                urg |= c->tags;
       ++                }
       +         }
       +         x = 0;
       +         for (i = 0; i < LENGTH(tags); i++) {
       +@@ -1059,6 +1146,7 @@ manage(Window w, XWindowAttributes *wa)
       +         c->x = MAX(c->x, c->mon->wx);
       +         c->y = MAX(c->y, c->mon->wy);
       +         c->bw = borderpx;
       ++        checkswallowed(c);
       + 
       +         wc.border_width = c->bw;
       +         XConfigureWindow(dpy, w, CWBorderWidth, &wc);
       +@@ -1073,8 +1161,10 @@ manage(Window w, XWindowAttributes *wa)
       +                 c->isfloating = c->oldstate = trans != None || c->isfixed;
       +         if (c->isfloating)
       +                 XRaiseWindow(dpy, c->win);
       +-        attach(c);
       +-        attachstack(c);
       ++        if(!c->swallower) {
       ++                attach(c);
       ++                attachstack(c);
       ++        }
       +         XChangeProperty(dpy, root, netatom[NetClientList], XA_WINDOW, 32, PropModeAppend,
       +                 (unsigned char *) &(c->win), 1);
       +         XMoveResizeWindow(dpy, c->win, c->x + 2 * sw, c->y, c->w, c->h); /* some windows require this */
       +@@ -1169,6 +1259,10 @@ movemouse(const Arg *arg)
       +                 case Expose:
       +                 case MapRequest:
       +                         handler[ev.type](&ev);
       ++
       ++                        // A MapRequest could've caused the current window to swallow another one.
       ++                        if(c->swallowed)
       ++                                c = c->swallowed;
       +                         break;
       +                 case MotionNotify:
       +                         if ((ev.xmotion.time - lasttime) <= (1000 / 60))
       +@@ -1323,6 +1417,9 @@ resizemouse(const Arg *arg)
       +                 case Expose:
       +                 case MapRequest:
       +                         handler[ev.type](&ev);
       ++
       ++                        if(c->swallowed)
       ++                                c = c->swallowed;
       +                         break;
       +                 case MotionNotify:
       +                         if ((ev.xmotion.time - lasttime) <= (1000 / 60))
       +@@ -1578,6 +1675,7 @@ setup(void)
       +         netatom[NetWMWindowType] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False);
       +         netatom[NetWMWindowTypeDialog] = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
       +         netatom[NetClientList] = XInternAtom(dpy, "_NET_CLIENT_LIST", False);
       ++        swallow_atom = XInternAtom(dpy, "_BETTER_SWALLOW", False);
       +         /* init cursors */
       +         cursor[CurNormal] = drw_cur_create(drw, XC_left_ptr);
       +         cursor[CurResize] = drw_cur_create(drw, XC_sizing);
       +@@ -1595,6 +1693,8 @@ setup(void)
       +                 PropModeReplace, (unsigned char *) &wmcheckwin, 1);
       +         XChangeProperty(dpy, wmcheckwin, netatom[NetWMName], utf8string, 8,
       +                 PropModeReplace, (unsigned char *) "dwm", 3);
       ++        XChangeProperty(dpy, root, swallow_atom, utf8string, 8,
       ++                PropModeReplace, (unsigned char *) "supported", 9);
       +         XChangeProperty(dpy, root, netatom[NetWMCheck], XA_WINDOW, 32,
       +                 PropModeReplace, (unsigned char *) &wmcheckwin, 1);
       +         /* EWMH support per view */
       +@@ -1775,11 +1875,55 @@ unfocus(Client *c, int setfocus)
       + }
       + 
       + void
       ++deleteswallower(Client *c) {
       ++        SwallowDef **prevnext = &swallowlist;
       ++        for(SwallowDef *sd = swallowlist; sd != NULL;) {
       ++                if(sd->swallower == c) {
       ++                        SwallowDef *next = sd->next;
       ++                        *prevnext = next;
       ++                        free(sd);
       ++                        sd = next;
       ++                } else {
       ++                        prevnext = &sd->next;
       ++                        sd = sd->next;
       ++                }
       ++        }
       ++
       ++        Client *sw = c->swallowed;
       ++        while(sw) {
       ++                sw->swallower = NULL;
       ++                Client *next = sw->next_swallowed;
       ++                 sw->next_swallowed = NULL;
       ++                sw = next;
       ++        }
       ++}
       ++
       ++void
       + unmanage(Client *c, int destroyed)
       + {
       +         Monitor *m = c->mon;
       +         XWindowChanges wc;
       + 
       ++        if(c->swallower) {
       ++                Client **prev = &c->swallower->swallowed;
       ++                for(; *prev != c; prev = &(*prev)->next_swallowed)
       ++                        ;
       ++                *prev = c->next_swallowed;
       ++                c->next_swallowed = NULL;
       ++
       ++                if(c->swallower->swallowed == NULL) {
       ++                        detach(c->swallower);
       ++                        detachstack(c->swallower);
       ++
       ++                        c->swallower->next = c->next;
       ++                        c->next = c->swallower;
       ++                        c->swallower->snext = c->snext;
       ++                        c->snext = c->swallower;
       ++
       ++                        copyclientpos(c->swallower, c);
       ++                }
       ++        }
       ++
       +         detach(c);
       +         detachstack(c);
       +         if (!destroyed) {
       +@@ -1793,9 +1937,10 @@ unmanage(Client *c, int destroyed)
       +                 XSync(dpy, False);
       +                 XSetErrorHandler(xerror);
       +                 XUngrabServer(dpy);
       +-        }
       ++        } else deleteswallower(c);
       ++        if(c->swallower) focus(c->swallower);
       ++        else focus(NULL);
       +         free(c);
       +-        focus(NULL);
       +         updateclientlist();
       +         arrange(m);
       + }
   DIR diff --git a/dwm.suckless.org/patches/betterswallow/index.md b/dwm.suckless.org/patches/betterswallow/index.md
       @@ -17,9 +17,6 @@ defaults to the devour mechanism, which unmaps the parent window itself.
        Development of this patch should happen on the [GitHub repository](https://github.com/afishhh/better-swallow)
        of `betterswallow`. If you encounter any bugs, feel free to open an issue.
        
       -Currently, only a version for DWM-6.3 exists. If you wish to update the patch to
       -a newer version of DWM, you can open a pull request on the `betterswallow` repository.
       -
        #### Patching
        
        The patch requires the `Xres` library. Ensure it's included in your build environment.
       @@ -46,6 +43,7 @@ Since `better-swallow` is quite long, I recommend creating an alias, such as `bs
        Download
        --------
        * [dwm-betterswallow-20250116-89eeca1.diff](dwm-betterswallow-20250116-89eeca1.diff) (2025-01-16)
       +* [dwm-betterswallow-6.6.diff](dwm-betterswallow-6.6.diff) (2025-12-22)
        
        Author
        ------