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;
}
}