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 <[EMAIL PROTECTED]> 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é

Reply via email to