Donald Chai wrote:
@pancake :

> I dont see any point for having a function called
> "dwmiinoinfiniteloop"

Well this function is necessary, I didn't know how to call it, though its name is relevant... If you don't like its name feel free to change it but I won't. The important thing is that it does its job.

I think what "pancake" meant is that code that needs a function called "dwmiinoinfiniteloop" can usually be rewritten to not require it, improving maintainability. From what I can tell, it unsets the second dwmii bit it finds, merging the second column of windows into the first column. Why?

--snip--

void dwmiinoinfiniteloop(void)
{
    Client* firstclients = nexttiled(clients),*t = firstclients;
    for( ; t && !t->dwmii ; t = nexttiled(t->next) );
    firstclients->dwmii = 1;
    if ( t && (t != firstclients) ) { t->dwmii = 0; }
}

The code below contains lots of "if's" that seem to be always true (or should be). Why check them? You don't call dwmiilayoutcol unless if (lt[sellt]->arrange == dwmiilayoutcol). Also, the line
    if (t->dwmii)
should always be true. Otherwise, you'll get an infinite loop. I think it'd be better to remove this check (and not explicitly set firstclients->dwmii=1). This might work better for the case of windows having multiple tags...

void dwmiilayoutcol(void)
{
    Client *firstclients = nexttiled(clients);
if ( !firstclients || (lt[sellt]->arrange != dwmiilayoutcol) ) { return; }
    dwmiinoinfiniteloop();
    Client *t = nexttiled(firstclients->next);
    int n = 1;
    for( ; t ; n += ( t->dwmii ? 1 : 0 ),t = nexttiled(t->next) );
int x = wx,dw = ww / n; for ( t = firstclients ; t ; )
    {
        if ( t->dwmii )
        {
            n = 1;
            Client *s = nexttiled(t->next);
            for( ; s && !s->dwmii ; n++,s = nexttiled(s->next) );
            int dh = wh / n,y = wy + dh;
            resize(t,x,wy,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
for( t = nexttiled(t->next) ; t && !t->dwmii ; t = nexttiled(t->next) )
            {
                resize(t,x,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
                y += dh;
            }
            x += dw;
        }
    }
}




Here's the c file as said.

Kind regards,
QUINTIN Guillaume.

/*
 * I used WMII and found it too "heavy". So I switched to dwm but I
 * quickly missed the possibilities of having several columns,
 * several windows in each column and moving the windows from a
 * column into another or change the windows' order within a column.
 * As there were no patch (or layout) providing that, I wrote one.
 * I also added a layout that does the same thing but arrange the
 * windows by rows.
 *
 * The col dwmii layout :
 *
 *   +--+--+--+
 *   |  |  |  |
 *   +--+  |  |
 *   |  +--+  |
 *   +--+  |  |
 *   |  |  |  |
 *   +--+--+--+
 *
 * The row dwmii layout :
 *
 *   +--+---+--+
 *   +  |   |  +
 *   +--+-+-+--+
 *   |    |    |
 *   +----+----+
 *   |         |
 *   +---------+
 *
 * You can move a window to the next/previous columnn, after the next
 * window or before the previous window within a column by simple
 * combination of keys (the same as in WMII).
 *
 * To get the dwmii layouts working you have to :
 * - have DWM version 5.1
 * - add these lines in the config.h file :
 *   - just before the layouts array :
 *
 *     #include "dwmii.c" 
 *
 *   - in the layouts array :
 *
 *     { "COL", dwmiilayoutcol },
 *     { "ROW", dwmiilayoutrow },
 *
 *   - in the keys array :
 *
 *     { MODKEY,           XK_c,      setlayout,       {.v = &layouts[1]} },
 *     { MODKEY,           XK_r,      setlayout,       {.v = &layouts[2]} },
 *     { MODKEY|ShiftMask, XK_Up,     dwmiikeypressed, {.i = XK_Up} },
 *     { MODKEY|ShiftMask, XK_Left,   dwmiikeypressed, {.i = XK_Left} },
 *     { MODKEY|ShiftMask, XK_Down,   dwmiikeypressed, {.i = XK_Down} },
 *     { MODKEY|ShiftMask, XK_Right,  dwmiikeypressed, {.i = XK_Right} },
 *     { MODKEY|ShiftMask, XK_n,      dwmiitoggle,     {0} },
 *
 * - add this line in the Client struct definition in the dwm.c file :
 *
 *   int dwmii;
 *
 * - compile and it should work !
 *
 * The dwmiitoggle sets the dwmii variable of a window, when
 * the dwmii is non zero then the window marks the start of a
 * new column/row depending on the layout used.
 *
 * As Donald Chai told me the dwmiimarkfirstwindow function is not necessary.
 * You can comment the two calls to this function in the dwmiilayoutXXX
 * functions or simply suppress these lines and the function as well.
 * the differences is in the way the windows are arranged. If you suppress
 * the function, then the first window of the first column of a tag will not
 * necessarily have its dwmii set to non zero, which means when you will select
 * several tags at once, the column you saw in a given tag will not necessarily
 * be a column !
 *
 * Enjoy it and feel free to send me all your comments !
 *
 * QUINTIN Guillaume
 *
 */

static void dwmiitoggle(const Arg *);
static void dwmiiinsertafter(Client *,Client *,int);
static void dwmiikeypressed(const Arg *);
static void dwmiimarkfirstwindow(void);
static void dwmiilayoutcol(void);
static void dwmiilayoutrow(void);
 
void dwmiitoggle(const Arg *arg)
{
	if ( !lt[sellt]->arrange || (sel && sel->isfloating) ) { return; }
	Client *firstclients = nexttiled(clients);
	if ( sel == firstclients ) { return ; }
	if ( sel->dwmii ) { sel->dwmii = 0; return; }
	sel->dwmii = 1;
	arrange();
}

void dwmiiinsertafter(Client *c,Client *after,int dwmii)
{
	if ( !c || !after ) { return; }
	detach(c);
	c->dwmii = dwmii;
	c->next = after->next;
	after->next = c;
}

void dwmiikeypressed(const Arg *arg)
{
	if ( !lt[sellt]->arrange || (sel && sel->isfloating) ) { return; }
	Client* firstclients = nexttiled(clients);
	if ( ( (arg->i == XK_Up) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Left) && (lt[sellt]->arrange == dwmiilayoutrow) ) )
	{
		if ( sel->dwmii ) { return; }
		Client *t = firstclients,*s = 0;
		for( ; t != sel ; s = t,t = nexttiled(t->next) );
		sel->dwmii = s->dwmii;
		dwmiiinsertafter(s,sel,0);
	}
	if ( ( (arg->i == XK_Right) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Down) && (lt[sellt]->arrange == dwmiilayoutrow) ) )
	{
		Client *t = nexttiled(sel->next),*s = 0;
		if ( !t ) { sel->dwmii = 1; arrange(); return; }
		int i = 2;
		for( ; t && ((i -= ( t->dwmii ? 1 : 0 )) > 0) ; s = t,t = nexttiled(t->next) );
		if ( sel->dwmii ) { t = nexttiled(sel->next); if ( t ) { t->dwmii = 1; } }
		dwmiiinsertafter(sel,s,( i == 2 ? 1 : 0 ));
	}
	if ( ( (arg->i == XK_Down) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Right) && (lt[sellt]->arrange == dwmiilayoutrow) ) )
	{
		Client *t = nexttiled(sel->next);
		if ( !t || t->dwmii ) { return; }
		t->dwmii = sel->dwmii;
		dwmiiinsertafter(sel,t,0);
	}
	if ( ( (arg->i == XK_Left) && (lt[sellt]->arrange == dwmiilayoutcol) ) || ( (arg->i == XK_Up) && (lt[sellt]->arrange == dwmiilayoutrow) ) )
	{
		if ( sel == firstclients ) { return; }
		Client *t = firstclients,*s = 0,*u = 0;
		for( ; t != sel ; s = t,t = nexttiled(t->next),u = ( t->dwmii ? s : u) );
		if ( !u ) { return; }
		if ( sel->dwmii ) { t = nexttiled(sel->next); if ( t ) { t->dwmii = 1; } }
		dwmiiinsertafter(sel,u,0);
	}
	arrange();
}

void dwmiimarkfirstwindow(void)
{
	Client* firstclients = nexttiled(clients),*t = firstclients;
	for( ; t && !t->dwmii ; t = nexttiled(t->next) );
	firstclients->dwmii = 1;
	if ( t && (t != firstclients) ) { t->dwmii = 0; }
}

void dwmiilayoutcol(void)
{
	Client *firstclients = nexttiled(clients);
	if ( !firstclients || (lt[sellt]->arrange != dwmiilayoutcol) ) { return; }
	dwmiimarkfirstwindow();
	Client *t = nexttiled(firstclients->next);
	int n = 1;
	for( ; t ; n += ( t->dwmii ? 1 : 0 ),t = nexttiled(t->next) );
	int x = wx,dw = ww / n;	
	for ( t = firstclients ; t ; )
	{
		n = 1;
		Client *s = nexttiled(t->next);
		for( ; s && !s->dwmii ; n++,s = nexttiled(s->next) );
		int dh = wh / n,y = wy + dh;
		resize(t,x,wy,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
		for( t = nexttiled(t->next) ; t && !t->dwmii ; t = nexttiled(t->next) )
		{
			resize(t,x,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
			y += dh;
		}
		x += dw;
	}
}

void dwmiilayoutrow(void)
{
	Client *firstclients = nexttiled(clients);
	if ( !firstclients || (lt[sellt]->arrange != dwmiilayoutrow) ) { return; }
	dwmiimarkfirstwindow();
	Client *t = nexttiled(firstclients->next);
	int n = 1;
	for( ; t ; n += ( t->dwmii ? 1 : 0 ),t = nexttiled(t->next) );
	int y = wy,dh = wh / n;	
	for ( t = firstclients ; t ; )
	{
		n = 1;
		Client *s = nexttiled(t->next);
		for( ; s && !s->dwmii ; n++,s = nexttiled(s->next) );
		int dw = ww / n,x = wx + dw;
		resize(t,wx,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
		for( t = nexttiled(t->next) ; t && !t->dwmii ; t = nexttiled(t->next) )
		{
			resize(t,x,y,dw - 2 * t->bw,dh - 2 * t->bw,resizehints);
			x += dw;
		}
		y += dh;
	}
}

Reply via email to