sites

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

dwm-flextile-20210722-138b405.diff (14514B)


      1 From cb3d26193fafd0b06217c3bf2d65a6eac74b4941 Mon Sep 17 00:00:00 2001
      2 From: Max Schillinger <maxschillinger@web.de>
      3 Date: Thu, 22 Jul 2021 23:19:36 +0200
      4 Subject: [PATCH] flextile layout for dwm commit 138b405
      5 
      6 ---
      7  config.def.h |  17 +++++-
      8  dwm.c        | 123 +++++++++++++++++++-------------------
      9  flextile.h   | 163 +++++++++++++++++++++++++++++++++++++++++++++++++++
     10  3 files changed, 238 insertions(+), 65 deletions(-)
     11  create mode 100644 flextile.h
     12 
     13 diff --git a/config.def.h b/config.def.h
     14 index a2ac963..1330db2 100644
     15 --- a/config.def.h
     16 +++ b/config.def.h
     17 @@ -21,6 +21,9 @@ static const char *colors[][3]      = {
     18  /* tagging */
     19  static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" };
     20  
     21 +/* include(s) depending on the tags array */
     22 +#include "flextile.h"
     23 +
     24  static const Rule rules[] = {
     25  	/* xprop(1):
     26  	 *	WM_CLASS(STRING) = instance, class
     27 @@ -33,8 +36,12 @@ static const Rule rules[] = {
     28  
     29  /* layout(s) */
     30  static const float mfact     = 0.55; /* factor of master area size [0.05..0.95] */
     31 -static const int nmaster     = 1;    /* number of clients in master area */
     32  static const int resizehints = 1;    /* 1 means respect size hints in tiled resizals */
     33 +static const int layoutaxis[] = {
     34 +	1,    /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */
     35 +	2,    /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */
     36 +	2,    /* stack axis:  1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */
     37 +};
     38  static const int lockfullscreen = 1; /* 1 will force focus on the fullscreen window */
     39  
     40  static const Layout layouts[] = {
     41 @@ -67,8 +74,8 @@ static Key keys[] = {
     42  	{ MODKEY,                       XK_b,      togglebar,      {0} },
     43  	{ MODKEY,                       XK_j,      focusstack,     {.i = +1 } },
     44  	{ MODKEY,                       XK_k,      focusstack,     {.i = -1 } },
     45 -	{ MODKEY,                       XK_i,      incnmaster,     {.i = +1 } },
     46 -	{ MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
     47 +	{ MODKEY,                       XK_i,      shiftmastersplit, {.i = +1} },   /* increase the number of tiled clients in the master area */
     48 +	{ MODKEY,                       XK_d,      shiftmastersplit, {.i = -1} },   /* reduce the number of tiled clients in the master area */
     49  	{ MODKEY,                       XK_h,      setmfact,       {.f = -0.05} },
     50  	{ MODKEY,                       XK_l,      setmfact,       {.f = +0.05} },
     51  	{ MODKEY,                       XK_Return, zoom,           {0} },
     52 @@ -95,6 +102,10 @@ static Key keys[] = {
     53  	TAGKEYS(                        XK_8,                      7)
     54  	TAGKEYS(                        XK_9,                      8)
     55  	{ MODKEY|ShiftMask,             XK_q,      quit,           {0} },
     56 +	{ MODKEY|ControlMask,           XK_t,      rotatelayoutaxis, {.i = 0} },    /* 0 = layout axis */
     57 +	{ MODKEY|ControlMask,           XK_Tab,    rotatelayoutaxis, {.i = 1} },    /* 1 = master axis */
     58 +	{ MODKEY|ControlMask|ShiftMask, XK_Tab,    rotatelayoutaxis, {.i = 2} },    /* 2 = stack axis */
     59 +	{ MODKEY|ControlMask,           XK_Return, mirrorlayout,     {0} },
     60  };
     61  
     62  /* button definitions */
     63 diff --git a/dwm.c b/dwm.c
     64 index 5e4d494..1f1487a 100644
     65 --- a/dwm.c
     66 +++ b/dwm.c
     67 @@ -111,27 +111,6 @@ typedef struct {
     68  	void (*arrange)(Monitor *);
     69  } Layout;
     70  
     71 -struct Monitor {
     72 -	char ltsymbol[16];
     73 -	float mfact;
     74 -	int nmaster;
     75 -	int num;
     76 -	int by;               /* bar geometry */
     77 -	int mx, my, mw, mh;   /* screen size */
     78 -	int wx, wy, ww, wh;   /* window area  */
     79 -	unsigned int seltags;
     80 -	unsigned int sellt;
     81 -	unsigned int tagset[2];
     82 -	int showbar;
     83 -	int topbar;
     84 -	Client *clients;
     85 -	Client *sel;
     86 -	Client *stack;
     87 -	Monitor *next;
     88 -	Window barwin;
     89 -	const Layout *lt[2];
     90 -};
     91 -
     92  typedef struct {
     93  	const char *class;
     94  	const char *instance;
     95 @@ -175,7 +154,6 @@ static long getstate(Window w);
     96  static int gettextprop(Window w, Atom atom, char *text, unsigned int size);
     97  static void grabbuttons(Client *c, int focused);
     98  static void grabkeys(void);
     99 -static void incnmaster(const Arg *arg);
    100  static void keypress(XEvent *e);
    101  static void killclient(const Arg *arg);
    102  static void manage(Window w, XWindowAttributes *wa);
    103 @@ -631,17 +609,32 @@ configurerequest(XEvent *e)
    104  Monitor *
    105  createmon(void)
    106  {
    107 +	unsigned int i;
    108  	Monitor *m;
    109  
    110  	m = ecalloc(1, sizeof(Monitor));
    111  	m->tagset[0] = m->tagset[1] = 1;
    112  	m->mfact = mfact;
    113 -	m->nmaster = nmaster;
    114  	m->showbar = showbar;
    115  	m->topbar = topbar;
    116  	m->lt[0] = &layouts[0];
    117  	m->lt[1] = &layouts[1 % LENGTH(layouts)];
    118  	strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol);
    119 +	m->ltaxis[0] = layoutaxis[0];
    120 +	m->ltaxis[1] = layoutaxis[1];
    121 +	m->ltaxis[2] = layoutaxis[2];
    122 +	m->msplit = 1;
    123 +	/* init tags, bars, layouts, axes, msplits and mfacts */
    124 +	m->curtag = m->prevtag = 1;
    125 +	for(i = 0; i < LENGTH(tags) + 1; i++){
    126 +		m->showbars[i] = m->showbar;
    127 +		m->lts[i] = &layouts[0];
    128 +		m->mfacts[i] = m->mfact;
    129 +		m->ltaxes[i][0] = m->ltaxis[0];
    130 +		m->ltaxes[i][1] = m->ltaxis[1];
    131 +		m->ltaxes[i][2] = m->ltaxis[2];
    132 +		m->msplits[i] = m->msplit;
    133 +	}
    134  	return m;
    135  }
    136  
    137 @@ -964,13 +957,6 @@ grabkeys(void)
    138  	}
    139  }
    140  
    141 -void
    142 -incnmaster(const Arg *arg)
    143 -{
    144 -	selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
    145 -	arrange(selmon);
    146 -}
    147 -
    148  #ifdef XINERAMA
    149  static int
    150  isuniquegeom(XineramaScreenInfo *unique, size_t n, XineramaScreenInfo *info)
    151 @@ -1504,7 +1490,7 @@ setlayout(const Arg *arg)
    152  	if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
    153  		selmon->sellt ^= 1;
    154  	if (arg && arg->v)
    155 -		selmon->lt[selmon->sellt] = (Layout *)arg->v;
    156 +		selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v;
    157  	strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol);
    158  	if (selmon->sel)
    159  		arrange(selmon);
    160 @@ -1523,7 +1509,7 @@ setmfact(const Arg *arg)
    161  	f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0;
    162  	if (f < 0.05 || f > 0.95)
    163  		return;
    164 -	selmon->mfact = f;
    165 +	selmon->mfact = selmon->mfacts[selmon->curtag] = f;
    166  	arrange(selmon);
    167  }
    168  
    169 @@ -1671,38 +1657,10 @@ tagmon(const Arg *arg)
    170  	sendmon(selmon->sel, dirtomon(arg->i));
    171  }
    172  
    173 -void
    174 -tile(Monitor *m)
    175 -{
    176 -	unsigned int i, n, h, mw, my, ty;
    177 -	Client *c;
    178 -
    179 -	for (n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    180 -	if (n == 0)
    181 -		return;
    182 -
    183 -	if (n > m->nmaster)
    184 -		mw = m->nmaster ? m->ww * m->mfact : 0;
    185 -	else
    186 -		mw = m->ww;
    187 -	for (i = my = ty = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), i++)
    188 -		if (i < m->nmaster) {
    189 -			h = (m->wh - my) / (MIN(n, m->nmaster) - i);
    190 -			resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - (2*c->bw), 0);
    191 -			if (my + HEIGHT(c) < m->wh)
    192 -				my += HEIGHT(c);
    193 -		} else {
    194 -			h = (m->wh - ty) / (n - i);
    195 -			resize(c, m->wx + mw, m->wy + ty, m->ww - mw - (2*c->bw), h - (2*c->bw), 0);
    196 -			if (ty + HEIGHT(c) < m->wh)
    197 -				ty += HEIGHT(c);
    198 -		}
    199 -}
    200 -
    201  void
    202  togglebar(const Arg *arg)
    203  {
    204 -	selmon->showbar = !selmon->showbar;
    205 +	selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar;
    206  	updatebarpos(selmon);
    207  	XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh);
    208  	arrange(selmon);
    209 @@ -1726,12 +1684,31 @@ void
    210  toggletag(const Arg *arg)
    211  {
    212  	unsigned int newtags;
    213 +	unsigned int i;
    214  
    215  	if (!selmon->sel)
    216  		return;
    217  	newtags = selmon->sel->tags ^ (arg->ui & TAGMASK);
    218  	if (newtags) {
    219  		selmon->sel->tags = newtags;
    220 +		if(newtags == ~0) {
    221 +			selmon->prevtag = selmon->curtag;
    222 +			selmon->curtag = 0;
    223 +		}
    224 +		if(!(newtags & 1 << (selmon->curtag - 1))) {
    225 +			selmon->prevtag = selmon->curtag;
    226 +			for (i=0; !(newtags & 1 << i); i++);
    227 +			selmon->curtag = i + 1;
    228 +		}
    229 +		selmon->sel->tags = newtags;
    230 +		selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
    231 +		selmon->mfact = selmon->mfacts[selmon->curtag];
    232 +		if (selmon->showbar != selmon->showbars[selmon->curtag])
    233 +			togglebar(NULL);
    234 +		selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0];
    235 +		selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1];
    236 +		selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2];
    237 +		selmon->msplit = selmon->msplits[selmon->curtag];
    238  		focus(NULL);
    239  		arrange(selmon);
    240  	}
    241 @@ -2038,11 +2015,33 @@ updatewmhints(Client *c)
    242  void
    243  view(const Arg *arg)
    244  {
    245 +	unsigned int i;
    246 +
    247  	if ((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
    248  		return;
    249  	selmon->seltags ^= 1; /* toggle sel tagset */
    250 -	if (arg->ui & TAGMASK)
    251 +	if (arg->ui & TAGMASK) {
    252  		selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
    253 +		selmon->prevtag = selmon->curtag;
    254 +		if(arg->ui == ~0)
    255 +			selmon->curtag = 0;
    256 +		else {
    257 +			for (i=0; !(arg->ui & 1 << i); i++);
    258 +			selmon->curtag = i + 1;
    259 +		}
    260 +	} else {
    261 +		selmon->prevtag = selmon->curtag ^ selmon->prevtag;
    262 +		selmon->curtag ^= selmon->prevtag;
    263 +		selmon->prevtag = selmon->curtag ^ selmon->prevtag;
    264 +	}
    265 +	selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag];
    266 +	selmon->mfact = selmon->mfacts[selmon->curtag];
    267 +	if(selmon->showbar != selmon->showbars[selmon->curtag])
    268 +		togglebar(NULL);
    269 +	selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0];
    270 +	selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1];
    271 +	selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2];
    272 +	selmon->msplit = selmon->msplits[selmon->curtag];
    273  	focus(NULL);
    274  	arrange(selmon);
    275  }
    276 diff --git a/flextile.h b/flextile.h
    277 new file mode 100644
    278 index 0000000..edab893
    279 --- /dev/null
    280 +++ b/flextile.h
    281 @@ -0,0 +1,163 @@
    282 +/* See LICENSE file for copyright and license details. */
    283 +/* © 2010 joten <joten@freenet.de> */
    284 +
    285 +struct Monitor {
    286 +	char ltsymbol[16];
    287 +	float mfact;
    288 +	double mfacts[LENGTH(tags) + 1];
    289 +	int ltaxis[3];
    290 +	int ltaxes[LENGTH(tags) + 1][3];
    291 +	int num;
    292 +	int curtag;
    293 +	int prevtag;
    294 +	int by;               /* bar geometry */
    295 +	int mx, my, mw, mh;   /* screen size */
    296 +	int wx, wy, ww, wh;   /* window area  */
    297 +	unsigned int msplit;
    298 +	unsigned int msplits[LENGTH(tags) + 1];
    299 +	unsigned int seltags;
    300 +	unsigned int sellt;
    301 +	unsigned int tagset[2];
    302 +	int showbar;
    303 +	int showbars[LENGTH(tags) + 1];
    304 +	int topbar;
    305 +	Client *clients;
    306 +	Client *sel;
    307 +	Client *stack;
    308 +	Monitor *next;
    309 +	Window barwin;
    310 +	const Layout *lt[2];
    311 +	const Layout *lts[LENGTH(tags) + 1];
    312 +};
    313 +
    314 +/* function declarations */
    315 +static void mirrorlayout(const Arg *arg);
    316 +static void rotatelayoutaxis(const Arg *arg);
    317 +static void shiftmastersplit(const Arg *arg);
    318 +
    319 +void
    320 +mirrorlayout(const Arg *arg)
    321 +{
    322 +	if(!selmon->lt[selmon->sellt]->arrange)
    323 +		return;
    324 +	selmon->ltaxis[0] *= -1;
    325 +	selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0];
    326 +	arrange(selmon);
    327 +}
    328 +
    329 +void
    330 +rotatelayoutaxis(const Arg *arg)
    331 +{
    332 +	if(!selmon->lt[selmon->sellt]->arrange)
    333 +		return;
    334 +	if(arg->i == 0) {
    335 +		if(selmon->ltaxis[0] > 0)
    336 +			selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 2 ? 1 : selmon->ltaxis[0] + 1;
    337 +		else
    338 +			selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -2 ? -1 : selmon->ltaxis[0] - 1;
    339 +	} else
    340 +		selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 3 ? 1 : selmon->ltaxis[arg->i] + 1;
    341 +	selmon->ltaxes[selmon->curtag][arg->i] = selmon->ltaxis[arg->i];
    342 +	arrange(selmon);
    343 +}
    344 +
    345 +void
    346 +shiftmastersplit(const Arg *arg)
    347 +{
    348 +	unsigned int n;
    349 +	Client *c;
    350 +
    351 +	for(n = 0, c = nexttiled(selmon->clients); c; c = nexttiled(c->next), n++);
    352 +	if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->msplit + arg->i < 1 || selmon->msplit + arg->i > n)
    353 +		return;
    354 +	selmon->msplit += arg->i;
    355 +	selmon->msplits[selmon->curtag] = selmon->msplit;
    356 +	arrange(selmon);
    357 +}
    358 +
    359 +void
    360 +tile(Monitor *m)
    361 +{
    362 +	char sym1 = 61, sym2 = 93, sym3 = 61, sym;
    363 +	int x1 = m->wx, y1 = m->wy, h1 = m->wh, w1 = m->ww, X1 = x1 + w1, Y1 = y1 + h1;
    364 +	int x2 = m->wx, y2 = m->wy, h2 = m->wh, w2 = m->ww, X2 = x2 + w2, Y2 = y2 + h2;
    365 +	unsigned int i, n, n1, n2;
    366 +	Client *c;
    367 +
    368 +	for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
    369 +	if(m->msplit > n)
    370 +		m->msplit = (n == 0) ? 1 : n;
    371 +	/* layout symbol */
    372 +	if(abs(m->ltaxis[0]) == m->ltaxis[1])    /* explicitly: ((abs(m->ltaxis[0]) == 1 && m->ltaxis[1] == 1) || (abs(m->ltaxis[0]) == 2 && m->ltaxis[1] == 2)) */
    373 +		sym1 = 124;
    374 +	if(abs(m->ltaxis[0]) == m->ltaxis[2])
    375 +		sym3 = 124;
    376 +	if(m->ltaxis[1] == 3)
    377 +		sym1 = (n == 0) ? 0 : m->msplit;
    378 +	if(m->ltaxis[2] == 3)
    379 +		sym3 = (n == 0) ? 0 : n - m->msplit;
    380 +	if(m->ltaxis[0] < 0) {
    381 +		sym = sym1;
    382 +		sym1 = sym3;
    383 +		sym2 = 91;
    384 +		sym3 = sym;
    385 +	}
    386 +	if(m->msplit == 1) {
    387 +		if(m->ltaxis[0] > 0)
    388 +			sym1 = 91;
    389 +		else
    390 +			sym3 = 93;
    391 +	}
    392 +	if(m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[2] == 3)
    393 +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3);
    394 +	else if((m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] > 0) || (m->ltaxis[2] == 3 && m->ltaxis[0] < 0))
    395 +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3);
    396 +	else if((m->ltaxis[2] == 3 && m->ltaxis[0] > 0) || (m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] < 0))
    397 +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, sym3);
    398 +	else
    399 +		snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3);
    400 +	if(n == 0)
    401 +		return;
    402 +	/* master and stack area */
    403 +	if(abs(m->ltaxis[0]) == 1 && n > m->msplit) {
    404 +		w1 *= m->mfact;
    405 +		w2 -= w1;
    406 +		x1 += (m->ltaxis[0] < 0) ? w2 : 0;
    407 +		x2 += (m->ltaxis[0] < 0) ? 0 : w1;
    408 +		X1 = x1 + w1;
    409 +		X2 = x2 + w2;
    410 +	} else if(abs(m->ltaxis[0]) == 2 && n > m->msplit) {
    411 +		h1 *= m->mfact;
    412 +		h2 -= h1;
    413 +		y1 += (m->ltaxis[0] < 0) ? h2 : 0;
    414 +		y2 += (m->ltaxis[0] < 0) ? 0 : h1;
    415 +		Y1 = y1 + h1;
    416 +		Y2 = y2 + h2;
    417 +	}
    418 +	/* master */
    419 +	n1 = (m->ltaxis[1] != 1 || w1 / m->msplit < bh) ? 1 : m->msplit;
    420 +	n2 = (m->ltaxis[1] != 2 || h1 / m->msplit < bh) ? 1 : m->msplit;
    421 +	for(i = 0, c = nexttiled(m->clients); i < m->msplit; c = nexttiled(c->next), i++) {
    422 +		resize(c, x1, y1,
    423 +			(m->ltaxis[1] == 1 && i + 1 == m->msplit) ? X1 - x1 - 2 * c->bw : w1 / n1 - 2 * c->bw,
    424 +			(m->ltaxis[1] == 2 && i + 1 == m->msplit) ? Y1 - y1 - 2 * c->bw : h1 / n2 - 2 * c->bw, False);
    425 +		if(n1 > 1)
    426 +			x1 = c->x + WIDTH(c);
    427 +		if(n2 > 1)
    428 +			y1 = c->y + HEIGHT(c);
    429 +	}
    430 +	/* stack */
    431 +	if(n > m->msplit) {
    432 +		n1 = (m->ltaxis[2] != 1 || w2 / (n - m->msplit) < bh) ? 1 : n - m->msplit;
    433 +		n2 = (m->ltaxis[2] != 2 || h2 / (n - m->msplit) < bh) ? 1 : n - m->msplit;
    434 +		for(i = 0; c; c = nexttiled(c->next), i++) {
    435 +			resize(c, x2, y2,
    436 +				(m->ltaxis[2] == 1 && i + 1 == n - m->msplit) ? X2 - x2 - 2 * c->bw : w2 / n1 - 2 * c->bw,
    437 +				(m->ltaxis[2] == 2 && i + 1 == n - m->msplit) ? Y2 - y2 - 2 * c->bw : h2 / n2 - 2 * c->bw, False);
    438 +			if(n1 > 1)
    439 +				x2 = c->x + WIDTH(c);
    440 +			if(n2 > 1)
    441 +				y2 = c->y + HEIGHT(c);
    442 +		}
    443 +	}
    444 +}
    445 -- 
    446 2.25.1
    447