sites

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

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