aewl

annotate view.c @ 473:2d8af0d7920d

implemented the maximization as I described on the mailinglist, this feels better to me.
author arg@mmvi
date Fri, 22 Sep 2006 07:37:56 +0200
parents e93b0ad5aeb5
children de69a7b0c8fa
rev   line source
arg@327 1 /*
arg@327 2 * (C)opyright MMVI Anselm R. Garbe <garbeam at gmail dot com>
arg@327 3 * See LICENSE file for license details.
arg@327 4 */
arg@327 5 #include "dwm.h"
arg@327 6
arg@380 7 /* static */
arg@380 8
arg@382 9 static Client *
arg@461 10 minclient() {
arg@382 11 Client *c, *min;
arg@382 12
arg@443 13 if((clients && clients->isfloat) || arrange == dofloat)
arg@443 14 return clients; /* don't touch floating order */
arg@382 15 for(min = c = clients; c; c = c->next)
arg@382 16 if(c->weight < min->weight)
arg@382 17 min = c;
arg@382 18 return min;
arg@382 19 }
arg@382 20
arg@442 21 static void
arg@461 22 reorder() {
arg@382 23 Client *c, *newclients, *tail;
arg@380 24
arg@382 25 newclients = tail = NULL;
arg@382 26 while((c = minclient())) {
arg@381 27 detach(c);
arg@382 28 if(tail) {
arg@382 29 c->prev = tail;
arg@382 30 tail->next = c;
arg@382 31 tail = c;
arg@381 32 }
arg@381 33 else
arg@382 34 tail = newclients = c;
arg@380 35 }
arg@382 36 clients = newclients;
arg@380 37 }
arg@380 38
arg@430 39 static Client *
arg@461 40 nexttiled(Client *c) {
arg@433 41 for(c = getnext(c); c && c->isfloat; c = getnext(c->next));
arg@430 42 return c;
arg@430 43 }
arg@430 44
arg@327 45 /* extern */
arg@327 46
arg@327 47 void (*arrange)(Arg *) = DEFMODE;
arg@327 48
arg@327 49 void
arg@461 50 detach(Client *c) {
arg@378 51 if(c->prev)
arg@378 52 c->prev->next = c->next;
arg@378 53 if(c->next)
arg@378 54 c->next->prev = c->prev;
arg@378 55 if(c == clients)
arg@378 56 clients = c->next;
arg@378 57 c->next = c->prev = NULL;
arg@378 58 }
arg@378 59
arg@378 60 void
arg@461 61 dofloat(Arg *arg) {
arg@402 62 Client *c;
arg@400 63
arg@327 64 for(c = clients; c; c = c->next) {
arg@327 65 if(isvisible(c)) {
arg@327 66 resize(c, True, TopLeft);
arg@327 67 }
arg@327 68 else
arg@327 69 ban(c);
arg@327 70 }
arg@446 71 if(!sel || !isvisible(sel)) {
arg@450 72 for(c = stack; c && !isvisible(c); c = c->snext);
arg@450 73 focus(c);
arg@446 74 }
arg@327 75 restack();
arg@327 76 }
arg@327 77
arg@327 78 void
arg@461 79 dotile(Arg *arg) {
arg@327 80 int h, i, n, w;
arg@402 81 Client *c;
arg@400 82
arg@327 83 w = sw - mw;
arg@430 84 for(n = 0, c = clients; c; c = c->next)
arg@430 85 if(isvisible(c) && !c->isfloat)
arg@327 86 n++;
arg@327 87
arg@327 88 if(n > 1)
arg@327 89 h = (sh - bh) / (n - 1);
arg@327 90 else
arg@327 91 h = sh - bh;
arg@327 92
arg@327 93 for(i = 0, c = clients; c; c = c->next) {
arg@327 94 if(isvisible(c)) {
arg@327 95 if(c->isfloat) {
arg@327 96 resize(c, True, TopLeft);
arg@327 97 continue;
arg@327 98 }
arg@327 99 if(n == 1) {
arg@327 100 c->x = sx;
arg@327 101 c->y = sy + bh;
arg@327 102 c->w = sw - 2;
arg@327 103 c->h = sh - 2 - bh;
arg@327 104 }
arg@327 105 else if(i == 0) {
arg@327 106 c->x = sx;
arg@327 107 c->y = sy + bh;
arg@327 108 c->w = mw - 2;
arg@327 109 c->h = sh - 2 - bh;
arg@327 110 }
arg@327 111 else if(h > bh) {
arg@327 112 c->x = sx + mw;
arg@327 113 c->y = sy + (i - 1) * h + bh;
arg@327 114 c->w = w - 2;
arg@327 115 if(i + 1 == n)
arg@327 116 c->h = sh - c->y - 2;
arg@327 117 else
arg@327 118 c->h = h - 2;
arg@327 119 }
arg@327 120 else { /* fallback if h < bh */
arg@327 121 c->x = sx + mw;
arg@327 122 c->y = sy + bh;
arg@327 123 c->w = w - 2;
arg@327 124 c->h = sh - 2 - bh;
arg@327 125 }
arg@327 126 resize(c, False, TopLeft);
arg@327 127 i++;
arg@327 128 }
arg@327 129 else
arg@327 130 ban(c);
arg@327 131 }
arg@446 132 if(!sel || !isvisible(sel)) {
arg@450 133 for(c = stack; c && !isvisible(c); c = c->snext);
arg@450 134 focus(c);
arg@446 135 }
arg@327 136 restack();
arg@327 137 }
arg@327 138
arg@327 139 void
arg@461 140 focusnext(Arg *arg) {
arg@327 141 Client *c;
arg@327 142
arg@327 143 if(!sel)
arg@327 144 return;
arg@327 145
arg@327 146 if(!(c = getnext(sel->next)))
arg@327 147 c = getnext(clients);
arg@327 148 if(c) {
arg@327 149 focus(c);
arg@327 150 restack();
arg@327 151 }
arg@327 152 }
arg@327 153
arg@327 154 void
arg@461 155 focusprev(Arg *arg) {
arg@327 156 Client *c;
arg@327 157
arg@327 158 if(!sel)
arg@327 159 return;
arg@327 160
arg@327 161 if(!(c = getprev(sel->prev))) {
arg@327 162 for(c = clients; c && c->next; c = c->next);
arg@327 163 c = getprev(c);
arg@327 164 }
arg@327 165 if(c) {
arg@327 166 focus(c);
arg@327 167 restack();
arg@327 168 }
arg@327 169 }
arg@327 170
arg@420 171 Bool
arg@461 172 isvisible(Client *c) {
arg@420 173 unsigned int i;
arg@420 174
arg@420 175 for(i = 0; i < ntags; i++)
arg@420 176 if(c->tags[i] && seltag[i])
arg@420 177 return True;
arg@420 178 return False;
arg@420 179 }
arg@420 180
arg@415 181 void
arg@461 182 resizecol(Arg *arg) {
arg@423 183 unsigned int n;
arg@423 184 Client *c;
arg@418 185
arg@430 186 for(n = 0, c = clients; c; c = c->next)
arg@430 187 if(isvisible(c) && !c->isfloat)
arg@423 188 n++;
arg@473 189 if(!sel || sel->isfloat || n < 2 || (arrange != dotile))
arg@415 190 return;
arg@423 191
arg@415 192 if(sel == getnext(clients)) {
arg@425 193 if(mw + arg->i > sw - 100 || mw + arg->i < 100)
arg@415 194 return;
arg@415 195 mw += arg->i;
arg@415 196 }
arg@415 197 else {
arg@425 198 if(mw - arg->i > sw - 100 || mw - arg->i < 100)
arg@415 199 return;
arg@415 200 mw -= arg->i;
arg@415 201 }
arg@415 202 arrange(NULL);
arg@415 203 }
arg@415 204
arg@327 205 void
arg@461 206 restack() {
arg@327 207 Client *c;
arg@327 208 XEvent ev;
arg@436 209
arg@437 210 if(!sel) {
arg@437 211 drawstatus();
arg@436 212 return;
arg@437 213 }
arg@436 214 if(sel->isfloat || arrange == dofloat) {
arg@436 215 XRaiseWindow(dpy, sel->win);
arg@436 216 XRaiseWindow(dpy, sel->twin);
arg@436 217 }
arg@446 218 if(arrange != dofloat)
arg@436 219 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
arg@436 220 XLowerWindow(dpy, c->twin);
arg@436 221 XLowerWindow(dpy, c->win);
arg@327 222 }
arg@327 223 drawall();
arg@327 224 XSync(dpy, False);
arg@327 225 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
arg@327 226 }
arg@327 227
arg@327 228 void
arg@461 229 togglemode(Arg *arg) {
arg@333 230 arrange = (arrange == dofloat) ? dotile : dofloat;
arg@327 231 if(sel)
arg@327 232 arrange(NULL);
arg@327 233 else
arg@327 234 drawstatus();
arg@327 235 }
arg@327 236
arg@327 237 void
arg@461 238 toggleview(Arg *arg) {
arg@327 239 unsigned int i;
arg@327 240
arg@327 241 seltag[arg->i] = !seltag[arg->i];
arg@327 242 for(i = 0; i < ntags && !seltag[i]; i++);
arg@327 243 if(i == ntags)
arg@327 244 seltag[arg->i] = True; /* cannot toggle last view */
arg@381 245 reorder();
arg@327 246 arrange(NULL);
arg@327 247 }
arg@327 248
arg@327 249 void
arg@461 250 view(Arg *arg) {
arg@327 251 unsigned int i;
arg@327 252
arg@327 253 for(i = 0; i < ntags; i++)
arg@327 254 seltag[i] = False;
arg@327 255 seltag[arg->i] = True;
arg@381 256 reorder();
arg@327 257 arrange(NULL);
arg@327 258 }
arg@327 259
arg@327 260 void
arg@461 261 viewall(Arg *arg) {
arg@395 262 unsigned int i;
arg@395 263
arg@395 264 for(i = 0; i < ntags; i++)
arg@395 265 seltag[i] = True;
arg@397 266 reorder();
arg@395 267 arrange(NULL);
arg@395 268 }
arg@395 269
arg@395 270 void
arg@461 271 zoom(Arg *arg) {
arg@473 272 int tmp;
arg@423 273 unsigned int n;
arg@423 274 Client *c;
arg@473 275 XEvent ev;
arg@473 276
arg@473 277 if(!sel)
arg@473 278 return;
arg@473 279
arg@473 280 if(sel->isfloat || (arrange == dofloat)) {
arg@473 281 tmp = sel->x; sel->x = sel->rx; sel->rx = tmp;
arg@473 282 tmp = sel->y; sel->y = sel->ry; sel->ry = tmp;
arg@473 283 tmp = sel->w; sel->w = sel->rw; sel->rw = tmp;
arg@473 284 tmp = sel->h; sel->h = sel->rh; sel->rh = tmp;
arg@473 285 resize(sel, True, TopLeft);
arg@473 286 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
arg@473 287 return;
arg@473 288 }
arg@327 289
arg@430 290 for(n = 0, c = clients; c; c = c->next)
arg@430 291 if(isvisible(c) && !c->isfloat)
arg@423 292 n++;
arg@473 293 if(n < 2 || (arrange != dotile))
arg@327 294 return;
arg@327 295
arg@430 296 if((c = sel) == nexttiled(clients))
arg@433 297 if(!(c = nexttiled(c->next)))
arg@429 298 return;
arg@443 299 detach(c);
arg@443 300 if(clients)
arg@443 301 clients->prev = c;
arg@443 302 c->next = clients;
arg@443 303 clients = c;
arg@378 304 focus(c);
arg@327 305 arrange(NULL);
arg@327 306 }