Hi,

I've written a patch that enables per-client 'cfacts'. This
allows users to modify a clients weight in the stack it is
currently located in. So if a client has an increased or
decreased weight it will be allocated more or less space
respectively than the other clients in its stack.

Attached is the patch and a description. Feel free to add this to
the patches-section.

Regards
Patrick
diff --git a/config.def.h b/config.def.h
index 875885b..809788b 100644
--- a/config.def.h
+++ b/config.def.h
@@ -65,6 +65,9 @@ static Key keys[] = {
        { MODKEY,                       XK_d,      incnmaster,     {.i = -1 } },
        { MODKEY,                       XK_h,      setmfact,       {.f = -0.05} 
},
        { MODKEY,                       XK_l,      setmfact,       {.f = +0.05} 
},
+       { MODKEY|ShiftMask,             XK_h,      setcfact,       {.f = +0.25} 
},
+       { MODKEY|ShiftMask,             XK_l,      setcfact,       {.f = -0.25} 
},
+       { MODKEY|ShiftMask,             XK_o,      setcfact,       {.f =  0.00} 
},
        { MODKEY,                       XK_Return, zoom,           {0} },
        { MODKEY,                       XK_Tab,    view,           {0} },
        { MODKEY|ShiftMask,             XK_c,      killclient,     {0} },
diff --git a/dwm.c b/dwm.c
index 1bbb4b3..4ff74cc 100644
--- a/dwm.c
+++ b/dwm.c
@@ -86,6 +86,7 @@ typedef struct Client Client;
 struct Client {
        char name[256];
        float mina, maxa;
+       float cfact;
        int x, y, w, h;
        int oldx, oldy, oldw, oldh;
        int basew, baseh, incw, inch, maxw, maxh, minw, minh;
@@ -200,6 +201,7 @@ static void setclientstate(Client *c, long state);
 static void setfocus(Client *c);
 static void setfullscreen(Client *c, Bool fullscreen);
 static void setlayout(const Arg *arg);
+static void setcfact(const Arg *arg);
 static void setmfact(const Arg *arg);
 static void setup(void);
 static void showhide(Client *c);
@@ -1027,6 +1029,7 @@ manage(Window w, XWindowAttributes *wa) {
        c->w = c->oldw = wa->width;
        c->h = c->oldh = wa->height;
        c->oldbw = wa->border_width;
+       c->cfact = 1.0;
 
        if(c->x + WIDTH(c) > c->mon->mx + c->mon->mw)
                c->x = c->mon->mx + c->mon->mw - WIDTH(c);
@@ -1473,6 +1476,23 @@ setlayout(const Arg *arg) {
                drawbar(selmon);
 }
 
+void setcfact(const Arg *arg) {
+       float f;
+       Client *c;
+
+       c = selmon->sel;
+
+       if(!arg || !c || !selmon->lt[selmon->sellt]->arrange)
+               return;
+       f = arg->f + c->cfact;
+       if(arg->f == 0.0)
+               f = 1.0;
+       else if(f < 0.25 || f > 4.0)
+               return;
+       c->cfact = f;
+       arrange(selmon);
+}
+
 /* arg > 1.0 will set mfact absolutly */
 void
 setmfact(const Arg *arg) {
@@ -1602,9 +1622,15 @@ tagmon(const Arg *arg) {
 void
 tile(Monitor *m) {
        unsigned int i, n, h, mw, my, ty;
+       float mfacts = 0, sfacts = 0;
        Client *c;
 
-       for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++);
+       for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++) {
+               if(n < m->nmaster)
+                       mfacts += c->cfact;
+               else
+                       sfacts += c->cfact;
+       }
        if(n == 0)
                return;
 
@@ -1614,14 +1640,16 @@ tile(Monitor *m) {
                mw = m->ww;
        for(i = my = ty = 0, c = nexttiled(m->clients); c; c = 
nexttiled(c->next), i++)
                if(i < m->nmaster) {
-                       h = (m->wh - my) / (MIN(n, m->nmaster) - i);
+                       h = (m->wh - my) * (c->cfact / mfacts);
                        resize(c, m->wx, m->wy + my, mw - (2*c->bw), h - 
(2*c->bw), False);
                        my += HEIGHT(c);
+                       mfacts -= c->cfact;
                }
                else {
-                       h = (m->wh - ty) / (n - i);
+                       h = (m->wh - ty) * (c->cfact / sfacts);
                        resize(c, m->wx + mw, m->wy + ty, m->ww - mw - 
(2*c->bw), h - (2*c->bw), False);
                        ty += HEIGHT(c);
+                       sfacts -= c->cfact;
                }
 }
 
ctags
=====

Description
-----------

This patch provides the ability to assign different weights to
clients in their respective stack in tiled layout. It implements
a new function setcfact which will modify the cfact-value for the
currently selected client. It accepts the following values:

* A positive float to increase a clients weight, thus increasing
  the space the client is allocated in its current stack.

* A negative float to decrease a clients weight, thus decreasing
  the space the client is allocated in its current stack.

* A zero-value float to reset a clients weight to default.

Default cfact-value for each client is 1.0. If a client is
assigned a cfact value of 0.5 it will be allocated half of the
space other clients would be allocated. If a client is assigned a
cfact value of 2.0 it will be allocated twice the space other
clients would be allocated.

The following illustrates the behavior. The clients cfact-values
are represented by floats inside the clients rectangles.

+---------------------+
|          |   0.5    |
|   1.0    +----------+
+----------+          |
|          |   1.0    |
|          +----------+
|   2.0    |          |
|          |   1.0    |
+----------+----------+

Default key bindings
--------------------

  Key      |  Argument  |  Description
:---------:|:----------:|:----------------
  Mod-`H`  |  `+0.25`   |  Increase cfact
  Mod-`L`  |  `-0.25`   |  Decrease cfact
  Mod-`O`  |  ` 0.00`   |  Reset cfact

Download
--------

* [dwm-6.1-cfacts.diff](dwm-6.1-ctags.diff)

Author
------

* Patrick Steinhardt (pks) <p...@pks.im>

Attachment: pgp1y57HOwemo.pgp
Description: PGP signature

Reply via email to