JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
some more refactoring
[dwm.git] / view.c
1 /* (C)opyright MMVI-MMVII Anselm R. Garbe <garbeam at gmail dot com>
2  * See LICENSE file for license details.
3  */
4 #include "dwm.h"
5
6 /* extern */
7
8 void (*arrange)(void) = DEFMODE;
9
10 void
11 attach(Client *c) {
12         if(clients)
13                 clients->prev = c;
14         c->next = clients;
15         clients = c;
16 }
17
18 void
19 attachstack(Client *c) {
20         c->snext = stack;
21         stack = c;
22 }
23
24 void
25 dofloat(void) {
26         Client *c;
27
28         for(c = clients; c; c = c->next) {
29                 if(isvisible(c)) {
30                         if(c->isbanned)
31                                 XMoveWindow(dpy, c->win, c->x, c->y);
32                         c->isbanned = False;
33                         resize(c, c->x, c->y, c->w, c->h, True);
34                 }
35                 else {
36                         c->isbanned = True;
37                         XMoveWindow(dpy, c->win, c->x + 2 * sw, c->y);
38                 }
39         }
40         if(!sel || !isvisible(sel)) {
41                 for(c = stack; c && !isvisible(c); c = c->snext);
42                 focus(c);
43         }
44         restack();
45 }
46
47 void
48 detach(Client *c) {
49         if(c->prev)
50                 c->prev->next = c->next;
51         if(c->next)
52                 c->next->prev = c->prev;
53         if(c == clients)
54                 clients = c->next;
55         c->next = c->prev = NULL;
56 }
57
58 void
59 detachstack(Client *c) {
60         Client **tc;
61         for(tc=&stack; *tc && *tc != c; tc=&(*tc)->snext);
62         *tc = c->snext;
63 }
64
65 void
66 focusnext(Arg *arg) {
67         Client *c;
68    
69         if(!sel)
70                 return;
71         for(c = sel->next; c && !isvisible(c); c = c->next);
72         if(!c)
73                 for(c = clients; c && !isvisible(c); c = c->next);
74         if(c) {
75                 focus(c);
76                 restack();
77         }
78 }
79
80 void
81 focusprev(Arg *arg) {
82         Client *c;
83
84         if(!sel)
85                 return;
86         for(c = sel->prev; c && !isvisible(c); c = c->prev);
87         if(!c) {
88                 for(c = clients; c && c->next; c = c->next);
89                 for(; c && !isvisible(c); c = c->prev);
90         }
91         if(c) {
92                 focus(c);
93                 restack();
94         }
95 }
96
97 Client *
98 getclient(Window w) {
99         Client *c;
100
101         for(c = clients; c; c = c->next)
102                 if(c->win == w)
103                         return c;
104         return NULL;
105 }
106
107 Bool
108 isvisible(Client *c) {
109         unsigned int i;
110
111         for(i = 0; i < ntags; i++)
112                 if(c->tags[i] && seltag[i])
113                         return True;
114         return False;
115 }
116
117 Client *
118 nextmanaged(Client *c) {
119         for(; c && (c->isfloat || !isvisible(c)); c = c->next);
120         return c;
121 }
122
123 void
124 restack(void) {
125         Client *c;
126         XEvent ev;
127
128         drawstatus();
129         if(!sel)
130                 return;
131         if(sel->isfloat || arrange == dofloat)
132                 XRaiseWindow(dpy, sel->win);
133         if(arrange != dofloat) {
134                 if(!sel->isfloat)
135                         XLowerWindow(dpy, sel->win);
136                 for(c = nextmanaged(clients); c; c = nextmanaged(c->next)) {
137                         if(c == sel)
138                                 continue;
139                         XLowerWindow(dpy, c->win);
140                 }
141         }
142         XSync(dpy, False);
143         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
144 }
145
146 void
147 togglefloat(Arg *arg) {
148         if(!sel || arrange == dofloat)
149                 return;
150         sel->isfloat = !sel->isfloat;
151         arrange();
152 }
153
154 void
155 togglemode(Arg *arg) {
156         arrange = (arrange == dofloat) ? dotile : dofloat;
157         if(sel)
158                 arrange();
159         else
160                 drawstatus();
161 }
162
163 void
164 toggleview(Arg *arg) {
165         unsigned int i;
166
167         seltag[arg->i] = !seltag[arg->i];
168         for(i = 0; i < ntags && !seltag[i]; i++);
169         if(i == ntags)
170                 seltag[arg->i] = True; /* cannot toggle last view */
171         arrange();
172 }
173
174 void
175 view(Arg *arg) {
176         unsigned int i;
177
178         for(i = 0; i < ntags; i++)
179                 seltag[i] = (arg->i == -1) ? True : False;
180         if(arg->i >= 0 && arg->i < ntags)
181                 seltag[arg->i] = True;
182         arrange();
183 }
184