diff options
| -rw-r--r-- | dwl.c | 75 | ||||
| -rw-r--r-- | patches/pertag.patch | 170 | 
2 files changed, 240 insertions, 5 deletions
@@ -104,6 +104,7 @@ typedef struct {  	const Arg arg;  } Button; +typedef struct Pertag Pertag;  typedef struct Monitor Monitor;  typedef struct {  	/* Must keep this field first */ @@ -201,6 +202,7 @@ struct Monitor {  	struct wlr_box w; /* window area, layout-relative */  	struct wl_list layers[4]; /* LayerSurface.link */  	const Layout *lt[2]; +	Pertag *pertag;  	unsigned int seltags;  	unsigned int sellt;  	uint32_t tagset[2]; @@ -434,6 +436,14 @@ static xcb_atom_t netatom[NetLast];  static pid_t *autostart_pids;  static size_t autostart_len; +struct Pertag { +	unsigned int curtag, prevtag; /* current and previous tag */ +	int nmasters[TAGCOUNT + 1]; /* number of windows in master area */ +	float mfacts[TAGCOUNT + 1]; /* mfacts per tag */ +	unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */ +	const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes  */ +}; +  /* function implementations */  void  applybounds(Client *c, struct wlr_box *bbox) @@ -753,6 +763,7 @@ cleanupmon(struct wl_listener *listener, void *data)  	wlr_output_layout_remove(output_layout, m->wlr_output);  	wlr_scene_output_destroy(m->scene_output); +	free(m->pertag);  	closemon(m);  	wlr_scene_node_destroy(&m->fullscreen_bg->node);  	free(m); @@ -1060,6 +1071,18 @@ createmon(struct wl_listener *listener, void *data)  	wl_list_insert(&mons, &m->link);  	printstatus(); +	m->pertag = calloc(1, sizeof(Pertag)); +	m->pertag->curtag = m->pertag->prevtag = 1; + +	for (i = 0; i <= TAGCOUNT; i++) { +		m->pertag->nmasters[i] = m->nmaster; +		m->pertag->mfacts[i] = m->mfact; + +		m->pertag->ltidxs[i][0] = m->lt[0]; +		m->pertag->ltidxs[i][1] = m->lt[1]; +		m->pertag->sellts[i] = m->sellt; +	} +  	/* The xdg-protocol specifies:  	 *  	 * If the fullscreened surface is not opaque, the compositor must make @@ -1566,7 +1589,7 @@ incnmaster(const Arg *arg)  {  	if (!arg || !selmon)  		return; -	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); +	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);  	arrange(selmon);  } @@ -2375,9 +2398,9 @@ setlayout(const Arg *arg)  	if (!selmon)  		return;  	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) -		selmon->sellt ^= 1; +		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;  	if (arg && arg->v) -		selmon->lt[selmon->sellt] = (Layout *)arg->v; +		selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;  	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));  	arrange(selmon);  	printstatus(); @@ -2394,7 +2417,7 @@ setmfact(const Arg *arg)  	f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f;  	if (f < 0.1 || f > 0.9)  		return; -	selmon->mfact = f; +	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;  	arrange(selmon);  } @@ -2776,9 +2799,29 @@ void  toggleview(const Arg *arg)  {  	uint32_t newtagset; +	size_t i;  	if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0))  		return; +	if (newtagset == (uint32_t)~0) { +		selmon->pertag->prevtag = selmon->pertag->curtag; +		selmon->pertag->curtag = 0; +	} + +	/* test if the user did not select the same tag */ +	if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { +		selmon->pertag->prevtag = selmon->pertag->curtag; +		for (i = 0; !(newtagset & 1 << i); i++) ; +		selmon->pertag->curtag = i + 1; +	} + +	/* apply settings for this view */ +	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; +	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; +	selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; +	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; +	selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; +  	selmon->tagset[selmon->seltags] = newtagset;  	focusclient(focustop(selmon), 1);  	arrange(selmon); @@ -2967,11 +3010,33 @@ urgent(struct wl_listener *listener, void *data)  void  view(const Arg *arg)  { +	size_t i, tmptag; +  	if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])  		return;  	selmon->seltags ^= 1; /* toggle sel tagset */ -	if (arg->ui & TAGMASK) +	if (arg->ui & ~0) {  		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; +		selmon->pertag->prevtag = selmon->pertag->curtag; + +		if (arg->ui == TAGMASK) +			selmon->pertag->curtag = 0; +		else { +			for (i = 0; !(arg->ui & 1 << i); i++) ; +			selmon->pertag->curtag = i + 1; +		} +	} else { +		tmptag = selmon->pertag->prevtag; +		selmon->pertag->prevtag = selmon->pertag->curtag; +		selmon->pertag->curtag = tmptag; +	} + +	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; +	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; +	selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; +	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; +	selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; +  	focusclient(focustop(selmon), 1);  	arrange(selmon);  	printstatus(); diff --git a/patches/pertag.patch b/patches/pertag.patch new file mode 100644 index 0000000..971732a --- /dev/null +++ b/patches/pertag.patch @@ -0,0 +1,170 @@ +From d3b551ffe3ec85e16341962e322150b81af6722f Mon Sep 17 00:00:00 2001 +From: wochap <gean.marroquin@gmail.com> +Date: Wed, 31 Jul 2024 08:27:26 -0500 +Subject: [PATCH] makes layout, mwfact and nmaster individual for every tag + +inspiration: https://github.com/djpohly/dwl/wiki/pertag +--- + dwl.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 70 insertions(+), 5 deletions(-) + +diff --git a/dwl.c b/dwl.c +index 145fd01..2f364bc 100644 +--- a/dwl.c ++++ b/dwl.c +@@ -102,6 +102,7 @@ typedef struct { + 	const Arg arg; + } Button; +  ++typedef struct Pertag Pertag; + typedef struct Monitor Monitor; + typedef struct { + 	/* Must keep these three elements in this order */ +@@ -199,6 +200,7 @@ struct Monitor { + 	struct wlr_box w; /* window area, layout-relative */ + 	struct wl_list layers[4]; /* LayerSurface.link */ + 	const Layout *lt[2]; ++	Pertag *pertag; + 	unsigned int seltags; + 	unsigned int sellt; + 	uint32_t tagset[2]; +@@ -427,6 +429,14 @@ static xcb_atom_t netatom[NetLast]; + /* attempt to encapsulate suck into one file */ + #include "client.h" +  ++struct Pertag { ++	unsigned int curtag, prevtag; /* current and previous tag */ ++	int nmasters[TAGCOUNT + 1]; /* number of windows in master area */ ++	float mfacts[TAGCOUNT + 1]; /* mfacts per tag */ ++	unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */ ++	const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes  */ ++}; ++ + /* function implementations */ + void + applybounds(Client *c, struct wlr_box *bbox) +@@ -712,6 +722,7 @@ cleanupmon(struct wl_listener *listener, void *data) + 	wlr_output_layout_remove(output_layout, m->wlr_output); + 	wlr_scene_output_destroy(m->scene_output); +  ++	free(m->pertag); + 	closemon(m); + 	wlr_scene_node_destroy(&m->fullscreen_bg->node); + 	free(m); +@@ -983,6 +994,18 @@ createmon(struct wl_listener *listener, void *data) + 	wl_list_insert(&mons, &m->link); + 	printstatus(); +  ++	m->pertag = calloc(1, sizeof(Pertag)); ++	m->pertag->curtag = m->pertag->prevtag = 1; ++ ++	for (i = 0; i <= TAGCOUNT; i++) { ++		m->pertag->nmasters[i] = m->nmaster; ++		m->pertag->mfacts[i] = m->mfact; ++ ++		m->pertag->ltidxs[i][0] = m->lt[0]; ++		m->pertag->ltidxs[i][1] = m->lt[1]; ++		m->pertag->sellts[i] = m->sellt; ++	} ++ + 	/* The xdg-protocol specifies: + 	 * + 	 * If the fullscreened surface is not opaque, the compositor must make +@@ -1472,7 +1495,7 @@ incnmaster(const Arg *arg) + { + 	if (!arg || !selmon) + 		return; +-	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0); ++	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0); + 	arrange(selmon); + } +  +@@ -2305,9 +2328,9 @@ setlayout(const Arg *arg) + 	if (!selmon) + 		return; + 	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) +-		selmon->sellt ^= 1; ++		selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1; + 	if (arg && arg->v) +-		selmon->lt[selmon->sellt] = (Layout *)arg->v; ++		selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v; + 	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol)); + 	arrange(selmon); + 	printstatus(); +@@ -2324,7 +2347,7 @@ setmfact(const Arg *arg) + 	f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f; + 	if (f < 0.1 || f > 0.9) + 		return; +-	selmon->mfact = f; ++	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f; + 	arrange(selmon); + } +  +@@ -2701,9 +2724,29 @@ void + toggleview(const Arg *arg) + { + 	uint32_t newtagset; ++	size_t i; + 	if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0)) + 		return; +  ++	if (newtagset == (uint32_t)~0) { ++		selmon->pertag->prevtag = selmon->pertag->curtag; ++		selmon->pertag->curtag = 0; ++	} ++ ++	/* test if the user did not select the same tag */ ++	if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) { ++		selmon->pertag->prevtag = selmon->pertag->curtag; ++		for (i = 0; !(newtagset & 1 << i); i++) ; ++		selmon->pertag->curtag = i + 1; ++	} ++ ++	/* apply settings for this view */ ++	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++	selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++	selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ + 	selmon->tagset[selmon->seltags] = newtagset; + 	focusclient(focustop(selmon), 1); + 	arrange(selmon); +@@ -2892,11 +2935,33 @@ urgent(struct wl_listener *listener, void *data) + void + view(const Arg *arg) + { ++	size_t i, tmptag; ++ + 	if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) + 		return; + 	selmon->seltags ^= 1; /* toggle sel tagset */ +-	if (arg->ui & TAGMASK) ++	if (arg->ui & ~0) { + 		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; ++		selmon->pertag->prevtag = selmon->pertag->curtag; ++ ++		if (arg->ui == TAGMASK) ++			selmon->pertag->curtag = 0; ++		else { ++			for (i = 0; !(arg->ui & 1 << i); i++) ; ++			selmon->pertag->curtag = i + 1; ++		} ++	} else { ++		tmptag = selmon->pertag->prevtag; ++		selmon->pertag->prevtag = selmon->pertag->curtag; ++		selmon->pertag->curtag = tmptag; ++	} ++ ++	selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag]; ++	selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag]; ++	selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag]; ++	selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt]; ++	selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1]; ++ + 	focusclient(focustop(selmon), 1); + 	arrange(selmon); + 	printstatus(); +--  +2.45.2 +  | 
