~ruther/dwl

f01a3acb7dd8738cb1867dce83979bc839baca5c — Rutherther 11 months ago 2524c9b patch/singletagset-pertag
Apply pertag to work with singletagset
2 files changed, 85 insertions(+), 14 deletions(-)

M config.def.h
M dwl.c
M config.def.h => config.def.h +9 -3
@@ 39,12 39,18 @@ static const Layout layouts[] = {
/* monitors */
/* 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.5,  1,      2,    &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
	{ "eDP-1",    0.5,   WL_OUTPUT_TRANSFORM_NORMAL,   -1,  -1 },
	*/
	/* defaults */
	{ NULL,       0.55, 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 +76 -11
@@ 97,6 97,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 */


@@ 201,19 202,24 @@ struct Monitor {
	int gamma_lut_changed;
	int nmaster;
	char ltsymbol[16];
	unsigned int pertag[2]; /* the tag used for layout via pertag */
};

typedef struct {
	const char *name;
	float mfact;
	int nmaster;
	float scale;
	const Layout *lt;
	enum wl_output_transform rr;
	int x, y;
} MonitorRule;

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

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


@@ 232,6 238,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,


@@ 271,6 278,7 @@ static void focusmon(const Arg *arg);
static void focusstack(const Arg *arg);
static Client *focustop(Monitor *m);
static void fullscreennotify(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);


@@ 386,6 394,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);


@@ 406,6 415,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)


@@ 876,6 892,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)
{


@@ 899,13 942,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] = m->lt[1] = r->lt;
			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);


@@ 1381,7 1423,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);
}



@@ 2149,9 2191,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();


@@ 2168,7 2210,7 @@ setmfact(const Arg *arg)
	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
	if (f < 0.1 || f > 0.9)
		return;
	selmon->mfact = f;
	selmon->mfact = pertag.mfacts[selmon->pertag[selmon->seltags]] = f;
	arrange(selmon);
}



@@ 2220,6 2262,7 @@ setsel(struct wl_listener *listener, void *data)
void
setup(void)
{
	const TagRule *r;
	struct xkb_context *context;
	struct xkb_keymap *keymap;



@@ 2308,6 2351,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);


@@ 2605,6 2661,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);


@@ 2813,6 2875,7 @@ 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 */


@@ 2823,12 2886,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