Re: [dwm] "Optimal" tiling patch for 4.8

From: Jordi Marine <jordimarine_AT_gmail.com>
Date: Fri, 28 Mar 2008 12:20:49 +0100

Nice, I use a grid like mode in 4.7, but I lose some space, your solutions
seems better.
However i'm waiting 4.9...
so i'm interested :)

On Fri, Mar 28, 2008 at 10:04 AM, John A. Grahor <jag_AT_techma.com> wrote:

> Here is a patch which adds an "Optimal" aspect ratio tiling mode for dwm
> 4.8.
>
> I call it optimal because it maintains the aspect ratio of all tiled
> clients as close to square as possible by changing the number of rows
> and columns displayed in the tiled area.
>
> The formula to do this is roughly:
>
> ncolumns = sqrt(numclients*tileareawidth/tileareaheight)
>
> but since dwm doesn't include libm, the algorithm loops from ncolumns =
> 1 to nclients and finds the number of columns which results in the
> average client aspect ratio closest to square.
>
> I remember someone asking for this a few weeks back so here it is.
>
> Also, if you can think of a better name than "Optimal" please let me know.
>
> And there may be some corner cases/ safety things I may have missed.
>
> I'll patch 4.9 when it comes out if anyone likes it.
>
> diff -rupN dwm-4.8/config.anselm.h dwm-4.8-optimal/config.anselm.h
> --- dwm-4.8/config.anselm.h 2008-03-13 12:55:43.000000000 -0400
> +++ dwm-4.8-optimal/config.anselm.h 2008-03-28 04:38:44.000000000-0400
> @@ -29,6 +29,7 @@ Layout layouts[] = {
> /* symbol function isfloating */
> { "[]|", tileh, False }, /* first entry is
> default */
> { "[]=", tilev, False },
> + { "[]+", tileoptimal, False },
> { "><>", floating, True },
> { "[M]", monocle, True },
> };
> @@ -107,6 +108,7 @@ Key keys[] = {
> { MODKEY, XK_f, setlayout,
> "><>" },
> { MODKEY, XK_v, setlayout,
> "[]=" },
> { MODKEY, XK_h, setlayout,
> "[]|" },
> + { MODKEY, XK_o, setlayout,
> "[]+" },
> { MODKEY|ShiftMask, XK_space, togglefloating,
> NULL },
> { MODKEY|ShiftMask, XK_c, killclient,
> NULL },
> { MODKEY, XK_0, view,
> NULL },
> diff -rupN dwm-4.8/config.def.h dwm-4.8-optimal/config.def.h
> --- dwm-4.8/config.def.h 2008-03-13 12:55:43.000000000 -0400
> +++ dwm-4.8-optimal/config.def.h 2008-03-28 04:39:05.000000000-0400
> @@ -29,6 +29,7 @@ Layout layouts[] = {
> /* symbol function isfloating */
> { "[]=", tilev, False }, /* first entry is
> default */
> { "[]|", tileh, False },
> + { "[]+", tileoptimal, False },
> { "><>", floating, True },
> { "[M]", monocle, True },
> };
> @@ -49,6 +50,7 @@ Key keys[] = {
> { MODKEY, XK_f, setlayout,
> "><>" },
> { MODKEY, XK_v, setlayout,
> "[]=" },
> { MODKEY, XK_h, setlayout,
> "[]|" },
> + { MODKEY, XK_o, setlayout,
> "[]+" },
> { MODKEY|ShiftMask, XK_space, togglefloating,
> NULL },
> { MODKEY|ShiftMask, XK_c, killclient,
> NULL },
> { MODKEY, XK_0, view,
> NULL },
> diff -rupN dwm-4.8/dwm.1 dwm-4.8-optimal/dwm.1
> --- dwm-4.8/dwm.1 2008-03-13 12:55:43.000000000 -0400
> +++ dwm-4.8-optimal/dwm.1 2008-03-28 04:40:23.000000000 -0400
> @@ -69,6 +69,9 @@ Applies vertical tiled layout.
> .B Mod1\-h
> Applies horizontal tiled layout.
> .TP
> +.B Mod1\-o
> +Applies "optimal" aspect ratio tiled layout.
> +.TP
> .B Mod1\-j
> Focus next window.
> .TP
> diff -rupN dwm-4.8/dwm.c dwm-4.8-optimal/dwm.c
> --- dwm-4.8/dwm.c 2008-03-13 12:55:43.000000000 -0400
> +++ dwm-4.8-optimal/dwm.c 2008-03-28 04:42:04.000000000 -0400
> @@ -174,6 +174,7 @@ Client *tilemaster(unsigned int n);
> void tileresize(Client *c, int x, int y, int w, int h);
> void tilev(void);
> void tilevstack(unsigned int n);
> +void tileoptimal(void);
> void togglefloating(const char *arg);
> void toggletag(const char *arg);
> void toggleview(const char *arg);
> @@ -1615,6 +1616,68 @@ tileh(void) {
> }
> }
>
> +double squareness(const double width, const double height) {
> + /* return a number that is 1 if square and less than 1 if not square
> */
> + return (width<height)?width/height:height/width;
> +}
> +
> +void
> +tileoptimal(void) {
> + int x, y, w, h;
> + unsigned int i,j, n = counttiled();
> + unsigned int cols,rows,extra;
> + double fom, maxfom;
> + Client *c;
> +
> + if(n == 0)
> + return;
> + c = tilemaster(n);
> + if(--n == 0)
> + return;
> +
> + x = tx; y = ty; w = tw; h = th;
> + cols = 1; rows = 1; extra = 0;
> + if (n > 1) {
> + maxfom = 0.0;
> + for (i = 1; i <= n; i++) {
> + rows = n/i;
> + extra = n%i;
> + w = tw/i;
> + fom = ( extra*(rows+1)*squareness(w,th/(rows+1))
> +
> +
> (i-extra)*rows*squareness(w,th/rows) ) / n;
> + if (fom > maxfom) {
> + maxfom = fom;
> + cols = i;
> + }
> + }
> + rows = n/cols;
> + extra = cols - n%cols;
> + w = tw/cols;
> + h = th/rows; /* do columns with fewer rows to the left */
> + }
> +
> + i = 1; /* i is column */
> + j = 1; /* j is row */
> + for(c = nexttiled(c->next); c; c = nexttiled(c->next)) {
> + int W = (i==cols?((tx + tw) - x):w) - 2 * c->border;
> + int H = (j==rows?((ty + th) - y):h) - 2 * c->border;
> + tileresize(c, x, y, W, H);
> + if (j++ == rows) {
> + if (i == extra) {
> + /* we're finished with the last column
> with fewer rows */
> + rows++;
> + h = th/rows;
> + }
> + if (i++ == cols) break;
> + x = c->x + c->w + 2 * c->border;
> + y = ty;
> + j = 1;
> + } else {
> + y = c->y + c->h + 2 * c->border;
> + }
> + }
> +}
> +
> Client *
> tilemaster(unsigned int n) {
> Client *c = nexttiled(clients);
>
>

-- 
Atentament.
Jordi Mariné
Received on Fri Mar 28 2008 - 12:21:21 UTC

This archive was generated by hypermail 2.2.0 : Sun Jul 13 2008 - 15:29:12 UTC