sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

nmaster-4.7.c (10211B)


      1 #if 0
      2 
      3 TITLE
      4 -----
      5  descrp:  ntile/tilecols layouts with clientspertag for dwm-4.7
      6  author:  pancake <youterm.com>
      7  update:  2007-12-01
      8 
      9 
     10 CONFIGURATION
     11 -------------
     12  You should modify your config.h to include "nmaster.c" AFTER setting
     13  the NMASTER, NCOLS, NROWS, BORDERPX, and RESIZEHINTS macro definitions
     14  and BEFORE the layouts definition.
     15 
     16  A sample configuration with ntile will be:
     17 
     18    #define NMASTER 1
     19    #define NCOLS 1
     20    #define NROWS 1
     21    #define CPTH 32
     22    #include "nmaster-4.7.c"
     23    
     24    Layout layouts[] = {
     25         { "-|=" , ntile },
     26         // ...
     27    };
     28 
     29    // keys
     30     { MODKEY|ShiftMask , XK_j    , setnmaster , "+1" } , \
     31     { MODKEY|ShiftMask , XK_k    , setnmaster , "-1" } , \
     32     { MODKEY , XK_q , clientspertag ,"^1" } , \
     33     { MODKEY , XK_w , clientspertag , "2" } , \
     34     { MODKEY , XK_e , clientspertag , "3" } , \
     35     { MODKEY           , XK_n , setcpth , "+32" } , \
     36     { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \
     37 
     38 
     39  clientspertag:
     40 
     41   both of them features the new cpt patch (clients per tag) which enables
     42   to define the maximum number of clients you want to focus, the rest are
     43   stacked at the bottom of the screen. This area has CPTH height and this
     44   value can be changed on the fly using the setcpth function.
     45 
     46   +------+----+
     47   |      |    |   Valid values are:
     48   |      |----|    -1  -  show all clients
     49   |      |    |     0  -  show all clients in the bottom stack area
     50   +---+--^+---+    >0  -  show N clients
     51   +---+---+---+
     52 
     53     #define CPTH 32   // num of pixels of the height of the stacked cpt area
     54  
     55     { MODKEY , XK_q , clientspertag ,"^1" } , \
     56     { MODKEY , XK_w , clientspertag , "2" } , \
     57     { MODKEY , XK_e , clientspertag , "3" } , \
     58     { MODKEY , XK_r , clientspertag , "4" } , \
     59     { MODKEY , XK_t , clientspertag , "5" } , \
     60  
     61     { MODKEY           , XK_n , setcpth , "+32" } , \
     62     { MODKEY|ShiftMask , XK_n , setcpth , "-32" } , \
     63 
     64 
     65  This source adds two new layouts:
     66 
     67  ntile:
     68 
     69   +-----+--+     
     70   |_____|--|     
     71   |     |--|     
     72   +-----+--+
     73 
     74     #define NMASTER 1
     75 
     76     { "-|="            , ntile } , \
     77 
     78     { MODKEY|ShiftMask , XK_j    , setnmaster , "+1" } , \
     79     { MODKEY|ShiftMask , XK_k    , setnmaster , "-1" } , \
     80 
     81 
     82  tilecols:
     83 
     84   +--+--+--+     
     85   |__|  |__|     
     86   |  |  |  |     
     87   +--+--+--+     
     88 
     89     #define NCOLS 2
     90     #define NROWS 1
     91 
     92     { "E|]"            , tilecols } , \
     93 
     94     { MODKEY|ShiftMask , XK_j , setnrows , "+1" } , \
     95     { MODKEY|ShiftMask , XK_k , setnrows , "-1" } , \
     96     { MODKEY|ShiftMask , XK_h , setncols , "+1" } , \
     97     { MODKEY|ShiftMask , XK_l , setncols , "-1" } ,
     98 
     99 #endif
    100 
    101 
    102 /* height for bottom stacked clients */
    103 #ifndef CPTH
    104 #define CPTH 32
    105 #endif
    106 /* initial value for clients per tag */
    107 #ifndef CPT
    108 #define CPT -1
    109 #endif
    110 
    111 void
    112 maxzoom(const char *arg) {
    113 	if (sel->isfloating)
    114 		togglemax(NULL);
    115 	else
    116 		zoom(NULL);
    117 }
    118 
    119 int cpt = CPT;
    120 int Cpth = CPTH;
    121 
    122 void
    123 clientspertag(const char *arg) {
    124 	if (*arg=='+' || *arg=='-') {
    125 		cpt += atoi(arg);
    126         } else if (arg[0]=='^') {
    127                 if (cpt==-1) cpt = atoi(arg+1);
    128                 else cpt = -1;
    129         } else cpt = atoi(arg);
    130         arrange();
    131 }
    132 
    133 void
    134 setcpth(const char *arg) {
    135 	int i;
    136 
    137 	if(!arg)
    138 		Cpth = CPTH;
    139 	else {
    140 		Cpth += atoi(arg);
    141 		if (Cpth-CPTH<=0)
    142 			Cpth = CPTH;
    143 		if (Cpth+CPTH>=wah)
    144 			Cpth = wah - CPTH;
    145 	}
    146 	if(sel)
    147 		arrange();
    148 }
    149 
    150 #ifdef NMASTER
    151 int nmaster = NMASTER;
    152 
    153 void
    154 ntile(void) {
    155 	unsigned int i, n, t, nx, ny, nw, nh, mw, mh, th;
    156 	int cptn = 0, cpth = 0;
    157 	Client *c;
    158 
    159 	domwfact = dozoom = True;
    160 
    161 	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) {
    162 		//if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; }
    163 		n++;
    164 	}
    165 	t = n;
    166 	if (cpt!=-1&&n>cpt) {
    167 		n    = cpt;
    168 		cpth = Cpth;
    169 		wah -= cpth;
    170 	}
    171 	/* window geoms */
    172 	mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster;
    173 	mw = (n <= nmaster) ? waw : mwfact * waw;
    174 	th = (n > nmaster) ? wah / (n - nmaster) : 0;
    175 	if(n > nmaster && th < bh)
    176 		th = wah;
    177 
    178 	nx = wax;
    179 	ny = way;
    180 
    181 	for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
    182 		if (cpt!=-1 && i>=cpt) {
    183 			nw = waw/(t-n) - c->border*2;
    184 			nx = (nw+c->border*2)*cptn;
    185 			cptn++;
    186 			ny = wah + way;
    187 			nh = cpth-(c->border*2);
    188 			if (nh<c->border) nh = cpth;
    189 			resize(c, nx, ny, nw, nh, RESIZEHINTS);
    190 			continue;
    191 		}
    192 		c->ismax = False;
    193 		if(i < nmaster) { /* master */
    194 			ny = way + i * mh;
    195 			nw = mw - 2 * c->border;
    196 			nh = mh;
    197 			if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */
    198 				nh = wah - mh * i;
    199 			nh -= 2 * c->border;
    200 		}
    201 		else {  /* tile window */
    202 			if(i == nmaster) {
    203 				ny = way;
    204 				nx += mw;
    205 			}
    206 			nw = waw - mw - 2 * c->border;
    207 			if(i + 1 == n) /* remainder */
    208 				nh = (way + wah) - ny - 2 * c->border;
    209 			else
    210 				nh = th - 2 * c->border;
    211 		}
    212 		resize(c, nx, ny, nw, nh, RESIZEHINTS);
    213 		if(n > nmaster && th != wah)
    214 			ny += nh + 2 * c->border;
    215 	}
    216 	wah += cpth;
    217 }
    218 
    219 void
    220 setnmaster(const char *arg) {
    221 	int i;
    222 
    223 	if(!arg)
    224 		nmaster = NMASTER;
    225 	else {
    226 		i = atoi(arg);
    227 		if((nmaster + i) < 1 || wah / (nmaster + i) <= 2 * BORDERPX)
    228 			return;
    229 		nmaster += i;
    230 	}
    231 	if(sel)
    232 		arrange();
    233 }
    234 #endif
    235 
    236 #ifdef NCOLS
    237 #ifdef NROWS
    238 unsigned int ncols = NCOLS;
    239 unsigned int nrows = NROWS;
    240 
    241 void
    242 setncols(const char *arg) {
    243 	int i;
    244 
    245 	if(!arg)
    246 		i = NCOLS;
    247 	else if(arg[0] != '+' && arg[0] != '-')
    248 		i = atoi(arg);
    249 	else
    250 		i = ncols + atoi(arg);
    251 
    252 	if((i < 1) || (i >= 1 && waw / i <= 2 * BORDERPX))
    253 		return;
    254 	ncols = i;
    255 
    256 	if(sel)
    257 		arrange();
    258 }
    259 
    260 void
    261 setnrows(const char *arg) {
    262 	int i;
    263 
    264 	if(!arg)
    265 		i = NROWS;
    266 	else if(arg[0] != '+' && arg[0] != '-')
    267 		i = atoi(arg);
    268 	else
    269 		i = nrows + atoi(arg);
    270 
    271 	if(i < 1 || wah <= 2 * BORDERPX * i)
    272 		return;
    273 	nrows = i;
    274  
    275 	if(sel)
    276 		arrange();
    277 }
    278 
    279 void
    280 tilecols(void) {
    281 	unsigned int i, n, nx, ny, nw, nh, mw, mh, tw, th, tw1, cols, rows, rows1, t;
    282 	int cpth = 0, cptn = 0;
    283 	Client *c;
    284 
    285 	domwfact = dozoom = True;
    286 
    287 	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next)) {
    288 	//	if (cpt!=-1 && n>=cpt && sel == c) { n=cpt; zoom(NULL); break; }
    289 		n++;
    290 	}
    291 
    292  	/* calculate correct number of rows */
    293  	if(ncols > 0 && n - nmaster > nrows * ncols)
    294  		rows = (n - nmaster) / ncols + ((n - nmaster) % ncols ? 1 : 0);
    295 	else
    296  		rows = nrows;
    297 
    298 	t = n;
    299 	if (cpt!=-1&&n>cpt) {
    300 		n    = cpt;
    301 		cpth = Cpth;
    302 		wah -= cpth;
    303 	}
    304 
    305 	/* window geoms */
    306 	mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster;
    307 
    308 	if (nmaster == 0) {
    309 		mh = mw = 0;
    310 	}
    311 	else if (n <= nmaster) {
    312 		mh = wah / (n > 0 ? n : 1);
    313 		mw = waw;
    314 	}
    315 	else {
    316 		mh = wah / nmaster;
    317 		mw = mwfact * waw;
    318 	}
    319 
    320 	if(rows == 0 || n <= nmaster + rows) {
    321 		rows1 = n > nmaster ? n - nmaster : 1;
    322 		tw = tw1 = waw - mw; 
    323 		th = wah / rows1;
    324 	}
    325 	else {
    326 		rows1 = 1 + (n - nmaster - 1) % rows;
    327 		cols = (n - nmaster) / rows + ((n - nmaster) % rows ? 1 : 0);
    328 		tw = (waw - mw) / cols;
    329 		tw1 = waw - mw - (cols - 1) * tw;
    330 		th = wah / rows;
    331 	}
    332 
    333 	nx = wax;
    334 	ny = way;
    335 
    336 	for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
    337 #if 0
    338 		if (cpt!=-1 && i>=cpt) {
    339 			ban(c);
    340 			continue;
    341 		}
    342 #endif
    343 		if (cpt!=-1 && i>=cpt) {
    344 			nw = waw/(t-n) - c->border*2;
    345 			nx = (nw+c->border*2)*cptn;
    346 			cptn++;
    347 			ny = wah + way;
    348 			nh = cpth-(c->border*2);
    349 			if (nh<c->border) nh = cpth;
    350 			resize(c, nx, ny, nw, nh, RESIZEHINTS);
    351 			continue;
    352 		}
    353 		c->ismax = False;
    354 		if(i < nmaster) { /* master column */
    355 			ny = way + i * mh;
    356 			nw = mw - 2 * c->border;
    357  			nh = mh - 2 * c->border;
    358  			if(i == 0)
    359  				nh += wah - mh * (n < nmaster ? n : nmaster);
    360 			nh = mh;
    361 			if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */
    362 				nh = wah - mh * i;
    363 			nh -= 2 * c->border;
    364 		}
    365  		else if(i < nmaster + rows1) { /* first stack column */
    366  			if(i == nmaster) { /* initialise */
    367 				ny = way;
    368 				nx += mw;
    369  				nh = wah - 2*c->border - (rows1 - 1) * th;
    370 			} else
    371 				nh = th - 2 * c->border;
    372  			nw = tw1 - 2 * c->border;
    373  		}
    374  		else { /* successive stack columns - rows > 0 if we reach here */
    375  			if((i - nmaster - rows1) % rows == 0) { /* reinitialise */
    376  				ny = way;
    377  				nx += nw + 2 * c-> border;
    378  				nh = wah - 2*c->border - (rows - 1) * th;
    379  			}
    380  			else {
    381  				nh = th - 2 * c->border;
    382  			}
    383  			nw = tw - 2 * c->border;
    384 		}
    385 		resize(c, nx, ny, nw, nh, RESIZEHINTS);
    386  		ny += nh + 2 * c->border;
    387 	}
    388 	wah += cpth;
    389 }
    390 #endif
    391 #endif
    392 
    393 /* EXPERIMENTAL:
    394  *
    395  *    Work in progress stuff
    396  */
    397 #ifdef EXPERIMENTAL
    398 void
    399 swapclients(Client *c1, Client *c2)
    400 {
    401 	Client *tmp;
    402 
    403 	if (c2 == NULL) {
    404 		c1->prev->next = NULL;
    405 		c1->next = clients;
    406 		clients = c1;
    407 		return;
    408 	}
    409 
    410 	tmp = c1->next;
    411 	c1->next = c2->next;
    412 	c2->next = (tmp == c2 ? c1 : tmp);
    413 
    414 	tmp = c2->prev;
    415 	c2->prev = c1->prev;
    416 	c1->prev = (tmp == c1 ? c2 : tmp );
    417 
    418 	if(c1->next)
    419 		c1->next->prev = c1;
    420 
    421 	if(c1->prev)
    422 		c1->prev->next = c1;
    423 
    424 	if(c2->next)
    425 		c2->next->prev = c2;
    426 
    427 	if(c2->prev)
    428 		c2->prev->next = c2;
    429 
    430 	//if(clients == c1)
    431 	//	clients = c2;
    432 }
    433 
    434 void
    435 swap(const char *arg) {
    436 	int i;
    437 
    438 	if(sel) {
    439 		if (*arg=='+')
    440 			swapclients(sel, sel->next);
    441 		else
    442 		if (*arg=='-')
    443 			swapclients(sel, sel->prev);
    444 		arrange();
    445 	}
    446 }
    447 #endif
    448 
    449 #ifdef EXPERIMENTAL
    450 void
    451 dntile(void) {
    452 	unsigned int i, n, nx, ny, nw, nh, mw, mh, th, inc;
    453 	Client *c;
    454 
    455 	for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
    456 		n++;
    457 	if (cpt!=-1 && n>cpt) n = cpt;
    458 
    459 	/* dynamic nmaster */
    460 	if (n<5) inc = 0;
    461 	else if (n<7) inc = 1;
    462 	else inc = 2;
    463 	nmaster+=inc;
    464 
    465 	/* window geoms */
    466 	mh = (n <= nmaster) ? wah / (n > 0 ? n : 1) : wah / nmaster;
    467 	mw = (n <= nmaster) ? waw : mwfact * waw;
    468 	th = (n > nmaster) ? wah / (n - nmaster) : 0;
    469 	if(n > nmaster && th < bh)
    470 		th = wah;
    471 
    472 	nx = wax;
    473 	ny = way;
    474 	for(i = 0, c = nexttiled(clients); c; c = nexttiled(c->next), i++) {
    475 		if (cpt!=-1 && i>=cpt) {
    476 			ban(c);
    477 			continue;
    478 		}
    479 		c->ismax = False;
    480 		if(i < nmaster) { /* master */
    481 			ny = way + i * mh;
    482 			nw = mw - 2 * c->border;
    483 			nh = mh;
    484 			if(i + 1 == (n < nmaster ? n : nmaster)) /* remainder */
    485 				nh = wah - mh * i;
    486 			nh -= 2 * c->border;
    487 		}
    488 		else {  /* tile window */
    489 			if(i == nmaster) {
    490 				ny = way;
    491 				nx += mw;
    492 			}
    493 			nw = waw - mw - 2 * c->border;
    494 			if(i + 1 == n) /* remainder */
    495 				nh = (way + wah) - ny - 2 * c->border;
    496 			else
    497 				nh = th - 2 * c->border;
    498 		}
    499 		resize(c, nx, ny, nw, nh, False);
    500 		if(n > nmaster && th != wah)
    501 			ny += nh + 2 * c->border;
    502 	}
    503 	nmaster -= inc;
    504 }
    505 #endif