JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
removed VRATIO, NMASTER, inc*(), renamed HRATIO into MASTER, see mailinglist for...
[dwm.git] / layout.c
1 /* See LICENSE file for copyright and license details. */
2 #include "dwm.h"
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 unsigned int blw = 0;
7 Layout *lt = NULL;
8
9 /* static */
10
11 static unsigned int nlayouts = 0;
12
13 LAYOUTS
14
15 /* extern */
16
17 void
18 floating(const char *arg) {
19         Client *c;
20
21         if(lt->arrange != floating)
22                 return;
23
24         for(c = clients; c; c = c->next)
25                 if(isvisible(c)) {
26                         unban(c);
27                         resize(c, c->x, c->y, c->w, c->h, True);
28                 }
29                 else
30                         ban(c);
31         focus(NULL);
32         restack();
33 }
34
35 void
36 focusclient(const char *arg) {
37         Client *c;
38    
39         if(!sel || !arg)
40                 return;
41         if(atoi(arg) < 0) {
42                 for(c = sel->prev; c && !isvisible(c); c = c->prev);
43                 if(!c) {
44                         for(c = clients; c && c->next; c = c->next);
45                         for(; c && !isvisible(c); c = c->prev);
46                 }
47         }
48         else {
49                 for(c = sel->next; c && !isvisible(c); c = c->next);
50                 if(!c)
51                         for(c = clients; c && !isvisible(c); c = c->next);
52         }
53         if(c) {
54                 focus(c);
55                 restack();
56         }
57 }
58
59 void
60 initlayouts(void) {
61         unsigned int i, w;
62
63         lt = &layout[0];
64         nlayouts = sizeof layout / sizeof layout[0];
65         for(blw = i = 0; i < nlayouts; i++) {
66                 w = textw(layout[i].symbol);
67                 if(w > blw)
68                         blw = w;
69         }
70 }
71
72 Client *
73 nexttiled(Client *c) {
74         for(; c && (c->isfloating || !isvisible(c)); c = c->next);
75         return c;
76 }
77
78 void
79 restack(void) {
80         Client *c;
81         XEvent ev;
82         XWindowChanges wc;
83
84         drawstatus();
85         if(!sel)
86                 return;
87         if(sel->isfloating || lt->arrange == floating)
88                 XRaiseWindow(dpy, sel->win);
89         if(lt->arrange != floating) {
90                 wc.stack_mode = Below;
91                 wc.sibling = barwin;
92                 if(!sel->isfloating) {
93                         XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc);
94                         wc.sibling = sel->win;
95                 }
96                 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
97                         if(c == sel)
98                                 continue;
99                         XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
100                         wc.sibling = c->win;
101                 }
102         }
103         XSync(dpy, False);
104         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
105 }
106
107 void
108 setlayout(const char *arg) {
109         int i;
110
111         if(!arg) {
112                 lt++;
113                 if(lt == layout + nlayouts)
114                         lt = layout;
115         }
116         else {
117                 i = atoi(arg);
118                 if(i < 0 || i >= nlayouts)
119                         return;
120                 lt = &layout[i];
121         }
122         if(sel)
123                 lt->arrange(NULL);
124         else
125                 drawstatus();
126 }
127
128 void
129 tile(const char *arg) {
130         static double master = MASTER;
131         double delta;
132         unsigned int i, n, nx, ny, nw, nh, mw, th;
133         Client *c;
134
135         if(lt->arrange != tile)
136                 return;
137
138         /* arg handling, manipulate master */
139         if(arg && (1 == sscanf(arg, "%lf", &delta))) {
140                 if(delta + master > 0.1 && delta + master < 0.9)
141                         master += delta;
142         }
143
144         for(n = 0, c = nexttiled(clients); c; c = nexttiled(c->next))
145                 n++;
146
147         /* window geoms */
148         mw = (n == 1) ? waw : master * waw;
149         th = (n > 1) ? wah / (n - 1) : 0;
150         if(n > 1 && th < bh)
151                 th = wah;
152
153         nx = wax;
154         ny = way;
155         for(i = 0, c = clients; c; c = c->next)
156                 if(isvisible(c)) {
157                         unban(c);
158                         if(c->isfloating)
159                                 continue;
160                         c->ismax = False;
161                         if(i == 0) { /* master */
162                                 nw = mw - 2 * c->border;
163                                 nh = wah - 2 * c->border;
164                         }
165                         else {  /* tile window */
166                                 if(i == 1) {
167                                         ny = way;
168                                         nx += mw;
169                                 }
170                                 nw = waw - mw - 2 * c->border;
171                                 if(i + 1 == n) /* remainder */
172                                         nh = (way + wah) - ny - 2 * c->border;
173                                 else
174                                         nh = th - 2 * c->border;
175                         }
176                         resize(c, nx, ny, nw, nh, False);
177                         if(n > 1 && th != wah)
178                                 ny += nh;
179                         i++;
180                 }
181                 else
182                         ban(c);
183         focus(NULL);
184         restack();
185 }
186
187 void
188 togglebar(const char *arg) {
189         if(bpos == BarOff)
190                 bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
191         else
192                 bpos = BarOff;
193         updatebarpos();
194         lt->arrange(NULL);
195 }
196
197 void
198 togglemax(const char *arg) {
199         XEvent ev;
200
201         if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
202                 return;
203         if((sel->ismax = !sel->ismax)) {
204                 sel->rx = sel->x;
205                 sel->ry = sel->y;
206                 sel->rw = sel->w;
207                 sel->rh = sel->h;
208                 resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
209         }
210         else
211                 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
212         drawstatus();
213         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
214 }
215
216 void
217 zoom(const char *arg) {
218         Client *c;
219
220         if(!sel || lt->arrange == floating || sel->isfloating)
221                 return;
222         if((c = sel) == nexttiled(clients))
223                 if(!(c = nexttiled(c->next)))
224                         return;
225         detach(c);
226         attach(c);
227         focus(c);
228         lt->arrange(NULL);
229 }