~ruther/dwl

4f6bdd3ea1fcc83abd962e9a2dc7737519164a6b — Rutherther 8 months ago 690cbdc v0.7/singletagset-pertag
singletagset-pertag
2 files changed, 90 insertions(+), 12 deletions(-)

M config.def.h
M dwl.c
M config.def.h => config.def.h +9 -3
@@ 43,12 43,18 @@ static const Layout layouts[] = {
*/
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
static const MonitorRule monrules[] = {
	/* name       mfact  nmaster scale layout       rotate/reflect                x    y */
	/* name   scale  rotate/reflect                x    y */
	/* example of a HiDPI laptop monitor:
	{ "eDP-1",    0.5f,  1,      2,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
	{ "eDP-1",    2, WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
	*/
	/* defaults */
	{ NULL,       0.55f, 1,      1,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
	{ NULL,       1, WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
};

static const TagRule tagrules[] = {
    /* tag     mfact      nmaster   layout */
    /* defaults */
    { 0,       0.55,      1,        &layouts[0] }
};

/* keyboard */

M dwl.c => dwl.c +81 -9
@@ 104,6 104,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 */


@@ 209,6 210,7 @@ struct Monitor {
	int nmaster;
	char ltsymbol[16];
	int asleep;
	unsigned int pertag[2]; /* the tag used for layout via pertag */
};

typedef struct {


@@ 227,6 229,13 @@ typedef struct {
} PointerConstraint;

typedef struct {
	unsigned int tag;
	float mfact;
	int nmaster;
	const Layout *lt;
} TagRule;

typedef struct {
	const char *id;
	const char *title;
	uint32_t tags;


@@ 245,6 254,7 @@ typedef struct {

/* function declarations */
static void applybounds(Client *c, struct wlr_box *bbox);
static void applypertag(Monitor *m);
static void applyrules(Client *c);
static void arrange(Monitor *m);
static void arrangelayer(Monitor *m, struct wl_list *list,


@@ 293,6 303,7 @@ static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(struct wl_listener *listener, void *data);
static void gpureset(struct wl_listener *listener, void *data);
static unsigned int getpertagtag(unsigned int curtagset);
static size_t getunusedtag(void);
static void handlesig(int signo);
static void incnmaster(const Arg *arg);


@@ 415,6 426,7 @@ static struct wlr_output_layout *output_layout;
static struct wlr_box sgeom;
static struct wl_list mons;
static Monitor *selmon;
static Pertag pertag;

#ifdef XWAYLAND
static void activatex11(struct wl_listener *listener, void *data);


@@ 435,6 447,13 @@ static xcb_atom_t netatom[NetLast];
/* attempt to encapsulate suck into one file */
#include "client.h"

struct Pertag {
	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)


@@ 1023,6 1042,33 @@ createlocksurface(struct wl_listener *listener, void *data)
		client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat));
}

unsigned int
getpertagtag(unsigned int curtagset)
{
	size_t i;

	if (curtagset == TAGMASK) {
		return 0;
	}

	if ((curtagset & TAGMASK) == 0) {
		return 0; // What to do in this case?
	}

	for (i = 0; !(curtagset & 1 << i); i++) ;
	return i + 1;
}

void
applypertag(Monitor *m)
{
	m->nmaster = pertag.nmasters[m->pertag[m->seltags]];
	m->mfact = pertag.mfacts[m->pertag[m->seltags]];
	m->sellt = pertag.sellts[m->pertag[m->seltags]];
	m->lt[m->sellt] = pertag.ltidxs[m->pertag[m->seltags]][m->sellt];
	m->lt[m->sellt^1] = pertag.ltidxs[m->pertag[m->seltags]][m->sellt^1];
}

void
createmon(struct wl_listener *listener, void *data)
{


@@ 1046,14 1092,12 @@ createmon(struct wl_listener *listener, void *data)
	wlr_output_state_init(&state);
	/* Initialize monitor state using configured rules */
	m->tagset[0] = m->tagset[1] = (1<<getunusedtag()) & TAGMASK;
	m->pertag[0] = m->pertag[1] = getpertagtag(m->tagset[0]);
	applypertag(m);
	for (r = monrules; r < END(monrules); r++) {
		if (!r->name || strstr(wlr_output->name, r->name)) {
			m->m.x = r->x;
			m->m.y = r->y;
			m->mfact = r->mfact;
			m->nmaster = r->nmaster;
			m->lt[0] = r->lt;
			m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]];
			strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
			wlr_output_state_set_scale(&state, r->scale);
			wlr_output_state_set_transform(&state, r->rr);


@@ 1597,7 1641,7 @@ incnmaster(const Arg *arg)
{
	if (!arg || !selmon)
		return;
	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
	selmon->nmaster = pertag.nmasters[selmon->pertag[selmon->seltags]] = MAX(selmon->nmaster + arg->i, 0);
	arrange(selmon);
}



@@ 2433,9 2477,9 @@ setlayout(const Arg *arg)
	if (!selmon)
		return;
	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
		selmon->sellt ^= 1;
		selmon->sellt = pertag.sellts[selmon->pertag[selmon->seltags]] ^= 1;
	if (arg && arg->v)
		selmon->lt[selmon->sellt] = (Layout *)arg->v;
		selmon->lt[selmon->sellt] = pertag.ltidxs[selmon->pertag[selmon->seltags]][selmon->sellt] = (Layout *)arg->v;
	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
	arrange(selmon);
	printstatus();


@@ 2452,7 2496,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 = pertag.mfacts[selmon->pertag[selmon->seltags]] = f;
	arrange(selmon);
}



@@ 2504,6 2548,10 @@ setsel(struct wl_listener *listener, void *data)
void
setup(void)
{
	const TagRule *r;
	struct xkb_context *context;
	struct xkb_keymap *keymap;

	int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
	struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
	sigemptyset(&sa.sa_mask);


@@ 2596,6 2644,19 @@ setup(void)
	LISTEN_STATIC(&output_layout->events.change, updatemons);
	wlr_xdg_output_manager_v1_create(dpy, output_layout);

	for (i = 0; i <= TAGCOUNT; i++) {
		for (r = tagrules; r < END(tagrules); r++) {
			if (!r->tag || r->tag == i) {
				pertag.mfacts[i] = r->mfact;
				pertag.nmasters[i] = r->nmaster;
				pertag.sellts[i] = 0;
				pertag.ltidxs[i][0] = r->lt;
				pertag.ltidxs[i][1] = r->lt;
				break;
			}
		}
	}

	/* Configure a listener to be notified when new outputs are available on the
	 * backend. */
	wl_list_init(&mons);


@@ 2857,6 2918,12 @@ toggleview(const Arg *arg)
		if (m !=selmon && newtagset & m->tagset[m->seltags])
			return;

	// set new pertag tag only if the tag we were at was removed, or if all tags are shown.
	if (!(newtagset & 1 << (selmon->pertag[selmon->seltags] - 1)) || newtagset == TAGMASK) {
		selmon->pertag[selmon->seltags] = getpertagtag(newtagset);
	}

	applypertag(selmon);
	selmon->tagset[selmon->seltags] = newtagset;
	attachclients(selmon);
	focusclient(focustop(selmon), 1);


@@ 3072,6 3139,8 @@ view(const Arg *arg)
			}
			m->seltags ^= 1;
			m->tagset[m->seltags] = origm->tagset[origm->seltags];
			m->pertag[m->seltags] = origm->pertag[origm->seltags];
			applypertag(m);
			attachclients(m);
			/* Beware: this changes selmon */
			focusclient(focustop(m), 1);


@@ 3081,11 3150,14 @@ view(const Arg *arg)
	}

	origm->seltags ^= 1; /* toggle sel tagset */
	if (arg->ui & TAGMASK)
	if (arg->ui & TAGMASK) {
		origm->tagset[origm->seltags] = arg->ui & TAGMASK;
		origm->pertag[origm->seltags] = getpertagtag(arg->ui & TAGMASK);
	}

	/* Change selmon back to orig mon */
	selmon = origm;
	applypertag(origm);
	attachclients(origm);
	focusclient(focustop(origm), 1);
	arrange(origm);

Do not follow this link