URI:
       submit autopage patch - sites - public wiki contents of suckless.org
  HTML git clone git://git.suckless.org/sites
   DIR Log
   DIR Files
   DIR Refs
       ---
   DIR commit 10e2c6e834051815915ebb85ed27f88e883e0e1b
   DIR parent f26b75e9b93d1e00a7bd450507af5f9fe6f37a14
  HTML Author: mike <mike@p16>
       Date:   Thu, 27 Aug 2026 23:28:30 -0500
       
       submit autopage patch
       
       Diffstat:
         A dwm.suckless.org/patches/autopage/… |     233 +++++++++++++++++++++++++++++++
         A dwm.suckless.org/patches/autopage/… |      59 +++++++++++++++++++++++++++++++
       
       2 files changed, 292 insertions(+), 0 deletions(-)
       ---
   DIR diff --git a/dwm.suckless.org/patches/autopage/dwm-autopage-6.8.diff b/dwm.suckless.org/patches/autopage/dwm-autopage-6.8.diff
       @@ -0,0 +1,233 @@
       +diff -urN dwm-6.8/config.def.h dwm-autopage/config.def.h
       +--- dwm-6.8/config.def.h        2026-08-07 00:23:50.492927886 -0500
       ++++ dwm-autopage/config.def.h        2026-08-12 19:37:15.854223459 -0500
       +@@ -39,10 +39,12 @@
       + static const int refreshrate = 120;  /* refresh rate (per second) for client move/resize */
       + 
       + static const Layout layouts[] = {
       +-        /* symbol     arrange function */
       +-        { "[]=",      tile },    /* first entry is default */
       +-        { "><>",      NULL },    /* no layout function means floating behavior */
       +-        { "[M]",      monocle },
       ++        /* symbol     arrange         page capacity  follow*/
       ++        { "[T]=",     tile,                        0,                        0 },    /* unlimited clients per tag */
       ++        { "[A]=",     tile,                        3,                        0 },    /* 3 clients allowed per tag */
       ++        { "[AF]=",    tile,                        3,                        1 },    /* 3 clients allowed per tag and follow autopaged clients */
       ++        { "><>",      NULL,                        0,                        0 },    /* no layout function means floating behavior */
       ++        { "[M]",      monocle,                0,                        0 },        /* unlimited clients per tag */
       + };
       + 
       + /* key definitions */
       +@@ -76,8 +78,10 @@
       +         { MODKEY,                       XK_Tab,    view,           {0} },
       +         { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
       +         { MODKEY,                       XK_t,      setlayout,      {.v = &layouts[0]} },
       +-        { MODKEY,                       XK_f,      setlayout,      {.v = &layouts[1]} },
       +-        { MODKEY,                       XK_m,      setlayout,      {.v = &layouts[2]} },
       ++        { MODKEY,                       XK_s,      setlayout,      {.v = &layouts[1]} },
       ++        { MODKEY,                       XK_a,      setlayout,      {.v = &layouts[2]} },
       ++        { MODKEY,                       XK_f,      setlayout,      {.v = &layouts[3]} },
       ++        { MODKEY,                       XK_m,      setlayout,      {.v = &layouts[4]} },
       +         { MODKEY,                       XK_space,  setlayout,      {0} },
       +         { MODKEY|ShiftMask,             XK_space,  togglefloating, {0} },
       +         { MODKEY,                       XK_0,      view,           {.ui = ~0 } },
       +diff -urN dwm-6.8/dwm.c dwm-autopage/dwm.c
       +--- dwm-6.8/dwm.c        2026-08-07 00:23:50.493927886 -0500
       ++++ dwm-autopage/dwm.c        2026-08-12 14:05:36.940616192 -0500
       +@@ -91,6 +91,7 @@
       +         int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid;
       +         int bw, oldbw;
       +         unsigned int tags;
       ++        int isautopaged;
       +         int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen;
       +         Client *next;
       +         Client *snext;
       +@@ -108,6 +109,8 @@
       + typedef struct {
       +         const char *symbol;
       +         void (*arrange)(Monitor *);
       ++        unsigned int pagecapacity;
       ++        int followautopage;
       + } Layout;
       + 
       + struct Monitor {
       +@@ -184,6 +187,8 @@
       + static void motionnotify(XEvent *e);
       + static void movemouse(const Arg *arg);
       + static Client *nexttiled(Client *c);
       ++static Client *oldestautopagedclient(Monitor *m, unsigned int tag);
       ++static void autopagemove(Client *c, unsigned int tag);
       + static void pop(Client *c);
       + static void propertynotify(XEvent *e);
       + static void quit(const Arg *arg);
       +@@ -208,6 +213,7 @@
       + static void tag(const Arg *arg);
       + static void tagmon(const Arg *arg);
       + static void tile(Monitor *m);
       ++static int nclientstag(Monitor *m, unsigned int tag);
       + static void togglebar(const Arg *arg);
       + static void togglefloating(const Arg *arg);
       + static void toggletag(const Arg *arg);
       +@@ -298,6 +304,11 @@
       +                 {
       +                         c->isfloating = r->isfloating;
       +                         c->tags |= r->tags;
       ++
       ++                        if (r->tags) {
       ++                                c->isautopaged = 0;
       ++                        }
       ++
       +                         for (m = mons; m && m->num != r->monitor; m = m->next);
       +                         if (m)
       +                                 c->mon = m;
       +@@ -1028,15 +1039,43 @@
       +         }
       + }
       + 
       +-void
       +-manage(Window w, XWindowAttributes *wa)
       ++static unsigned int
       ++nexttag(unsigned int tag)
       ++{
       ++        if (tag >= (1U << (LENGTH(tags) - 1)))
       ++                return 0;
       ++        return tag << 1;
       ++}
       ++
       ++static int
       ++nclientstag(Monitor *m, unsigned int tag)
       ++{
       ++        int n = 0;
       ++        Client *c;
       ++        if (!tag)
       ++                return 0;
       ++        for (c = m->clients; c; c = c->next)
       ++                if (!c->isfloating && (c->tags & tag))
       ++                        n++;
       ++        return n;
       ++}
       ++
       ++static void
       ++autopagemove(Client *c, unsigned int tag)
       + {
       ++        c->tags = tag;
       ++        c->isautopaged = 1;
       ++}
       ++
       ++void
       ++manage(Window w, XWindowAttributes *wa) {
       +         Client *c, *t = NULL;
       +         Window trans = None;
       +         XWindowChanges wc;
       + 
       +         c = ecalloc(1, sizeof(Client));
       +         c->win = w;
       ++        c->isautopaged = 1;
       +         /* geometry */
       +         c->x = c->oldx = wa->x;
       +         c->y = c->oldy = wa->y;
       +@@ -1051,6 +1090,19 @@
       +         } else {
       +                 c->mon = selmon;
       +                 applyrules(c);
       ++
       ++                if (c->isfloating)
       ++                        c->isautopaged = 0;
       ++        }
       ++
       ++        unsigned int cap = c->mon->lt[c->mon->sellt]->pagecapacity;
       ++        if (cap && c->isautopaged && nclientstag(c->mon, c->tags) >= (int)cap) {
       ++                unsigned int nt = nexttag(c->tags);
       ++                if (nt) {
       ++                        autopagemove(c, nt);
       ++                        if (c->mon->lt[c->mon->sellt]->followautopage)        
       ++                                view(&(Arg){ .ui = nt });
       ++                }
       +         }
       + 
       +         if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww)
       +@@ -1671,6 +1723,7 @@
       + {
       +         if (selmon->sel && arg->ui & TAGMASK) {
       +                 selmon->sel->tags = arg->ui & TAGMASK;
       ++                selmon->sel->isautopaged = 0;
       +                 focus(NULL);
       +                 arrange(selmon);
       +         }
       +@@ -1712,6 +1765,48 @@
       +                 }
       + }
       + 
       ++static Client *
       ++oldestautopagedclient(Monitor *m, unsigned int tag)
       ++{
       ++        Client *c, *oldest = NULL;
       ++
       ++        for (c = m->clients; c; c = c->next)
       ++                if (!c->isfloating &&
       ++                        c->isautopaged &&
       ++                        (c->tags & tag))
       ++                        oldest = c;
       ++        
       ++        return oldest;
       ++}
       ++
       ++static void
       ++collapse(Monitor *m, unsigned int tag)
       ++{
       ++        unsigned int cap, nt;
       ++        Client *c;
       ++
       ++        cap = m->lt[m->sellt]->pagecapacity;
       ++
       ++        if (!cap)
       ++                return;
       ++
       ++        while (nclientstag(m, tag) < (int)cap) {
       ++                nt = nexttag(tag);
       ++        
       ++                if (!nt)
       ++                        break;
       ++        
       ++                c = oldestautopagedclient(m, nt);
       ++
       ++                if (!c)
       ++                        break;
       ++
       ++                autopagemove(c, tag);
       ++
       ++                tag = nt;
       ++        }
       ++}
       ++
       + void
       + togglebar(const Arg *arg)
       + {
       +@@ -1745,6 +1840,7 @@
       +         newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
       +         if (newtags) {
       +                 selmon->sel->tags = newtags;
       ++                selmon->sel->isautopaged = 0;
       +                 focus(NULL);
       +                 arrange(selmon);
       +         }
       +@@ -1780,6 +1876,8 @@
       + {
       +         Monitor *m = c->mon;
       +         XWindowChanges wc;
       ++        unsigned int tag = c->tags;
       ++        unsigned int t;
       + 
       +         detach(c);
       +         detachstack(c);
       +@@ -1796,6 +1894,10 @@
       +                 XUngrabServer(dpy);
       +         }
       +         free(c);
       ++        for (t = 1; t <= TAGMASK; t <<= 1) {
       ++                if (tag & t)
       ++                        collapse(m, t);
       ++        }
       +         focus(NULL);
       +         updateclientlist();
       +         arrange(m);
   DIR diff --git a/dwm.suckless.org/patches/autopage/index.md b/dwm.suckless.org/patches/autopage/index.md
       @@ -0,0 +1,59 @@
       +autopage
       +========
       +
       +Description
       +-----------
       +The `autopage` patch for dwm adds configurable per-layout client page
       +capacity with automatic "paging" to overflow clients to the next tag.
       +Rule-assigned and manually moved clients are protected from autopaging while
       +empty slots are filled by eligible autopaged clients from the neighboring tag.
       +
       +The behavior of `autopage` can be configured in config.def.h
       +```
       +    
       +static const Layout layouts[] = {
       +        /* symbol     arrange         page capacity  follow*/
       +        { "[T]=",     tile,                        0,                        0 },    /* unlimited clients per tag */
       +        { "[A]=",     tile,                        3,                        0 },    /* 3 clients allowed per tag */
       +        { "[AF]=",    tile,                        4,                        1 },    /* 4 clients allowed per tag and follow autopagedclients */
       +        { "[F]",      NULL,                        0,                        0 },    /* no layout function means floating behavior */
       +        { "[M]",      monocle,                0,                        0 },        /* unlimited clients per tag */
       +};
       +
       +```
       +The example only shows customization of the tiled layout, but the autopager
       +is not layout dependent.  It can work on just about any layout except for
       +"floating" because I wrote it so that floating windows are not autopage
       +candidates. 
       +
       +
       +As clients are closed, autopaged clients are pulled from subsequent tags to fill
       +empty slots left by the closed clients. Rule-assigned and manually moved
       +clients are still protected and will not change position.
       +
       +Behavior
       +--------
       +
       +capacity = 3
       +Tag 1: C1 C2 C3
       +Tag 2: C4 C5 C6
       +Tag 3: C7 C8 C9
       +Tag 4: C10 C11 C12
       +
       +(close client 4)
       +
       +Tag 1: C1 C2 C3
       +Tag 2: C5 C6 C7
       +Tag 3: C8 C9 C10
       +Tag 4: C11 C12 
       +
       +Download
       +--------
       +* [dwm-autopage-6.8.diff](dwm-autopage-6.8.diff)
       +  (2026-08-21)
       +
       +Author
       +------
       +* [Mike L.](mike868711@gmail.com)
       +
       +