Xinqi Bao's Git

let not overlap the borders
[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 + 2 * c->border;
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 }