dwm-autopage-6.8.diff (6093B)
1 diff -urN dwm-6.8/config.def.h dwm-autopage/config.def.h 2 --- dwm-6.8/config.def.h 2026-08-07 00:23:50.492927886 -0500 3 +++ dwm-autopage/config.def.h 2026-08-12 19:37:15.854223459 -0500 4 @@ -39,10 +39,12 @@ 5 static const int refreshrate = 120; /* refresh rate (per second) for client move/resize */ 6 7 static const Layout layouts[] = { 8 - /* symbol arrange function */ 9 - { "[]=", tile }, /* first entry is default */ 10 - { "><>", NULL }, /* no layout function means floating behavior */ 11 - { "[M]", monocle }, 12 + /* symbol arrange page capacity follow*/ 13 + { "[T]=", tile, 0, 0 }, /* unlimited clients per tag */ 14 + { "[A]=", tile, 3, 0 }, /* 3 clients allowed per tag */ 15 + { "[AF]=", tile, 3, 1 }, /* 3 clients allowed per tag and follow autopaged clients */ 16 + { "><>", NULL, 0, 0 }, /* no layout function means floating behavior */ 17 + { "[M]", monocle, 0, 0 }, /* unlimited clients per tag */ 18 }; 19 20 /* key definitions */ 21 @@ -76,8 +78,10 @@ 22 { MODKEY, XK_Tab, view, {0} }, 23 { MODKEY|ShiftMask, XK_c, killclient, {0} }, 24 { MODKEY, XK_t, setlayout, {.v = &layouts[0]} }, 25 - { MODKEY, XK_f, setlayout, {.v = &layouts[1]} }, 26 - { MODKEY, XK_m, setlayout, {.v = &layouts[2]} }, 27 + { MODKEY, XK_s, setlayout, {.v = &layouts[1]} }, 28 + { MODKEY, XK_a, setlayout, {.v = &layouts[2]} }, 29 + { MODKEY, XK_f, setlayout, {.v = &layouts[3]} }, 30 + { MODKEY, XK_m, setlayout, {.v = &layouts[4]} }, 31 { MODKEY, XK_space, setlayout, {0} }, 32 { MODKEY|ShiftMask, XK_space, togglefloating, {0} }, 33 { MODKEY, XK_0, view, {.ui = ~0 } }, 34 diff -urN dwm-6.8/dwm.c dwm-autopage/dwm.c 35 --- dwm-6.8/dwm.c 2026-08-07 00:23:50.493927886 -0500 36 +++ dwm-autopage/dwm.c 2026-08-12 14:05:36.940616192 -0500 37 @@ -91,6 +91,7 @@ 38 int basew, baseh, incw, inch, maxw, maxh, minw, minh, hintsvalid; 39 int bw, oldbw; 40 unsigned int tags; 41 + int isautopaged; 42 int isfixed, isfloating, isurgent, neverfocus, oldstate, isfullscreen; 43 Client *next; 44 Client *snext; 45 @@ -108,6 +109,8 @@ 46 typedef struct { 47 const char *symbol; 48 void (*arrange)(Monitor *); 49 + unsigned int pagecapacity; 50 + int followautopage; 51 } Layout; 52 53 struct Monitor { 54 @@ -184,6 +187,8 @@ 55 static void motionnotify(XEvent *e); 56 static void movemouse(const Arg *arg); 57 static Client *nexttiled(Client *c); 58 +static Client *oldestautopagedclient(Monitor *m, unsigned int tag); 59 +static void autopagemove(Client *c, unsigned int tag); 60 static void pop(Client *c); 61 static void propertynotify(XEvent *e); 62 static void quit(const Arg *arg); 63 @@ -208,6 +213,7 @@ 64 static void tag(const Arg *arg); 65 static void tagmon(const Arg *arg); 66 static void tile(Monitor *m); 67 +static int nclientstag(Monitor *m, unsigned int tag); 68 static void togglebar(const Arg *arg); 69 static void togglefloating(const Arg *arg); 70 static void toggletag(const Arg *arg); 71 @@ -298,6 +304,11 @@ 72 { 73 c->isfloating = r->isfloating; 74 c->tags |= r->tags; 75 + 76 + if (r->tags) { 77 + c->isautopaged = 0; 78 + } 79 + 80 for (m = mons; m && m->num != r->monitor; m = m->next); 81 if (m) 82 c->mon = m; 83 @@ -1028,15 +1039,43 @@ 84 } 85 } 86 87 -void 88 -manage(Window w, XWindowAttributes *wa) 89 +static unsigned int 90 +nexttag(unsigned int tag) 91 +{ 92 + if (tag >= (1U << (LENGTH(tags) - 1))) 93 + return 0; 94 + return tag << 1; 95 +} 96 + 97 +static int 98 +nclientstag(Monitor *m, unsigned int tag) 99 +{ 100 + int n = 0; 101 + Client *c; 102 + if (!tag) 103 + return 0; 104 + for (c = m->clients; c; c = c->next) 105 + if (!c->isfloating && (c->tags & tag)) 106 + n++; 107 + return n; 108 +} 109 + 110 +static void 111 +autopagemove(Client *c, unsigned int tag) 112 { 113 + c->tags = tag; 114 + c->isautopaged = 1; 115 +} 116 + 117 +void 118 +manage(Window w, XWindowAttributes *wa) { 119 Client *c, *t = NULL; 120 Window trans = None; 121 XWindowChanges wc; 122 123 c = ecalloc(1, sizeof(Client)); 124 c->win = w; 125 + c->isautopaged = 1; 126 /* geometry */ 127 c->x = c->oldx = wa->x; 128 c->y = c->oldy = wa->y; 129 @@ -1051,6 +1090,19 @@ 130 } else { 131 c->mon = selmon; 132 applyrules(c); 133 + 134 + if (c->isfloating) 135 + c->isautopaged = 0; 136 + } 137 + 138 + unsigned int cap = c->mon->lt[c->mon->sellt]->pagecapacity; 139 + if (cap && c->isautopaged && nclientstag(c->mon, c->tags) >= (int)cap) { 140 + unsigned int nt = nexttag(c->tags); 141 + if (nt) { 142 + autopagemove(c, nt); 143 + if (c->mon->lt[c->mon->sellt]->followautopage) 144 + view(&(Arg){ .ui = nt }); 145 + } 146 } 147 148 if (c->x + WIDTH(c) > c->mon->wx + c->mon->ww) 149 @@ -1671,6 +1723,7 @@ 150 { 151 if (selmon->sel && arg->ui & TAGMASK) { 152 selmon->sel->tags = arg->ui & TAGMASK; 153 + selmon->sel->isautopaged = 0; 154 focus(NULL); 155 arrange(selmon); 156 } 157 @@ -1712,6 +1765,48 @@ 158 } 159 } 160 161 +static Client * 162 +oldestautopagedclient(Monitor *m, unsigned int tag) 163 +{ 164 + Client *c, *oldest = NULL; 165 + 166 + for (c = m->clients; c; c = c->next) 167 + if (!c->isfloating && 168 + c->isautopaged && 169 + (c->tags & tag)) 170 + oldest = c; 171 + 172 + return oldest; 173 +} 174 + 175 +static void 176 +collapse(Monitor *m, unsigned int tag) 177 +{ 178 + unsigned int cap, nt; 179 + Client *c; 180 + 181 + cap = m->lt[m->sellt]->pagecapacity; 182 + 183 + if (!cap) 184 + return; 185 + 186 + while (nclientstag(m, tag) < (int)cap) { 187 + nt = nexttag(tag); 188 + 189 + if (!nt) 190 + break; 191 + 192 + c = oldestautopagedclient(m, nt); 193 + 194 + if (!c) 195 + break; 196 + 197 + autopagemove(c, tag); 198 + 199 + tag = nt; 200 + } 201 +} 202 + 203 void 204 togglebar(const Arg *arg) 205 { 206 @@ -1745,6 +1840,7 @@ 207 newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 208 if (newtags) { 209 selmon->sel->tags = newtags; 210 + selmon->sel->isautopaged = 0; 211 focus(NULL); 212 arrange(selmon); 213 } 214 @@ -1780,6 +1876,8 @@ 215 { 216 Monitor *m = c->mon; 217 XWindowChanges wc; 218 + unsigned int tag = c->tags; 219 + unsigned int t; 220 221 detach(c); 222 detachstack(c); 223 @@ -1796,6 +1894,10 @@ 224 XUngrabServer(dpy); 225 } 226 free(c); 227 + for (t = 1; t <= TAGMASK; t <<= 1) { 228 + if (tag & t) 229 + collapse(m, t); 230 + } 231 focus(NULL); 232 updateclientlist(); 233 arrange(m);