diff -u dwm-2.1/client.c dwm-2.1.throwaway/client.c --- dwm-2.1/client.c 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/client.c 2006-11-07 06:14:34.000000000 +0000 @@ -193,6 +193,29 @@ XKillClient(dpy, sel->win); } +#include +void +determineIfAspectRatioClient(Client *c) +{ + c->aspectRatio=-1; + XClassHint ch; + if(XGetClassHint(dpy, c->win, &ch) && ch.res_class){ + int i; + for(i=0;iaspectRatio=(double)c->h/(double)c->w; + break; + } + } + if(ch.res_class){ + XFree(ch.res_class); + } + if(ch.res_name){ + XFree(ch.res_name); + } + } +} + void manage(Window w, XWindowAttributes *wa) { Client *c; @@ -208,6 +231,7 @@ c->w = c->tw = wa->width; c->h = wa->height; c->th = bh; + determineIfAspectRatioClient(c);/*modification*/ updatesize(c); if(c->x + c->w + 2 * BORDERPX > sw) c->x = sw - c->w - 2 * BORDERPX; diff -u dwm-2.1/config.default.h dwm-2.1.throwaway/config.default.h --- dwm-2.1/config.default.h 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/config.default.h 2006-11-07 03:05:13.000000000 +0000 @@ -3,24 +3,27 @@ */ #define TAGS \ -const char *tags[] = { "1", "2", "3", "4", "5", NULL }; +const char *tags[] = { "1", " 2", "3", "4","5", "6",\ +"7", "8", "9", "10","11", "12",NULL }; #define DEFMODE dotile /* dofloat */ #define FLOATSYMBOL "><>" #define TILESYMBOL "[]=" -#define FONT "fixed" -#define NORMBGCOLOR "#333366" -#define NORMFGCOLOR "#cccccc" -#define SELBGCOLOR "#666699" -#define SELFGCOLOR "#eeeeee" -#define STATUSBGCOLOR "#dddddd" -#define STATUSFGCOLOR "#222222" +#define FONT "-*-helvetica-bold-r-normal-*-17-*-*-*-*-*-*-*" +#define SELBGCOLOR "#a04000" +#define SELFGCOLOR "#000000" +#define NORMBGCOLOR "#a07000" +#define NORMFGCOLOR "#000000" +#define STATUSBGCOLOR "#a04000" +#define STATUSFGCOLOR "#000000" #define MASTER 600 /* per thousand */ #define MODKEY Mod1Mask #define SNAP 20 /* pixel */ +#define NO_MONITORS 1 + #define KEYS \ static Key key[] = { \ /* modifier key function arguments */ \ @@ -28,39 +31,94 @@ { MODKEY, XK_Tab, focusnext, { 0 } }, \ { MODKEY|ShiftMask, XK_Tab, focusprev, { 0 } }, \ { MODKEY, XK_Return, zoom, { 0 } }, \ - { MODKEY, XK_g, resizemaster, { .i = 15 } }, \ - { MODKEY, XK_s, resizemaster, { .i = -15 } }, \ - { MODKEY|ShiftMask, XK_1, tag, { .i = 0 } }, \ - { MODKEY|ShiftMask, XK_2, tag, { .i = 1 } }, \ - { MODKEY|ShiftMask, XK_3, tag, { .i = 2 } }, \ - { MODKEY|ShiftMask, XK_4, tag, { .i = 3 } }, \ - { MODKEY|ShiftMask, XK_5, tag, { .i = 4 } }, \ - { MODKEY|ControlMask|ShiftMask, XK_1, toggletag, { .i = 0 } }, \ - { MODKEY|ControlMask|ShiftMask, XK_2, toggletag, { .i = 1 } }, \ - { MODKEY|ControlMask|ShiftMask, XK_3, toggletag, { .i = 2 } }, \ - { MODKEY|ControlMask|ShiftMask, XK_4, toggletag, { .i = 3 } }, \ - { MODKEY|ControlMask|ShiftMask, XK_5, toggletag, { .i = 4 } }, \ + { MODKEY|ShiftMask, XK_F1, tag, { .i = 0 } }, \ + { MODKEY|ShiftMask, XK_F2, tag, { .i = 1 } }, \ + { MODKEY|ShiftMask, XK_F3, tag, { .i = 2 } }, \ + { MODKEY|ShiftMask, XK_F4, tag, { .i = 3 } }, \ + { MODKEY|ShiftMask, XK_F5, tag, { .i = 4 } }, \ + { MODKEY|ShiftMask, XK_F6, tag, { .i = 5 } }, \ + { MODKEY|ShiftMask, XK_F7, tag, { .i = 6 } }, \ + { MODKEY|ShiftMask, XK_F8, tag, { .i = 7 } }, \ + { MODKEY|ShiftMask, XK_F9, tag, { .i = 8 } }, \ + { MODKEY|ShiftMask, XK_F10, tag, { .i = 9 } }, \ + { MODKEY|ShiftMask, XK_F11, tag, { .i = 10 } }, \ + { MODKEY|ShiftMask, XK_F12, tag, { .i = 11 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F1, toggletag, { .i = 0 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F2, toggletag, { .i = 1 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F3, toggletag, { .i = 2 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F4, toggletag, { .i = 3 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F5, toggletag, { .i = 4 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F6, toggletag, { .i = 5 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F7, toggletag, { .i = 6 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F8, toggletag, { .i = 7 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F9, toggletag, { .i = 8 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F10, toggletag, { .i = 9 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F11, toggletag, { .i = 10 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_F12, toggletag, { .i = 11 } }, \ { MODKEY|ShiftMask, XK_c, killclient, { 0 } }, \ - { MODKEY, XK_space, togglemode, { 0 } }, \ - { MODKEY, XK_0, viewall, { 0 } }, \ - { MODKEY, XK_1, view, { .i = 0 } }, \ - { MODKEY, XK_2, view, { .i = 1 } }, \ - { MODKEY, XK_3, view, { .i = 2 } }, \ - { MODKEY, XK_4, view, { .i = 3 } }, \ - { MODKEY, XK_5, view, { .i = 4 } }, \ - { MODKEY|ControlMask, XK_1, toggleview, { .i = 0 } }, \ - { MODKEY|ControlMask, XK_2, toggleview, { .i = 1 } }, \ - { MODKEY|ControlMask, XK_3, toggleview, { .i = 2 } }, \ - { MODKEY|ControlMask, XK_4, toggleview, { .i = 3 } }, \ - { MODKEY|ControlMask, XK_5, toggleview, { .i = 4 } }, \ + { MODKEY, XK_f, togglemode, { 0 } }, \ + { MODKEY, XK_F1, view, { .i = 0 } }, \ + { MODKEY, XK_F2, view, { .i = 1 } }, \ + { MODKEY, XK_F3, view, { .i = 2 } }, \ + { MODKEY, XK_F4, view, { .i = 3 } }, \ + { MODKEY, XK_F5, view, { .i = 4 } }, \ + { MODKEY, XK_F6, view, { .i = 5 } }, \ + { MODKEY, XK_F7, view, { .i = 6 } }, \ + { MODKEY, XK_F8, view, { .i = 7 } }, \ + { MODKEY, XK_F9, view, { .i = 8 } }, \ + { MODKEY, XK_F10, view, { .i = 9 } }, \ + { MODKEY, XK_F11, view, { .i = 10 } }, \ + { MODKEY, XK_F12, view, { .i = 11 } }, \ + { MODKEY|ControlMask, XK_F1, toggleview, { .i = 0 } }, \ + { MODKEY|ControlMask, XK_F2, toggleview, { .i = 1 } }, \ + { MODKEY|ControlMask, XK_F3, toggleview, { .i = 2 } }, \ + { MODKEY|ControlMask, XK_F4, toggleview, { .i = 3 } }, \ + { MODKEY|ControlMask, XK_F5, toggleview, { .i = 4 } }, \ + { MODKEY|ControlMask, XK_F6, toggleview, { .i = 5 } }, \ + { MODKEY|ControlMask, XK_F7, toggleview, { .i = 6 } }, \ + { MODKEY|ControlMask, XK_F8, toggleview, { .i = 7 } }, \ + { MODKEY|ControlMask, XK_F9, toggleview, { .i = 8 } }, \ + { MODKEY|ControlMask, XK_F10, toggleview, { .i = 9} }, \ + { MODKEY|ControlMask, XK_F11, toggleview, { .i = 10 } }, \ + { MODKEY|ControlMask, XK_F12, toggleview, { .i = 11} }, \ { MODKEY|ShiftMask, XK_q, quit, { 0 } }, \ + { MODKEY|ControlMask, XK_n, adjustnumbercols, { .i=1 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_n, adjustnumbercols, { .i=-1 } }, \ + { MODKEY, XK_n, adjustcoltypes, { .i=1 } }, \ + { MODKEY|ShiftMask, XK_n, adjustcoltypes, { .i=-1 } }, \ + { MODKEY, XK_s, sortallbytitle, { 0 } }, \ + { MODKEY, XK_p, setAndJump, { .i=1 } }, \ + { MODKEY|ShiftMask, XK_p, unsetAndJump, { .i=-1 } }, \ + { MODKEY|ControlMask, XK_p, setwithnexttag, { .i=1 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_p, zapcurrenttag, { .i=-1 } }, \ + { MODKEY, XK_o, setAndJump, { .i=-1 } }, \ + { MODKEY|ShiftMask, XK_o, unsetAndJump, { .i=1 } }, \ + { MODKEY|ControlMask, XK_o, setwithnexttag, { .i=-1 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_o, zapcurrenttag, { .i=1 } }, \ + { MODKEY, XK_space, movewrtcurrenttag, { .i=1 } }, \ + { MODKEY|ShiftMask, XK_space, movewrtcurrenttag, { .i=-1 } }, \ + { MODKEY|ControlMask, XK_space, pushAllClients, { .i=1 } }, \ + { MODKEY|ControlMask|ShiftMask, XK_space, pushAllClients, { .i=-1 } }, \ + { MODKEY, XK_l, popcurrenttag, { 0 } }, \ + { MODKEY, XK_1, moveToPosn, {.i=1} },\ + { MODKEY, XK_2, moveToPosn, {.i=2} },\ + { MODKEY, XK_3, moveToPosn, {.i=3} },\ + { MODKEY, XK_4, moveToPosn, {.i=4} },\ + { MODKEY, XK_5, moveToPosn, {.i=5} },\ + { MODKEY, XK_6, moveToPosn, {.i=6} },\ + { MODKEY, XK_7, moveToPosn, {.i=7} },\ + { MODKEY, XK_8, moveToPosn, {.i=8} },\ + { MODKEY, XK_9, moveToPosn, {.i=9} },\ + { MODKEY, XK_0, moveToPosn, {.i=10} }\ }; +static const char* const respectAspectRatio[]={"xine","XVroot"}; + /* Query class:instance:title for regex matching info with following command: * xprop | awk -F '"' '/^WM_CLASS/ { printf("%s:%s:",$4,$2) }; /^WM_NAME/ { printf("%s\n",$2) }' */ #define RULES \ static Rule rule[] = { \ /* class:instance:title regex tags regex isfloat */ \ - { "Firefox.*", "2", False }, \ + { "Firefox.*", "^2$", False }, \ { "Gimp.*", NULL, True }, \ }; diff -u dwm-2.1/config.mk dwm-2.1.throwaway/config.mk --- dwm-2.1/config.mk 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/config.mk 2006-11-07 03:01:34.000000000 +0000 @@ -8,17 +8,17 @@ MANPREFIX = ${PREFIX}/share/man X11INC = /usr/X11R6/include -X11LIB = /usr/X11R6/lib +X11LIB = /usr/X11R6/lib64 # includes and libs INCS = -I. -I/usr/include -I${X11INC} LIBS = -L/usr/lib -lc -L${X11LIB} -lX11 # flags -CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" -LDFLAGS = ${LIBS} -#CFLAGS = -g -Wall -O2 ${INCS} -DVERSION=\"${VERSION}\" -#LDFLAGS = -g ${LIBS} +#CFLAGS = -Os ${INCS} -DVERSION=\"${VERSION}\" +#LDFLAGS = ${LIBS} +CFLAGS = -g -Wall ${INCS} -DVERSION=\"${VERSION}\" +LDFLAGS = -g ${LIBS} # compiler and linker CC = cc diff -u dwm-2.1/draw.c dwm-2.1.throwaway/draw.c --- dwm-2.1/draw.c 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/draw.c 2006-11-07 03:01:34.000000000 +0000 @@ -20,7 +20,8 @@ } static void -drawtext(const char *text, unsigned long col[ColLast], Bool highlight) { +drawtext(const char *text, unsigned long col[ColLast], Bool highlight, +Bool highlight2) { int x, y, w, h; static char buf[256]; unsigned int len, olen; @@ -69,6 +70,12 @@ r.width = r.height = (h + 2) / 4; XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); } + if(highlight2) { + r.width = r.height = (h+2)/4; + r.x = dc.x + dc.w -r.width - 2; + r.y = dc.y + dc.h -r.height- 2; + XFillRectangles(dpy, dc.drawable, dc.gc, &r, 1); + } } /* extern */ @@ -82,21 +89,39 @@ drawstatus(); } +static Bool occupiedTags[23]; + +void +figureTagsSet() +{ + Client *c; + int i; + for(i=0;inext){ + for(i=0;itags[i]; + } + } +} + void drawstatus(void) { int i, x; dc.x = dc.y = 0; + figureTagsSet(); for(i = 0; i < ntags; i++) { dc.w = textw(tags[i]); if(seltag[i]) - drawtext(tags[i], dc.sel, sel && sel->tags[i]); + drawtext(tags[i], dc.sel, sel && sel->tags[i],occupiedTags[i]); else - drawtext(tags[i], dc.norm, sel && sel->tags[i]); + drawtext(tags[i], dc.norm, sel && sel->tags[i],occupiedTags[i]); dc.x += dc.w; } dc.w = bmw; - drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False); + drawtext(arrange == dofloat ? FLOATSYMBOL : TILESYMBOL, dc.status, False,False); x = dc.x + dc.w; dc.w = textw(stext); dc.x = bx + bw - dc.w; @@ -104,13 +129,13 @@ dc.x = x; dc.w = bw - x; } - drawtext(stext, dc.status, False); + drawtext(stext, dc.status, False, False); if((dc.w = dc.x - x) > bh) { dc.x = x; if(sel) - drawtext(sel->name, dc.sel, False); + drawtext(sel->name, dc.sel, False, False); else - drawtext(NULL, dc.norm, False); + drawtext(NULL, dc.norm, False, False); } XCopyArea(dpy, dc.drawable, barwin, dc.gc, 0, 0, bw, bh, 0, 0); XSync(dpy, False); @@ -128,7 +153,7 @@ XMapWindow(dpy, c->twin); dc.x = dc.y = 0; dc.w = c->tw; - drawtext(c->name, dc.norm, False); + drawtext(c->name, dc.norm, False, False); XCopyArea(dpy, dc.drawable, c->twin, dc.gc, 0, 0, c->tw, c->th, 0, 0); XSync(dpy, False); } diff -u dwm-2.1/dwm.h dwm-2.1.throwaway/dwm.h --- dwm-2.1/dwm.h 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/dwm.h 2006-11-07 06:14:35.000000000 +0000 @@ -37,7 +37,7 @@ /* mask shorthands, used in event.c and client.c */ #define BUTTONMASK (ButtonPressMask | ButtonReleaseMask) /* other stuff used in different places */ -#define BORDERPX 1 +#define BORDERPX 2 #define PROTODELWIN 1 enum { NetSupported, NetWMName, NetLast }; /* EWMH atoms */ @@ -83,6 +83,7 @@ int grav; long flags; unsigned int border, weight; + double aspectRatio;/*set to -1.0 for unset, otherwise set directly*/ Bool isfloat, isfixed, ismax; Bool *tags; Client *next; @@ -92,6 +93,19 @@ Window twin; }; +static +inline +int +clamp(int x,int lo,int hi) +{ + if(xhi){ + return hi; + } + return x; +} + extern const char *tags[]; /* all tags */ extern char stext[1024]; /* status text */ extern int bx, by, bw, bh, bmw; /* bar geometry, bar mode label width */ @@ -147,6 +161,14 @@ extern void settags(Client *c, Client *trans); /* sets tags of c */ extern void tag(Arg *arg); /* tags c with arg's index */ extern void toggletag(Arg *arg); /* toggles c tags with arg's index */ +extern void setwithnexttag(Arg *arg); /* set highestTag+arg->i on client */ +extern void popcurrenttag(Arg *arg); /* unset highestTag+arg->i on client */ +extern void movewrtcurrenttag(Arg *arg); /*deselect highestTag & select highestTag+arg->i */ +extern void zapcurrenttag(Arg *arg); /* unset highestTag from all clients (if possible) */ +extern void setAndJump(Arg *arg); /* set highestTag+arg->i on client and move to it*/ +extern void unsetAndJump(Arg *arg); /* unset highestTag on client & move to highestTag+arg->i */ +extern void pushAllClients(Arg *arg); /*apply highestTag+arg->i to all clients */ +extern int highestTagUsed(); /* util.c */ extern void *emallocz(unsigned int size); /* allocates zero-initialized memory, exits on error */ @@ -168,3 +190,7 @@ extern void view(Arg *arg); /* views the tag with arg's index */ extern void viewall(Arg *arg); /* views all tags, arg is ignored */ extern void zoom(Arg *arg); /* zooms the focused client to master area, arg is ignored */ +extern void adjustnumbercols(Arg *arg); /* change number of columns */ +extern void adjustcoltypes(Arg *arg); /* increment/decrement number of full columns */ +extern void sortallbytitle(Arg *arg); /*sort all clients in title order */ +extern void moveToPosn(Arg *arg); /* put client at position arg->i (restrictions) */ diff -u dwm-2.1/event.c dwm-2.1.throwaway/event.c --- dwm-2.1/event.c 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/event.c 2006-11-07 06:14:33.000000000 +0000 @@ -173,6 +173,10 @@ if(ev->value_mask & CWBorderWidth) c->border = ev->border_width; gravitate(c, False); + /*subtle: no aspect ratio change can set aspectRatio<=0 (yes?)*/ + if(c->aspectRatio>0 && (ev->value_mask & CWWidth) && (ev->value_mask & CWHeight)){ + c->aspectRatio=(double)ev->height/(double)ev->width; + } wc.x = c->x; wc.y = c->y; wc.width = c->w; diff -u dwm-2.1/tag.c dwm-2.1.throwaway/tag.c --- dwm-2.1/tag.c 2006-11-02 09:18:01.000000000 +0000 +++ dwm-2.1.throwaway/tag.c 2006-11-07 03:01:34.000000000 +0000 @@ -133,3 +133,125 @@ sel->weight = (i == ntags) ? arg->i : i; arrange(); } + +/* begin changes and additions */ + +/* find the highest currently viewed tag */ +int +highestTagUsed() +{ + int i; + for(i=ntags-1;i>=0;--i){ + if(seltag[i]){ + return i; + } + } + return 0; /*should never happen*/ +} + +/*take care of updating the weight*/ +void +flipTag(Client *c,int idx) +{ + c->tags[idx]=True; + if(idxweight){ + c->weight=idx; + } +} + +void +setwithnexttag(Arg *arg) +{ + if(sel){ + flipTag(sel,clamp(highestTagUsed()+arg->i,0,ntags-1)); + arrange(); + } +} + +void +pushAllClients(Arg *arg) +{ + int hiTag=highestTagUsed(),toSet=hiTag+arg->i; + if(toSet>=0 && toSetnext) { + if(c->tags[hiTag]){/* prevent potentially much pointless work */ + flipTag(c,toSet); + } + } + movewrtcurrenttag(arg); + } +} + +void +setAndJump(Arg *arg) +{ + /* arg->i is +/-1*/ + setwithnexttag(arg); + movewrtcurrenttag(arg); +} + +void +unsetAndJump(Arg *arg) +{ + /* arg->i is +/-1*/ + popcurrenttag(arg); + movewrtcurrenttag(arg); +} + +Bool +unsetspecifiedtag(Client *c,int toZap) +{ + int i; + c->tags[toZap]=False; + for(i = 0; i < ntags && !c->tags[i]; i++) /*do nothing*/; + + if(i == ntags){ /* oops: wiped out last tag */ + c->tags[toZap] = True; + c->weight=toZap; + return False; + }else{ + c->weight=i; + return True; + } +} + +void +popcurrenttag(Arg *arg) +{ + if(sel && unsetspecifiedtag(sel,highestTagUsed())){ + arrange(); + } +} + +void +movewrtcurrenttag(Arg *arg) +{ + int curTag=highestTagUsed(); + if(arg && (arg->i!=1 || curTag!=ntags-1) && (arg->i!=-1 || curTag!=0)){ + seltag[curTag]=False; + seltag[curTag+arg->i]=True; + arrange(); + } +} + +void +zapcurrenttag(Arg *arg) +{ + /* require arg.i=+/- 1 */ + Client *c; + int toZap=highestTagUsed(); + Bool ok=True; + for(c = clients; c; c = c->next) { + if(c->tags[toZap]){/* prevent potentially much pointless work */ + ok=ok && unsetspecifiedtag(c,toZap); + } + } + int dest=toZap+arg->i; + if(ok && dest>=0 && desti!=1 || noColsArr[tg]i!=-1 || noColsArr[tg]>1)){ + noColsArr[tg]+=arg->i; + noStackColsArr[tg]=noColsArr[tg]-1; + arrange(); + } +} + +/* change the balance between number of full and stacked columns */ +void +adjustcoltypes(Arg *arg) +{ + int tg=highestTagUsed(); + if(arg && (arg->i!=1 || noStackColsArr[tg]>0) && (arg->i!=-1 || noStackColsArr[tg]i; + arrange(); + } +} + +typedef struct ARCrec { + int idx;/*order position in _visible_ clients*/ + int height; + Client *c; +} ARCrec; + +/***************************************************************************** + * formulae should now be correct for arbitrary NO_MONITORS + * first build width/height tables, then fill them rather than merge two + * into combined code to ease future experiments + * + * all per-column arrays are now indexed from 1 up (rather than 0) + * + * term ARC: Aspect Ratio Constrained + * TODO: + *really rethink the aspect ratio stuff + * + ****************************************************************************/ +void +dotile(void) +{ + int n,i,j,tg=highestTagUsed(); + Client *c; + int noCols=noColsArr[tg],noStackCols=noStackColsArr[tg]; + ARCrec arcs[32]; + int arcTop=0; + for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)){ + if(c->aspectRatio>0.1){/*silly threshold*/ + arcs[arcTop].idx=n; + arcs[arcTop].c=c; + ++arcTop; + } + n++; + } + int noStackColsP=noStackCols; /* no stacks we'll actually use this time */ + int noInSCols=n-(noCols-noStackColsP); /* no clients in stack cols */ + int nP = clamp(n,1,noCols); /* no cols actually used on this view */ + while(!(noInSCols*bh <= (sh-bh)*noStackColsP) && noInSCols>0){ /* inc stack cols until fits */ + ++noStackColsP; + noInSCols=n-(noCols-noStackColsP); + } + Bool useNonTrivialCols=noStackColsP>0 && n >= noCols + && noInSCols*bh <= (sh-2*bh)*noStackColsP; /* got enough height for at least titles? */ + int colEndOn[MAX_COLS+1],heights[MAX_COLS+1],widths[MAX_COLS+1]; + int crossCol=nP-(nP%NO_MONITORS)*((nP/NO_MONITORS)+1); + int noOfShortCols = noCols - noInSCols%noStackColsP; /* x%0==0 as desired */ + /* build tables of essential layout parameters */ + colEndOn[0]=-1; + for(i = 1; i <= nP; ++i){ + int div=nP; + if(NO_MONITORS>1 && nP%NO_MONITORS!=0 && nP>1){ + div+=(i>crossCol?NO_MONITORS:0)-1; + } + widths[i]=sw/div;//set width _before_ possible aspect ratio clients + if(useNonTrivialCols && i>noCols-noStackColsP){ + int origNo = noInSCols/noStackColsP + (i>noOfShortCols?1:0); /* no clients in this col */ + int no=origNo; /* becomes no "normal" clients in this col */ + int normClientHgt=sh-bh;/*height available for normal clients*/ + colEndOn[i] = no + colEndOn[i-1];/* col i finishes on this client */ + /* scan clients appearing in this column for aspect ratio constrained clients */ + for(j=0;jaspectRatio) + +1+2*BORDERPX;//avoid ceil() & account for border + normClientHgt-=arcs[j].height; + --no; + } + } + if(normClientHgt0?origNo:1); + for(j=0;j0?no:1); + } + }else{ + colEndOn[i] = i-1; + heights[i] = sh-bh;/* default to every column full height */ + } + } + colEndOn[nP]=n-1; /* ensure final column ends with last client*/ + /* use tables to assign actual client positions in layout */ + int colNo = 1, cumHgt = sy + bh, cumWid=0, arcIdx=0; + for(i = 0, c = clients; c; c = c->next) { + if(isvisible(c)) { + if(c->isfloat) { + resize(c, True, TopLeft); + continue; + } + c->ismax = False; + c->x = cumWid; + c->y = cumHgt; + c->w = widths[colNo]-2*BORDERPX; + Bool arClient=(c==arcs[arcIdx].c); + c->h = (arClient?arcs[arcIdx++].height:heights[colNo]); + if(i == colEndOn[colNo]){ /* next client starts a new column */ + if(!arClient){ + c->h = sh - c->y; /* soak up rounding down error pixels */ + } + cumWid+=widths[colNo++]; + cumHgt = sy + bh; + }else if(useNonTrivialCols){ + cumHgt += c->h; + } + c->h-=2*BORDERPX;/*do AFTER cumulative height calc*/ + resize(c, False, TopLeft); + i++; + } + else + ban(c); + } + if(!sel || !isvisible(sel)) { + for(c = stack; c && !isvisible(c); c = c->snext); + focus(c); + } + restack(); +} - for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) - n++; - mpx = (sw * master) / 1000; - stackw = sw - mpx; - stackh = sh - bh; - th = stackh; - if(n > 1) - th /= (n - 1); +static Client * +minname() +{ + Client *c, *min; - for(i = 0, c = clients; c; c = c->next) - if(isvisible(c)) { - if(c->isfloat) { - resize(c, True, TopLeft); - continue; - } - c->ismax = False; - c->x = sx; - c->y = sy + bh; - if(n == 1) { /* only 1 window */ - c->w = sw - 2 * BORDERPX; - c->h = sh - 2 * BORDERPX - bh; - } - else if(i == 0) { /* master window */ - c->w = mpx - 2 * BORDERPX; - c->h = sh - bh - 2 * BORDERPX; - } - else { /* tile window */ - c->x += mpx; - c->w = stackw - 2 * BORDERPX; - if(th > bh) { - c->y = sy + (i - 1) * th + bh; - if(i + 1 == n) - c->h = sh - c->y - 2 * BORDERPX; - else - c->h = th - 2 * BORDERPX; - } - else /* fallback if th < bh */ - c->h = stackh - 2 * BORDERPX; - } - resize(c, False, TopLeft); - i++; - } - else - ban(c); + if((clients && clients->isfloat) || arrange == dofloat) + return clients; /* don't touch floating order */ + for(min = c = clients; c; c = c->next) + if(c->weight < min->weight + || (c->weight == min->weight && strncasecmp(c->name,min->name,sizeof(c->name))<0)) + min = c; + return min; +} - if(!sel || !isvisible(sel)) { - for(c = stack; c && !isvisible(c); c = c->snext); - focus(c); - } - restack(); +/* sort all the clients (whether displayed or not) by title */ +void +sortallbytitle(Arg *arg) +{ + reorder(&minname); + arrange(); +} + +//precondition: arg must have .i set to integer >=1 +//something is still a bit flakey here +void +moveToPosn(Arg *arg) +{ + unsigned int n; + Client *c,*d=0;//we'll re-insert just after client d + int seenSel=0; + if(arg->i==0 || !sel || !clients || sel->isfloat || arrange!=dotile){ + return; + } + for(n = 0, c = clients; c; c = c->next){ + if(isvisible(c) && !c->isfloat){ + if(c==sel){ + seenSel=1; + }else if(n==arg->i-1+seenSel){ + d=c; + } + n++; + } + } + c=sel; + if(!d || c==d){//situation we can't/shouldn't deal with + return; + } + detach(c); + c->next=d->next; + c->prev=d; + c->prev->next=c; + if(c->next){ + c->next->prev=c; + } + focus(c); + arrange(); } +/* end changes and additions */ + + void focusnext(Arg *arg) { Client *c; @@ -249,7 +405,7 @@ for(i = 0; i < ntags && !seltag[i]; i++); if(i == ntags) seltag[arg->i] = True; /* cannot toggle last view */ - reorder(); + reorder(&minclient); arrange(); } @@ -260,7 +416,7 @@ for(i = 0; i < ntags; i++) seltag[i] = False; seltag[arg->i] = True; - reorder(); + reorder(&minclient); arrange(); } @@ -270,7 +426,7 @@ for(i = 0; i < ntags; i++) seltag[i] = True; - reorder(); + reorder(&minclient); arrange(); }