[dwm] small dwm tile() patch
I grabbed the latest dwm earlier to port various bits of my own into clean patches against the latest dwm. I hadn't looked at the standard tile function for a little while, but I notice that the current incarnation recalculates the window geometries (mw and th) for each client rather than once in front of the client loop. hg bisect says this started happening at changeset 1072:5a06b4b69479 when the Xinerama work began. Obviously mw and th are different from monitor to monitor, but within a monitor they're constant, so I think the following (trivial) patch is correct: diff --git a/dwm.c b/dwm.c --- a/dwm.c +++ b/dwm.c @@ -1689,12 +1689,13 @@ tile(void) { for(n = 0, c = nexttiled(clients, m); c; c = nexttiled(c-next, m)) n++; + /* window geoms */ + mw = (n == 1) ? m-waw : m-mwfact * m-waw; + th = (n 1) ? m-wah / (n - 1) : 0; + if(n 1 th bh) + th = m-wah; + for(j = 0, c = mc = nexttiled(clients, m); c; c = nexttiled(c-next, m)) { - /* window geoms */ - mw = (n == 1) ? m-waw : m-mwfact * m-waw; - th = (n 1) ? m-wah / (n - 1) : 0; - if(n 1 th bh) - th = m-wah; if(j == 0) { /* master */ nx = m-wax; ny = m-way; Best wishes, Chris.
Re: [dwm] dzen replacing dwm status bar
Anselm R. Garbe [EMAIL PROTECTED] writes: [Re: embedded windows] I'd like to keep this complexity out of dwm. I really think to provide a more flexible way to change the bar position and geometry. One simple solution that might be sufficient: here I have two gaps defined, a top gap and a bottom gap. During the geometry setup, I add the top gap to sy and subtract (top gap + bottom gap) from sh. I guess if one could limit the dwm bar to a fraction of the width of the screen, there would also be space to the right or left of that for something like a dzen. Best wishes, Chris.
Re: [dwm] Xinerama support
pancake [EMAIL PROTECTED] writes: This way you can achieve any of the possibilities (show the same client in both monitors, move a window from one to another, etc.. X doesn't give you a mechanism for showing the same client on both monitors. Best wishes, Chris.
Re: [dwm] dwm wish, a tidy-up function
Sander van Dijk [EMAIL PROTECTED] writes: On Dec 6, 2007 11:23 AM, Anselm R. Garbe [EMAIL PROTECTED] wrote: Ok, but the DWMTAGS idea is ok for everyone? Would that work? If the new dwm is a child of the old one it would, but when the dwm restart is controlled by a shell loop such as while true do dwm done I believe this wouldn't work, right? If dwm were to produce the list of selected tags on stdout on exit and could accept a list of tags as arguments on startup, this would allow a 'restart by quit' without losing the selected tags and without requiring a special 'quit and exec' function. Also, if the point of a restart is just to retag windows according to the rules, wouldn't it be cleaner to implement just that rather than a full re-exec? Best wishes, Chris.
Re: [dwm] input status text bug?
Anselm R. Garbe [EMAIL PROTECTED] writes: If we decide for line-based input reading, one easily could block dwm from further event processing through running echo -n foo | dwm I think that'd be a big disadvantage. It could append read text to the end of stext[] whenever it successfully reads(), except that the first character after a '\n' clears stext[] and starts a new status. It needn't block. Best wishes, Chris.
Re: [dwm] Taglayouts poll
Kai Grossjohann [EMAIL PROTECTED] writes: On Fri, Oct 26, 2007 at 05:09:06PM +0100, Chris Webb wrote: One completely different approach to implementing multiple layouts in a pure tagging context is to introduce a new layout index, completely independent of the tag toggles. In the same way you can view() or toggleview() a tag at present, you could select() by index a particular set of layout parameters. You'd need to display the selected layout as well as the selected tags in the status bar, or it would rapidly become very confusing. This would be interesting to try and I confess I haven't tried it. However, I suspect in my normal usage it would just replace one keystroke with two. I think you can have one key execute two actions, by adding two lines for the same key into the keybindings. Then folks who like it can bind keys that do view() followed by select(). While we're examining the solution space, I'll point out that it's a small step from doing this sort of layout indexing to completely replacing the single workspace with multiple workspaces. Windows would belong to tags as in standard dwm, each workspace having a set of selected tags (not necessary disjoint) as well as their own independent layout and parameters. Finally, a status bar of the form WORKSPACES LAYOUT TAGS TITLE MESSAGE would be needed, rather than dwm's TAGS LAYOUT TITLE MESSAGE One might then switch between different workspaces for different jobs, and mix in and out tags full of windows within a particular job. Initialisation is an issue here: what tags are present in each workspace at startup? Just the first tag in each? Just tag i % k in workspace i? There's no canonical choice as far as I can see, which is untidy. Cheers, Chris.
Re: [dwm] Taglayouts poll
Sander van Dijk [EMAIL PROTECTED] writes: No, it shouldn't, for the simple reason that it doesn't fit within the tagging paradigm. You're right, it doesn't really. I would characterise this patch (and variants such as the one I use) as changing the underlying paradigm from pure tagging to something closer to traditional workspaces. In addition to the unordered set of selected tags, the patch leads to one tag being distinguished as the 'main' selected tag. This main tag is then used to index the layouts, regardless of the other selected tags. One way to view this is that the 'main' tag, reset by view(), is the current workspace, and that toggleview() allows you to temporarily mix in the windows from other workspaces using the current workspace's layout. In my personal dwm derivative, I even color the main selected tag and additional mixed-in tags differently in the status bar to emphasise their different status. This is a more complicated model than pure tagging. Conceptually, the tagging model is simpler and neater---more dwm-like in fact. I doubt this fits well into upstream dwm. However, when I came to put together and use a working environment based upon dwm, and particularly as I added a couple more layouts and extended tile() to be more flexible, I discovered that having a single layout into which I could choose sets of windows to drop felt significantly less convenient to me than multiple layouts on multiple workspaces. view() tag A, set up layout suitable for task A; view() tag B, set up layout suitable for task B; return to viewing tag A, reset layout for task A... is a pattern that was begging to be optimised away. Clearly YMMV. Incidentally, something else needed for consistency when implementing taglayouts-type behaviour is to index all the layout parameters like mwfact, nmaster (if you have it) and nstack/ncols/nrows (if you have any of them). I don't think this patch currently does this? Hence, to do this taglayouts stuff right One completely different approach to implementing multiple layouts in a pure tagging context is to introduce a new layout index, completely independent of the tag toggles. In the same way you can view() or toggleview() a tag at present, you could select() by index a particular set of layout parameters. You'd need to display the selected layout as well as the selected tags in the status bar, or it would rapidly become very confusing. This would be interesting to try and I confess I haven't tried it. However, I suspect in my normal usage it would just replace one keystroke with two. Cheers, Chris.
Re: [dwm] Taglayouts poll
Jan Christoph Ebersbach [EMAIL PROTECTED] writes: On Fri 26-10-2007 17:09 +0100, Chris Webb wrote: Incidentally, something else needed for consistency when implementing taglayouts-type behaviour is to index all the layout parameters like mwfact, nmaster (if you have it) and nstack/ncols/nrows (if you have any of them). I don't think this patch currently does this? You are right, the patch doesn't do this at the moment and it's one thing that I really miss. As far as I remember, it's sufficient to replace the definition of mwfact with double mwfact[NTAGS]; add for (i = 0; i NTAGS; i++) mwfact[i] = MWFACT; into setup() (or preferably put the mwfact initialisation into the ltidx loop), insert a free(mwfact); into cleanup() and replace mwfact by mwfact[csel] everywhere else. Cheers, Chris.
Re: [dwm] Taglayouts poll
Chris Webb [EMAIL PROTECTED] writes: insert a free(mwfact); into cleanup() You don't need this bit with a static mwfact[NTAGS] of course. D'oh. Edited my email after writing to reflect the fact that dwm has gone static but didn't delete the unnecessary free(). Best wishes, Chris.
Re: [dwm] idxoftag
Isn't the fundamental problem with all this that you are assuming that tags are named by their number. You can't do this in the more general case where you have tags like 'www' or 'scratchpad'. Best wishes, Chris.
Re: [dwm] RESIZEHINTS broken?
Anselm R. Garbe [EMAIL PROTECTED] writes: Agreed, I will change the resize code accordingly. So RESIZEHINTS will be renamed to INCRESIZE or something like that. I think the situation is slightly more complex than this. You want full size hint support (including hints that enlarge the window beyond the requested size) for floating windows and in floating mode, whereas you want restricted size hint support (disallowing growth of a window beyond requested dimensions) in tiling modes. The sizehints argument to resize() probably therefore needs to be a tri-state. Best wishes, Chris.
Re: [dwm] idxoftag
Stefano Soffia [EMAIL PROTECTED] writes: I do not understand what you mean with `more general case'. Note that currently, the idxoftag() function performs a comparison between pointers not between strings. Ah, I've just spotted what you're doing: it's not actually what I thought you were doing. Please ignore my comment. Best wishes, Chris.
Re: [dwm] setmwfact bug
Szabolcs Nagy [EMAIL PROTECTED] writes: there's a typo in in dwm.c in setmwfact(): ... else if(1 == sscanf(arg, %lf, delta)) { if(arg[0] == '+' || arg[0] == '-') mwfact += delta; else mwfact = delta; // should be -= ... } I don't think it should be. The current behaviour is that setmwfact(+0.1) adds 0.1 to mwfact, setmwfact(-0.1) subtracts 0.1 from mwfact, and setmwfact(0.1) sets mwfact equal to 0.1. Your =- would make setmwfact(0.1) equivalent to setmwfact(-0.1). Cheers, hrus.
Re: [dwm] improved tile()
Anselm R. Garbe [EMAIL PROTECTED] writes: I know my English is totally crap, so excuse that. Anyway you describe the problem pretty well. No, your English is fine; it's my reading that's dodgy! :-) Cheers, Chris.
[dwm] [PATCH] An experiment with X resources
This morning I've been thinking about run time configuration of dwm. I've never especially liked the compile-time rules table in config.h. The fact that one or two programs I use happen to be broken and need a rule with isfloating = 1 doesn't seem like something that the dwm binary should be cluttered with. Clearly this is a matter of personal taste and your mileage will probably vary, but it definitely grates for me. I also have a couple of different screens and I'd like to be able to reconfigure fonts and colours (depending on the display dwm is managing) without keeping multiple dwm binaries in my home directory. As an experiment, I've added support for customisation with X resources in a branch of my own tree. To avoid growing the code too much, I completely replaced the hard-coded rules table with a dynamic one populated from X resources, but all other settings use config.h values as defaults. Key bindings remain a matter for config.h. As far as I can see, configuring these at runtime would introduce a big, ugly symbol table into dwm for little or no gain. Doing all this grows dwm.c less than I was originally expecting, as can be seen from the patch. Most of the extra code is involved with constructing the tag and rule lists rather than just to add simpler config options like fonts and colours. I've ported my patch back to upstream dwm (hg tip) and attached it at the end of this message in case anyone else on the list is interested in experimenting along the same lines. A sample .Xresources file to merge (use xrdb -merge/-load) might be: Dwm.bar: top Dwm.font: -*-terminus-medium-r-*-*-12-*-*-*-*-*-iso10646-* Dwm.normal.border: #cc Dwm.normal.background: #ff Dwm.normal.background: #00 Dwm.selected.border: #ff Dwm.selected.background: #ff Dwm.selected.foreground: #ff Dwm.tags: 1 2 3 4 5 6 7 8 9 Dwm.rules: scratchpad browser Dwm.properties.scratchpad: URxvt:scratch Dwm.floating.scratchpad: True Dwm.properties.browser: Opera Dwm.tags.browser: 2 Cheers, Chris. diff -r 92c19c929a59 config.def.h --- a/config.def.h Sun Sep 23 18:50:04 2007 +0200 +++ b/config.def.h Mon Sep 24 14:28:26 2007 +0100 @@ -1,4 +1,8 @@ /* See LICENSE file for copyright and license details. */ + +/* resources */ +#define RESNAMEdwm +#define RESCLASS Dwm /* appearance */ #define BARPOS BarTop /* BarBot, BarOff */ @@ -12,14 +16,7 @@ #define SELFGCOLOR #ff /* tagging */ -const char *tags[] = { 1, 2, 3, 4, 5, 6, 7, 8, www, NULL }; -Rule rules[] = { - /* class:instance:title regex tags regex isfloating */ - { Firefox,www, False }, - { Gimp, NULL, True }, - { MPlayer,NULL, True }, - { Acroread, NULL, True }, -}; +#define TAGS 1 2 3 4 5 6 7 8 9 /* layout(s) */ #define ISTILE isarrange(tile) /* || isarrange(custom) */ diff -r 92c19c929a59 dwm.c --- a/dwm.c Sun Sep 23 18:50:04 2007 +0200 +++ b/dwm.c Mon Sep 24 14:28:26 2007 +0100 @@ -40,6 +40,7 @@ #include X11/Xatom.h #include X11/Xlib.h #include X11/Xproto.h +#include X11/Xresource.h #include X11/Xutil.h /* macros */ @@ -132,6 +133,8 @@ void *emallocz(unsigned int size); void *emallocz(unsigned int size); void enternotify(XEvent *e); void eprint(const char *errstr, ...); +void *erealloc(void *res, unsigned int size); +char *estrdup(const char *s); void expose(XEvent *e); void floating(void); /* default floating layout */ void focus(Client *c); @@ -139,7 +142,10 @@ void focusprev(const char *arg); void focusprev(const char *arg); Client *getclient(Window w); unsigned long getcolor(const char *colstr); +char *getresource(const char *resource, char *defval); +void getrules(void); long getstate(Window w); +void gettags(void); Bool gettextprop(Window w, Atom atom, char *text, unsigned int size); void grabbuttons(Client *c, Bool focused); unsigned int idxoftag(const char *tag); @@ -190,11 +196,11 @@ void zoom(const char *arg); void zoom(const char *arg); /* variables */ -char stext[256]; +char stext[256], **tags; double mwfact; int screen, sx, sy, sw, sh, wax, way, waw, wah; int (*xerrorxlib)(Display *, XErrorEvent *); -unsigned int bh, bpos, ntags; +unsigned int bh, bpos, ntags = 0; unsigned int blw = 0; unsigned int ltidx = 0; /* default */ unsigned int nlayouts = 0; @@ -226,7 +232,9 @@ Display *dpy; Display *dpy; DC dc = {0}; Window barwin, root; +Rule *rules; Regs *regs = NULL; +XrmDatabase xrdb; /* configuration, allows nested code to access above variables */ #include config.h @@ -402,7 +410,6 @@ compileregs(void) { if(regs) return; - nrules = sizeof rules / sizeof rules[0]; regs = emallocz(nrules * sizeof(Regs)); for(i = 0; i nrules; i++) {
Re: [dwm] [PATCH] An experiment with X resources
Anselm R. Garbe [EMAIL PROTECTED] writes: The only questionable issue I don't like is the strsep(3) use, because of portability concerns. Failing all else, I guess a strsep() tokeniser while(tag = strsep(line, \t\n)) { if(!tag[0]) continue; tags = erealloc(tags, sizeof(char *) * ++ntags); tags[ntags - 1] = tag; } can always be expanded to something like this do { tag = line; if (line = strpbrk(line, \t\n)) *line++ = '\0'; if !tag[0] continue; tags = erealloc(tags, sizeof(char *) * ++ntags); tags[ntags - 1] = tag; } while (line); assuming strpbrk is reasonably universal. Cheers, Chris.
Re: [dwm] [PATCH] An experiment with X resources
Jukka Salmi [EMAIL PROTECTED] writes: Hmm, why using the ternary operator? Are there systems where `realloc(NULL, size)' does not behave identically to `malloc(size)'? I remember some old unix systems that segfault if you pass realloc a null pointer! I haven't seen anything like that for a long time, though, and I think ISO C now specifies that realloc(NULL, size) is the same as malloc(size), so I was probably just being over-paranoid. Cheers, Chris.
Re: [dwm] [PATCH] An experiment with X resources
Anselm R. Garbe [EMAIL PROTECTED] writes: it won't last long that the need arises to also configure the key bindings, and the terminal command, and the dmenu command, and what not using such capabilities. Actually... :-) What wasn't in that patch, but is in my tree, is a little convenience function that lets you define commands by name in .Xresources: Dwm.command.xterm: urxvt -bg red Dwm.command.browser: opera and then bind them in config.h Key keys[] = { [...] { MODKEY, XK_Return, spawn_command, xterm } { MODKEY | ShiftMask, XK_Return, spawn_command, browser } [...] } At present, my spawn_command is a no-op if the corresponding Dwm.command.* X resource isn't defined. Unfortunately, to do this requires that xrdb doesn't get freed at the end of setup(), so I need to rethink this a bit before I'll be happy with it. I also now configure my mwfact, nmaster, nrows and ncols parameters for my 'supertile()' through X resources. For me, this gives a sweet spot between runtime configurability and keeping code complexity low, with compiled-in key bindings which are constant across all the systems I use, but runtime configurable colours, rules, tag names and commands, which vary from system to system. I used X resources not because I think they're a nice system per se, but rather because I end up having to use them for other X apps anyway. I didn't fancy trying to express a rules table as a command line argument or environment variable! Besides this, the X resource file format always seemed insane to me. Yes, I agree. Many of the design choices in Xlib are baroque to the point of insanity. Cheers, Chris.
Re: [dwm] [patch] nmaster for dwm 4.5
Peter Hartlich [EMAIL PROTECTED] writes: Attached is Jeroen Schot's nmaster patch, ported to dwm (pre-)4.5 and with incnmaster() renamed setnmaster(). [...] void setnmaster(const char *arg) { int i; if(!isarrange(tile)) return; if(!arg) nmaster = NMASTER; else { i = atoi(arg); if((nmaster + i) 1 || wah / (nmaster + i) = 2 * BORDERPX) return; nmaster += i; } if(sel) arrange(); else drawbar(); } For setnmaster to behave consistently with setmwfact (which takes an absolute value or a delta beginning with + or -), you might prefer something like void setnmaster(const char *arg) { int i; if(!isarrange(tile)) return; if(!arg) nmaster = NMASTER; else { if(arg[0] != '+' arg[0] != '-') i = atoi(arg); else i = nmaster + atoi(arg); if(i 1 || wah / i = 2 * BORDERPX) return; nmaster = i; } if(sel) arrange(); else drawbar(); } Best wishes, Chris.
Re: [dwm] Unused space between clients
Xavier [EMAIL PROTECTED] writes: [rxvt-unicode] Previously, I had some weird corruptions at the place of this unused space. This only happened with urxvt though, not xterm. Not sure why.. But I'm happier with urxvt anyway. I've noticed this behaviour with urxvt when window size hints are being over-ruled by dwm. Terminals certainly do look much nicer in tiled mode when it does this, so it would be nice to fix urxvt to do the right thing. Sometimes after resizing, when the window is 'cleared', the bottom part line and/or rightmost part column doesn't clear, leading to the corruptions you describe. Another manifestation is that focus tinting doesn't properly affect the extra half line/column space at the bottom and right of a resized window. I wonder whether it would be easy to fix urxvt to 'round up' the area it refreshes instead of 'rounding down' when there are partial rows and columns... Best wishes, Chris.
Re: [dwm] [patch] Stack columns patch for dwm-4.4.1
pancake [EMAIL PROTECTED] writes: Here's my keybindings { MODKEY|ShiftMask, XK_l, setncols, +1 }, \ { MODKEY|ShiftMask, XK_h, setncols, -1 }, \ { MODKEY|ShiftMask, XK_j, setnmaster, +1 }, \ { MODKEY|ShiftMask, XK_k, setnmaster, -1 }, \ [I.e. interchanging the setncols and setnmaster keybindings.] Okay, if you think this a more natural extension of the default binding set, I'll pick this change up back into my own patch. My personal tree has diverged quite a bit, so in preparing a patch for others to use against stock dwm, I just copied the config.default.h bindings from the other nmaster patch out there, and added something by analogy rather than actually trying to live with the suggested extra keystrokes! Some tips: config.default.h: //#define NCOLS 1 /* maximum number of stacking area columns */ #define NCOLS 1 /* default number of stacking area columns */ Actually, I guess it's the 'default limit to the number of stacking area columns', as the code won't create ncols columns unless there are enough windows (more than (ncols - 1)*nrows) to fill them. The i 0 condition has been changed to i 1 to avoid strange situations. The ncols setting of zero is intentional, creating as many columns as required without limit to give exactly nrows clients per row. Maybe you're right that it isn't especially useful and just adds confusion: it's indistinguishable from ncols 1 for practical purposes. Originally, my tile() had no ncols limit, and so I needed an nrows of zero to get the default behaviour of an unlimited number of clients stacked in a single column. Now I agree, this is less confusingly achieved by setting ncols = 1, so nrows = 0 can go away. Removing these two special cases will also simplify a couple of tests in tile(), which is no bad thing! You can check this code here: http://news.nopcode.org/pvcroot/dwm-4.4.1-pancake.tar.gz Glancing through, I notice you've merged in the incnmaster function as well as my very similar setnmaster function. setnmaster is a superset of incnmaster, so you probably don't want to also carry the additional code weight of the latter. The bstack code could do with supporting the same set of possibilities as my extended tile. I'll take a look at allowing the master area to be either above or to the left of the stacking area in my tiling code, and define two layout functions with the common code pulled out to share. (I really need to update my personal tree to descend from the single dwm.c in hg tip in any case.) Cheers, Chris.
[dwm] [patch] Stack columns patch for dwm-4.4.1
Below is a patch for the current release (4.4.1) of dwm which enables multiple columns in the stacking area. It introduces variables nrows and ncols with corresponding default values NROWS and NCOLS in config.h.default, and corresponding setnrows() and setncols() for use in keybindings. If nrows == ncols == 0, tile() behaves in the normal manner. When nrows 0, tile() creates an extra column if adding another window to the current one would cause it to exceed nrows clients. If ncols 0, the maximum number of columns created cannot exceed ncols, overriding the nrows setting. The patch also reintroduces nmaster in a similar way to the existing nmaster patch, but allows it to be zero to simulate a grid mode. Where there are not enough windows to fill all the columns evenly, the extra space is used by the top-most client in the first column. I'd be interested in any feedback. (I use this 'extended tiling' mode myself, and so intend to maintain the patch going forward.) Best wishes, Chris. diff -uNrd dwm-4.4.1.orig/config.default.h dwm-4.4.1/config.default.h --- dwm-4.4.1.orig/config.default.h 2007-08-26 11:53:49.0 +0100 +++ dwm-4.4.1/config.default.h 2007-09-09 16:35:23.0 +0100 @@ -33,6 +33,9 @@ { ,floating }, \ }; #define MWFACT 0.6 /* master width factor [0.1 .. 0.9] */ +#define NMASTER1 /* clients in master area */ +#define NROWS 2 /* clients per column in stacking area */ +#define NCOLS 3 /* maximum number of stacking area columns */ #define SNAP 32 /* snap pixel */ /* key definitions */ @@ -48,6 +51,12 @@ { MODKEY, XK_k, focusprev, NULL }, \ { MODKEY, XK_h, setmwfact, -0.05 }, \ { MODKEY, XK_l, setmwfact, +0.05 }, \ + { MODKEY|ShiftMask, XK_j, setnrows, -1 }, \ + { MODKEY|ShiftMask, XK_k, setnrows, +1 }, \ + { MODKEY|ControlMask, XK_j, setncols, -1 }, \ + { MODKEY|ControlMask, XK_k, setncols, +1 }, \ + { MODKEY|ShiftMask, XK_h, setnmaster, -1 }, \ + { MODKEY|ShiftMask, XK_l, setnmaster, +1 }, \ { MODKEY, XK_m, togglemax, NULL }, \ { MODKEY, XK_Return, zoom, NULL }, \ { MODKEY|ShiftMask, XK_space, togglefloating, NULL }, \ diff -uNrd dwm-4.4.1.orig/tile.c dwm-4.4.1/tile.c --- dwm-4.4.1.orig/tile.c 2007-08-26 11:53:49.0 +0100 +++ dwm-4.4.1/tile.c2007-09-09 16:34:17.0 +0100 @@ -5,10 +5,82 @@ /* static */ static double mwfact = MWFACT; +static unsigned int nmaster = NMASTER; +static unsigned int nrows = NROWS; +static unsigned int ncols = NCOLS; /* extern */ void +setnmaster(const char *arg) { + int i; + + if(!isarrange(tile)) + return; + if(!arg) + i = NMASTER; + else if(arg[0] != '+' arg[0] != '-') + i = atoi(arg); + else + i = nmaster + atoi(arg); + + if(i 0 || wah = 2 * BORDERPX * i) + return; + + nmaster = i; + if(sel) + arrange(); + else + drawstatus(); +} + +void +setnrows(const char *arg) { + int i; + + if(!isarrange(tile)) + return; + if(!arg) + i = NROWS; + else if(arg[0] != '+' arg[0] != '-') + i = atoi(arg); + else + i = nrows + atoi(arg); + + if(i 0 || wah = 2 * BORDERPX * i) + return; + nrows = i; + + if(sel) + arrange(); + else + drawstatus(); +} + +void +setncols(const char *arg) { + int i; + + if(!isarrange(tile)) + return; + if(!arg) + i = NCOLS; + else if(arg[0] != '+' arg[0] != '-') + i = atoi(arg); + else + i = ncols + atoi(arg); + + if((i 0) || (i = 1 waw / i = 2 * BORDERPX)) + return; + ncols = i; + + if(sel) + arrange(); + else + drawstatus(); +} + +void setmwfact(const char *arg) { double delta; @@ -32,40 +104,79 @@ void tile(void) { - unsigned int i, n, nx, ny, nw, nh, mw, th; + unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, tw1, cols, rows, rows1; Client *c; for(n = 0, c = nexttiled(clients); c; c = nexttiled(c-next)) n++; + /* calculate correct number of rows */ + if(ncols 0 n - nmaster nrows * ncols) + rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 :