sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

commit 10e2c6e834051815915ebb85ed27f88e883e0e1b
parent f26b75e9b93d1e00a7bd450507af5f9fe6f37a14
Author: mike <mike@p16>
Date:   Thu, 27 Aug 2026 23:28:30 -0500

submit autopage patch

Diffstat:
Adwm.suckless.org/patches/autopage/dwm-autopage-6.8.diff | 233+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Adwm.suckless.org/patches/autopage/index.md | 59+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 292 insertions(+), 0 deletions(-)

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