dwm-flextile-5.8.1.diff (13766B)
1 diff -up ../dwm-5.8.1-0/config.def.h ./config.def.h 2 --- ../dwm-5.8.1-0/config.def.h 2010-05-29 13:49:12.000000000 +0200 3 +++ ./config.def.h 2010-05-31 15:18:43.686311000 +0200 4 @@ -25,6 +25,11 @@ static const Rule rules[] = { 5 /* layout(s) */ 6 static const float mfact = 0.55; /* factor of master area size [0.05..0.95] */ 7 static const Bool resizehints = True; /* True means respect size hints in tiled resizals */ 8 +static const int layoutaxis[] = { 9 + 1, /* layout axis: 1 = x, 2 = y; negative values mirror the layout, setting the master area to the right / bottom instead of left / top */ 10 + 2, /* master axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ 11 + 2, /* stack axis: 1 = x (from left to right), 2 = y (from top to bottom), 3 = z (monocle) */ 12 +}; 13 14 static const Layout layouts[] = { 15 /* symbol arrange function */ 16 @@ -81,6 +86,12 @@ static Key keys[] = { 17 TAGKEYS( XK_8, 7) 18 TAGKEYS( XK_9, 8) 19 { MODKEY|ShiftMask, XK_q, quit, {0} }, 20 + { MODKEY|ControlMask, XK_t, rotatelayoutaxis, {.i = 0} }, /* 0 = layout axis */ 21 + { MODKEY|ControlMask, XK_Tab, rotatelayoutaxis, {.i = 1} }, /* 1 = master axis */ 22 + { MODKEY|ControlMask|ShiftMask, XK_Tab, rotatelayoutaxis, {.i = 2} }, /* 2 = stack axis */ 23 + { MODKEY|ControlMask, XK_Return, mirrorlayout, {0} }, 24 + { MODKEY|ControlMask, XK_j, shiftmastersplit, {.i = -1} }, /* reduce the number of tiled clients in the master area */ 25 + { MODKEY|ControlMask, XK_k, shiftmastersplit, {.i = +1} }, /* increase the number of tiled clients in the master area */ 26 }; 27 28 /* button definitions */ 29 diff -up ../dwm-5.8.1-0/dwm.c ./dwm.c 30 --- ../dwm-5.8.1-0/dwm.c 2010-05-29 13:49:12.000000000 +0200 31 +++ ./dwm.c 2010-05-31 16:02:14.553316000 +0200 32 @@ -120,26 +120,6 @@ typedef struct { 33 void (*arrange)(Monitor *); 34 } Layout; 35 36 -struct Monitor { 37 - char ltsymbol[16]; 38 - float mfact; 39 - int num; 40 - int by; /* bar geometry */ 41 - int mx, my, mw, mh; /* screen size */ 42 - int wx, wy, ww, wh; /* window area */ 43 - unsigned int seltags; 44 - unsigned int sellt; 45 - unsigned int tagset[2]; 46 - Bool showbar; 47 - Bool topbar; 48 - Client *clients; 49 - Client *sel; 50 - Client *stack; 51 - Monitor *next; 52 - Window barwin; 53 - const Layout *lt[2]; 54 -}; 55 - 56 typedef struct { 57 const char *class; 58 const char *instance; 59 @@ -193,6 +173,7 @@ static void killclient(const Arg *arg); 60 static void manage(Window w, XWindowAttributes *wa); 61 static void mappingnotify(XEvent *e); 62 static void maprequest(XEvent *e); 63 +static void mirrorlayout(const Arg *arg); 64 static void monocle(Monitor *m); 65 static void movemouse(const Arg *arg); 66 static Client *nexttiled(Client *c); 67 @@ -202,6 +183,7 @@ static void quit(const Arg *arg); 68 static void resize(Client *c, int x, int y, int w, int h, Bool interact); 69 static void resizemouse(const Arg *arg); 70 static void restack(Monitor *m); 71 +static void rotatelayoutaxis(const Arg *arg); 72 static void run(void); 73 static void scan(void); 74 static void sendmon(Client *c, Monitor *m); 75 @@ -209,6 +191,7 @@ static void setclientstate(Client *c, lo 76 static void setlayout(const Arg *arg); 77 static void setmfact(const Arg *arg); 78 static void setup(void); 79 +static void shiftmastersplit(const Arg *arg); 80 static void showhide(Client *c); 81 static void sigchld(int unused); 82 static void spawn(const Arg *arg); 83 @@ -275,6 +258,34 @@ static Window root; 84 85 /* compile-time check if all tags fit into an unsigned int bit array. */ 86 struct NumTags { char limitexceeded[LENGTH(tags) > 31 ? -1 : 1]; }; 87 +struct Monitor { 88 + char ltsymbol[16]; 89 + float mfact; 90 + double mfacts[LENGTH(tags) + 1]; 91 + int ltaxis[3]; 92 + int ltaxes[LENGTH(tags) + 1][3]; 93 + int num; 94 + int curtag; 95 + int prevtag; 96 + int by; /* bar geometry */ 97 + int mx, my, mw, mh; /* screen size */ 98 + int wx, wy, ww, wh; /* window area */ 99 + unsigned int msplit; 100 + unsigned int msplits[LENGTH(tags) + 1]; 101 + unsigned int seltags; 102 + unsigned int sellt; 103 + unsigned int tagset[2]; 104 + Bool showbar; 105 + Bool showbars[LENGTH(tags) + 1]; 106 + Bool topbar; 107 + Client *clients; 108 + Client *sel; 109 + Client *stack; 110 + Monitor *next; 111 + Window barwin; 112 + const Layout *lt[2]; 113 + const Layout *lts[LENGTH(tags) + 1]; 114 +}; 115 116 /* function implementations */ 117 void 118 @@ -616,6 +627,10 @@ createmon(void) { 119 m->lt[0] = &layouts[0]; 120 m->lt[1] = &layouts[1 % LENGTH(layouts)]; 121 strncpy(m->ltsymbol, layouts[0].symbol, sizeof m->ltsymbol); 122 + m->ltaxis[0] = layoutaxis[0]; 123 + m->ltaxis[1] = layoutaxis[1]; 124 + m->ltaxis[2] = layoutaxis[2]; 125 + m->msplit = 1; 126 return m; 127 } 128 129 @@ -1173,6 +1188,15 @@ maprequest(XEvent *e) { 130 } 131 132 void 133 +mirrorlayout(const Arg *arg) { 134 + if(!selmon->lt[selmon->sellt]->arrange) 135 + return; 136 + selmon->ltaxis[0] *= -1; 137 + selmon->ltaxes[selmon->curtag][0] = selmon->ltaxis[0]; 138 + arrange(selmon); 139 +} 140 + 141 +void 142 monocle(Monitor *m) { 143 unsigned int n = 0; 144 Client *c; 145 @@ -1387,6 +1411,21 @@ restack(Monitor *m) { 146 } 147 148 void 149 +rotatelayoutaxis(const Arg *arg) { 150 + if(!selmon->lt[selmon->sellt]->arrange) 151 + return; 152 + if(arg->i == 0) { 153 + if(selmon->ltaxis[0] > 0) 154 + selmon->ltaxis[0] = selmon->ltaxis[0] + 1 > 2 ? 1 : selmon->ltaxis[0] + 1; 155 + else 156 + selmon->ltaxis[0] = selmon->ltaxis[0] - 1 < -2 ? -1 : selmon->ltaxis[0] - 1; 157 + } else 158 + selmon->ltaxis[arg->i] = selmon->ltaxis[arg->i] + 1 > 3 ? 1 : selmon->ltaxis[arg->i] + 1; 159 + selmon->ltaxes[selmon->curtag][arg->i] = selmon->ltaxis[arg->i]; 160 + arrange(selmon); 161 +} 162 + 163 +void 164 run(void) { 165 XEvent ev; 166 /* main event loop */ 167 @@ -1451,7 +1490,7 @@ setlayout(const Arg *arg) { 168 if(!arg || !arg->v || arg->v != selmon->lt[selmon->sellt]) 169 selmon->sellt ^= 1; 170 if(arg && arg->v) 171 - selmon->lt[selmon->sellt] = (Layout *)arg->v; 172 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag] = (Layout *)arg->v; 173 strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, sizeof selmon->ltsymbol); 174 if(selmon->sel) 175 arrange(selmon); 176 @@ -1469,14 +1508,16 @@ setmfact(const Arg *arg) { 177 f = arg->f < 1.0 ? arg->f + selmon->mfact : arg->f - 1.0; 178 if(f < 0.1 || f > 0.9) 179 return; 180 - selmon->mfact = f; 181 + selmon->mfact = selmon->mfacts[selmon->curtag] = f; 182 arrange(selmon); 183 } 184 185 void 186 setup(void) { 187 XSetWindowAttributes wa; 188 - 189 + Monitor *m; 190 + unsigned int i; 191 + 192 /* clean up any zombies immediately */ 193 sigchld(0); 194 195 @@ -1511,7 +1552,19 @@ setup(void) { 196 XSetLineAttributes(dpy, dc.gc, 1, LineSolid, CapButt, JoinMiter); 197 if(!dc.font.set) 198 XSetFont(dpy, dc.gc, dc.font.xfont->fid); 199 - /* init bars */ 200 + /* init tags, bars, layouts, axes, msplits and mfacts */ 201 + for(m = mons; m; m = m->next) { 202 + m->curtag = m->prevtag = 1; 203 + for(i=0; i < LENGTH(tags) + 1; i++) { 204 + m->showbars[i] = m->showbar; 205 + m->lts[i] = &layouts[0]; 206 + m->mfacts[i] = m->mfact; 207 + m->ltaxes[i][0] = m->ltaxis[0]; 208 + m->ltaxes[i][1] = m->ltaxis[1]; 209 + m->ltaxes[i][2] = m->ltaxis[2]; 210 + m->msplits[i] = m->msplit; 211 + } 212 + } 213 updatebars(); 214 updatestatus(); 215 /* EWMH support per view */ 216 @@ -1528,6 +1581,19 @@ setup(void) { 217 } 218 219 void 220 +shiftmastersplit(const Arg *arg) { 221 + unsigned int n; 222 + Client *c; 223 + 224 + for(n = 0, c = nexttiled(selmon->clients); c; c = nexttiled(c->next), n++); 225 + if(!arg || !selmon->lt[selmon->sellt]->arrange || selmon->msplit + arg->i < 1 || selmon->msplit + arg->i > n) 226 + return; 227 + selmon->msplit += arg->i; 228 + selmon->msplits[selmon->curtag] = selmon->msplit; 229 + arrange(selmon); 230 +} 231 + 232 +void 233 showhide(Client *c) { 234 if(!c) 235 return; 236 @@ -1592,37 +1658,95 @@ textnw(const char *text, unsigned int le 237 238 void 239 tile(Monitor *m) { 240 - int x, y, h, w, mw; 241 - unsigned int i, n; 242 + char sym1 = 61, sym2 = 93, sym3 = 61, sym; 243 + int x1 = m->wx, y1 = m->wy, h1 = m->wh, w1 = m->ww, X1 = x1 + w1, Y1 = y1 + h1; 244 + int x2 = m->wx, y2 = m->wy, h2 = m->wh, w2 = m->ww, X2 = x2 + w2, Y2 = y2 + h2; 245 + unsigned int i, n, n1, n2; 246 Client *c; 247 248 for(n = 0, c = nexttiled(m->clients); c; c = nexttiled(c->next), n++); 249 + if(m->msplit > n) 250 + m->msplit = (n == 0) ? 1 : n; 251 + if(n == 0 && m->ltaxis[1] != 3) 252 + return; 253 + /* layout symbol */ 254 + if(abs(m->ltaxis[0]) == m->ltaxis[1]) /* explicitly: ((abs(m->ltaxis[0]) == 1 && m->ltaxis[1] == 1) || (abs(m->ltaxis[0]) == 2 && m->ltaxis[1] == 2)) */ 255 + sym1 = 124; 256 + if(abs(m->ltaxis[0]) == m->ltaxis[2]) 257 + sym3 = 124; 258 + if(m->ltaxis[1] == 3) 259 + sym1 = (n == 0) ? 0 : m->msplit; 260 + if(m->ltaxis[2] == 3) 261 + sym3 = (n == 0) ? 0 : n - m->msplit; 262 + if(m->ltaxis[0] < 0) { 263 + sym = sym1; 264 + sym1 = sym3; 265 + sym2 = 91; 266 + sym3 = sym; 267 + } 268 + if(m->msplit == 1) { 269 + if(m->ltaxis[0] > 0) 270 + sym1 = 91; 271 + else 272 + sym3 = 93; 273 + } 274 + if(m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[2] == 3) 275 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%d", sym1, sym2, sym3); 276 + else if((m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] > 0) || (m->ltaxis[2] == 3 && m->ltaxis[0] < 0)) 277 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%d%c%c", sym1, sym2, sym3); 278 + else if((m->ltaxis[2] == 3 && m->ltaxis[0] > 0) || (m->msplit > 1 && m->ltaxis[1] == 3 && m->ltaxis[0] < 0)) 279 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%d", sym1, sym2, sym3); 280 + else 281 + snprintf(m->ltsymbol, sizeof m->ltsymbol, "%c%c%c", sym1, sym2, sym3); 282 if(n == 0) 283 return; 284 + /* master and stack area */ 285 + if(abs(m->ltaxis[0]) == 1 && n > m->msplit) { 286 + w1 *= m->mfact; 287 + w2 -= w1; 288 + x1 += (m->ltaxis[0] < 0) ? w2 : 0; 289 + x2 += (m->ltaxis[0] < 0) ? 0 : w1; 290 + X1 = x1 + w1; 291 + X2 = x2 + w2; 292 + } else if(abs(m->ltaxis[0]) == 2 && n > m->msplit) { 293 + h1 *= m->mfact; 294 + h2 -= h1; 295 + y1 += (m->ltaxis[0] < 0) ? h2 : 0; 296 + y2 += (m->ltaxis[0] < 0) ? 0 : h1; 297 + Y1 = y1 + h1; 298 + Y2 = y2 + h2; 299 + } 300 /* master */ 301 - c = nexttiled(m->clients); 302 - mw = m->mfact * m->ww; 303 - resize(c, m->wx, m->wy, (n == 1 ? m->ww : mw) - 2 * c->bw, m->wh - 2 * c->bw, False); 304 - if(--n == 0) 305 - return; 306 - /* tile stack */ 307 - x = (m->wx + mw > c->x + c->w) ? c->x + c->w + 2 * c->bw : m->wx + mw; 308 - y = m->wy; 309 - w = (m->wx + mw > c->x + c->w) ? m->wx + m->ww - x : m->ww - mw; 310 - h = m->wh / n; 311 - if(h < bh) 312 - h = m->wh; 313 - for(i = 0, c = nexttiled(c->next); c; c = nexttiled(c->next), i++) { 314 - resize(c, x, y, w - 2 * c->bw, /* remainder */ ((i + 1 == n) 315 - ? m->wy + m->wh - y - 2 * c->bw : h - 2 * c->bw), False); 316 - if(h != m->wh) 317 - y = c->y + HEIGHT(c); 318 + n1 = (m->ltaxis[1] != 1 || w1 / m->msplit < bh) ? 1 : m->msplit; 319 + n2 = (m->ltaxis[1] != 2 || h1 / m->msplit < bh) ? 1 : m->msplit; 320 + for(i = 0, c = nexttiled(m->clients); i < m->msplit; c = nexttiled(c->next), i++) { 321 + resize(c, x1, y1, 322 + (m->ltaxis[1] == 1 && i + 1 == m->msplit) ? X1 - x1 - 2 * c->bw : w1 / n1 - 2 * c->bw, 323 + (m->ltaxis[1] == 2 && i + 1 == m->msplit) ? Y1 - y1 - 2 * c->bw : h1 / n2 - 2 * c->bw, False); 324 + if(n1 > 1) 325 + x1 = c->x + WIDTH(c); 326 + if(n2 > 1) 327 + y1 = c->y + HEIGHT(c); 328 + } 329 + /* stack */ 330 + if(n > m->msplit) { 331 + n1 = (m->ltaxis[2] != 1 || w2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; 332 + n2 = (m->ltaxis[2] != 2 || h2 / (n - m->msplit) < bh) ? 1 : n - m->msplit; 333 + for(i = 0; c; c = nexttiled(c->next), i++) { 334 + resize(c, x2, y2, 335 + (m->ltaxis[2] == 1 && i + 1 == n - m->msplit) ? X2 - x2 - 2 * c->bw : w2 / n1 - 2 * c->bw, 336 + (m->ltaxis[2] == 2 && i + 1 == n - m->msplit) ? Y2 - y2 - 2 * c->bw : h2 / n2 - 2 * c->bw, False); 337 + if(n1 > 1) 338 + x2 = c->x + WIDTH(c); 339 + if(n2 > 1) 340 + y2 = c->y + HEIGHT(c); 341 + } 342 } 343 } 344 345 void 346 togglebar(const Arg *arg) { 347 - selmon->showbar = !selmon->showbar; 348 + selmon->showbar = selmon->showbars[selmon->curtag] = !selmon->showbar; 349 updatebarpos(selmon); 350 XMoveResizeWindow(dpy, selmon->barwin, selmon->wx, selmon->by, selmon->ww, bh); 351 arrange(selmon); 352 @@ -1642,12 +1766,31 @@ togglefloating(const Arg *arg) { 353 void 354 toggletag(const Arg *arg) { 355 unsigned int newtags; 356 + unsigned int i; 357 358 if(!selmon->sel) 359 return; 360 newtags = selmon->sel->tags ^ (arg->ui & TAGMASK); 361 if(newtags) { 362 selmon->sel->tags = newtags; 363 + if(newtags == ~0) { 364 + selmon->prevtag = selmon->curtag; 365 + selmon->curtag = 0; 366 + } 367 + if(!(newtags & 1 << (selmon->curtag - 1))) { 368 + selmon->prevtag = selmon->curtag; 369 + for (i=0; !(newtags & 1 << i); i++); 370 + selmon->curtag = i + 1; 371 + } 372 + selmon->sel->tags = newtags; 373 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; 374 + selmon->mfact = selmon->mfacts[selmon->curtag]; 375 + if (selmon->showbar != selmon->showbars[selmon->curtag]) 376 + togglebar(NULL); 377 + selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; 378 + selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; 379 + selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; 380 + selmon->msplit = selmon->msplits[selmon->curtag]; 381 arrange(selmon); 382 } 383 } 384 @@ -1914,11 +2057,33 @@ updatewmhints(Client *c) { 385 386 void 387 view(const Arg *arg) { 388 + unsigned int i; 389 + 390 if((arg->ui & TAGMASK) == selmon->tagset[selmon->seltags]) 391 return; 392 selmon->seltags ^= 1; /* toggle sel tagset */ 393 - if(arg->ui & TAGMASK) 394 + if(arg->ui & TAGMASK) { 395 selmon->tagset[selmon->seltags] = arg->ui & TAGMASK; 396 + selmon->prevtag = selmon->curtag; 397 + if(arg->ui == ~0) 398 + selmon->curtag = 0; 399 + else { 400 + for (i=0; !(arg->ui & 1 << i); i++); 401 + selmon->curtag = i + 1; 402 + } 403 + } else { 404 + selmon->prevtag = selmon->curtag ^ selmon->prevtag; 405 + selmon->curtag ^= selmon->prevtag; 406 + selmon->prevtag = selmon->curtag ^ selmon->prevtag; 407 + } 408 + selmon->lt[selmon->sellt] = selmon->lts[selmon->curtag]; 409 + selmon->mfact = selmon->mfacts[selmon->curtag]; 410 + if(selmon->showbar != selmon->showbars[selmon->curtag]) 411 + togglebar(NULL); 412 + selmon->ltaxis[0] = selmon->ltaxes[selmon->curtag][0]; 413 + selmon->ltaxis[1] = selmon->ltaxes[selmon->curtag][1]; 414 + selmon->ltaxis[2] = selmon->ltaxes[selmon->curtag][2]; 415 + selmon->msplit = selmon->msplits[selmon->curtag]; 416 arrange(selmon); 417 } 418