aewl

annotate view.c @ 381:b00cc483d13b

still something wrong with reorder()
author Anselm R. Garbe <arg@10kloc.org>
date Tue, 29 Aug 2006 13:40:09 +0200
parents 4bf79305d675
children 76b62c0c8c11
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@381 9 static void
arg@381 10 reorder()
arg@380 11 {
arg@381 12 Client *c, *orig, *p;
arg@380 13
arg@381 14 orig = clients;
arg@381 15 clients = NULL;
arg@381 16
arg@381 17 while((c = orig)) {
arg@381 18 orig = orig->next;
arg@381 19 detach(c);
arg@381 20
arg@381 21 for(p = clients; p && p->next && p->weight <= c->weight; p = p->next);
arg@381 22 c->prev = p;
arg@381 23 if(p) {
arg@381 24 if((c->next = p->next))
arg@381 25 c->next->prev = c;
arg@381 26 p->next = c;
arg@381 27 }
arg@381 28 else
arg@381 29 clients = c;
arg@380 30 }
arg@380 31 }
arg@380 32
arg@327 33 /* extern */
arg@327 34
arg@327 35 void (*arrange)(Arg *) = DEFMODE;
arg@327 36
arg@327 37 void
arg@378 38 detach(Client *c)
arg@378 39 {
arg@378 40 if(c->prev)
arg@378 41 c->prev->next = c->next;
arg@378 42 if(c->next)
arg@378 43 c->next->prev = c->prev;
arg@378 44 if(c == clients)
arg@378 45 clients = c->next;
arg@378 46 c->next = c->prev = NULL;
arg@378 47 }
arg@378 48
arg@378 49 void
arg@327 50 dofloat(Arg *arg)
arg@327 51 {
arg@327 52 Client *c;
arg@327 53
arg@327 54 for(c = clients; c; c = c->next) {
arg@327 55 c->ismax = False;
arg@327 56 if(isvisible(c)) {
arg@327 57 resize(c, True, TopLeft);
arg@327 58 }
arg@327 59 else
arg@327 60 ban(c);
arg@327 61 }
arg@327 62 if(!sel || !isvisible(sel))
arg@327 63 sel = getnext(clients);
arg@327 64 if(sel)
arg@327 65 focus(sel);
arg@327 66 else
arg@327 67 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
arg@327 68 restack();
arg@327 69 }
arg@327 70
arg@327 71 void
arg@327 72 dotile(Arg *arg)
arg@327 73 {
arg@327 74 int h, i, n, w;
arg@327 75 Client *c;
arg@327 76
arg@327 77 w = sw - mw;
arg@327 78 for(n = 0, c = clients; c; c = c->next)
arg@327 79 if(isvisible(c) && !c->isfloat)
arg@327 80 n++;
arg@327 81
arg@327 82 if(n > 1)
arg@327 83 h = (sh - bh) / (n - 1);
arg@327 84 else
arg@327 85 h = sh - bh;
arg@327 86
arg@327 87 for(i = 0, c = clients; c; c = c->next) {
arg@327 88 c->ismax = False;
arg@327 89 if(isvisible(c)) {
arg@327 90 if(c->isfloat) {
arg@327 91 resize(c, True, TopLeft);
arg@327 92 continue;
arg@327 93 }
arg@327 94 if(n == 1) {
arg@327 95 c->x = sx;
arg@327 96 c->y = sy + bh;
arg@327 97 c->w = sw - 2;
arg@327 98 c->h = sh - 2 - bh;
arg@327 99 }
arg@327 100 else if(i == 0) {
arg@327 101 c->x = sx;
arg@327 102 c->y = sy + bh;
arg@327 103 c->w = mw - 2;
arg@327 104 c->h = sh - 2 - bh;
arg@327 105 }
arg@327 106 else if(h > bh) {
arg@327 107 c->x = sx + mw;
arg@327 108 c->y = sy + (i - 1) * h + bh;
arg@327 109 c->w = w - 2;
arg@327 110 if(i + 1 == n)
arg@327 111 c->h = sh - c->y - 2;
arg@327 112 else
arg@327 113 c->h = h - 2;
arg@327 114 }
arg@327 115 else { /* fallback if h < bh */
arg@327 116 c->x = sx + mw;
arg@327 117 c->y = sy + bh;
arg@327 118 c->w = w - 2;
arg@327 119 c->h = sh - 2 - bh;
arg@327 120 }
arg@327 121 resize(c, False, TopLeft);
arg@327 122 i++;
arg@327 123 }
arg@327 124 else
arg@327 125 ban(c);
arg@327 126 }
arg@327 127 if(!sel || !isvisible(sel))
arg@327 128 sel = getnext(clients);
arg@327 129 if(sel)
arg@327 130 focus(sel);
arg@327 131 else
arg@327 132 XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
arg@327 133 restack();
arg@327 134 }
arg@327 135
arg@327 136 void
arg@327 137 focusnext(Arg *arg)
arg@327 138 {
arg@327 139 Client *c;
arg@327 140
arg@327 141 if(!sel)
arg@327 142 return;
arg@327 143
arg@327 144 if(!(c = getnext(sel->next)))
arg@327 145 c = getnext(clients);
arg@327 146 if(c) {
arg@327 147 focus(c);
arg@327 148 restack();
arg@327 149 }
arg@327 150 }
arg@327 151
arg@327 152 void
arg@327 153 focusprev(Arg *arg)
arg@327 154 {
arg@327 155 Client *c;
arg@327 156
arg@327 157 if(!sel)
arg@327 158 return;
arg@327 159
arg@327 160 if(!(c = getprev(sel->prev))) {
arg@327 161 for(c = clients; c && c->next; c = c->next);
arg@327 162 c = getprev(c);
arg@327 163 }
arg@327 164 if(c) {
arg@327 165 focus(c);
arg@327 166 restack();
arg@327 167 }
arg@327 168 }
arg@327 169
arg@327 170 Bool
arg@327 171 isvisible(Client *c)
arg@327 172 {
arg@327 173 unsigned int i;
arg@327 174
arg@327 175 for(i = 0; i < ntags; i++)
arg@327 176 if(c->tags[i] && seltag[i])
arg@327 177 return True;
arg@327 178 return False;
arg@327 179 }
arg@327 180
arg@327 181 void
arg@327 182 restack()
arg@327 183 {
arg@327 184 static unsigned int nwins = 0;
arg@327 185 static Window *wins = NULL;
arg@327 186 unsigned int f, fi, m, mi, n;
arg@327 187 Client *c;
arg@327 188 XEvent ev;
arg@327 189
arg@327 190 for(f = 0, m = 0, c = clients; c; c = c->next)
arg@327 191 if(isvisible(c)) {
arg@327 192 if(c->isfloat || arrange == dofloat)
arg@327 193 f++;
arg@327 194 else
arg@327 195 m++;
arg@327 196 }
arg@327 197 if(!(n = 2 * (f + m))) {
arg@327 198 drawstatus();
arg@327 199 return;
arg@327 200 }
arg@327 201 if(nwins < n) {
arg@327 202 nwins = n;
arg@327 203 wins = erealloc(wins, nwins * sizeof(Window));
arg@327 204 }
arg@327 205
arg@327 206 fi = 0;
arg@327 207 mi = 2 * f;
arg@327 208 if(sel->isfloat || arrange == dofloat) {
arg@342 209 wins[fi++] = sel->twin;
arg@327 210 wins[fi++] = sel->win;
arg@327 211 }
arg@327 212 else {
arg@342 213 wins[mi++] = sel->twin;
arg@327 214 wins[mi++] = sel->win;
arg@327 215 }
arg@327 216 for(c = clients; c; c = c->next)
arg@327 217 if(isvisible(c) && c != sel) {
arg@327 218 if(c->isfloat || arrange == dofloat) {
arg@342 219 wins[fi++] = c->twin;
arg@327 220 wins[fi++] = c->win;
arg@327 221 }
arg@327 222 else {
arg@342 223 wins[mi++] = c->twin;
arg@327 224 wins[mi++] = c->win;
arg@327 225 }
arg@327 226 }
arg@327 227 XRestackWindows(dpy, wins, n);
arg@327 228 drawall();
arg@327 229 XSync(dpy, False);
arg@327 230 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
arg@327 231 }
arg@327 232
arg@327 233 void
arg@327 234 togglemode(Arg *arg)
arg@327 235 {
arg@333 236 arrange = (arrange == dofloat) ? dotile : dofloat;
arg@327 237 if(sel)
arg@327 238 arrange(NULL);
arg@327 239 else
arg@327 240 drawstatus();
arg@327 241 }
arg@327 242
arg@327 243 void
arg@327 244 toggleview(Arg *arg)
arg@327 245 {
arg@327 246 unsigned int i;
arg@327 247
arg@327 248 seltag[arg->i] = !seltag[arg->i];
arg@327 249 for(i = 0; i < ntags && !seltag[i]; i++);
arg@327 250 if(i == ntags)
arg@327 251 seltag[arg->i] = True; /* cannot toggle last view */
arg@381 252 reorder();
arg@327 253 arrange(NULL);
arg@327 254 }
arg@327 255
arg@327 256 void
arg@327 257 view(Arg *arg)
arg@327 258 {
arg@327 259 unsigned int i;
arg@381 260 Client *c;
arg@327 261
arg@327 262 for(i = 0; i < ntags; i++)
arg@327 263 seltag[i] = False;
arg@327 264 seltag[arg->i] = True;
arg@381 265 reorder();
arg@327 266 arrange(NULL);
arg@327 267 }
arg@327 268
arg@327 269 void
arg@327 270 zoom(Arg *arg)
arg@327 271 {
arg@378 272 Client *c = sel;
arg@327 273
arg@378 274 if(!c || (arrange != dotile) || c->isfloat || c->ismax)
arg@327 275 return;
arg@327 276
arg@378 277 if(c == getnext(clients))
arg@378 278 if(!(c = getnext(c->next)))
arg@327 279 return;
arg@378 280 detach(c);
arg@381 281 c->next = clients;
arg@381 282 clients->prev = c;
arg@381 283 clients = c;
arg@378 284 focus(c);
arg@327 285 arrange(NULL);
arg@327 286 }