dwm-meillo

annotate view.c @ 384:126e78129f1d

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