JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
applied Jukka Salmi's setmwfact patch
[dwm.git] / layout.c
1 /* See LICENSE file for copyright and license details. */
2 #include "dwm.h"
3 #include <stdlib.h>
4
5 /* static */
6
7 typedef struct {
8         const char *symbol;
9         void (*arrange)(void);
10 } Layout;
11
12 unsigned int blw = 0;
13 static Layout *lt = NULL;
14
15 static void
16 floating(void) { /* default floating layout */
17         Client *c;
18
19         for(c = clients; c; c = c->next)
20                 if(isvisible(c))
21                         resize(c, c->x, c->y, c->w, c->h, True);
22 }
23
24 static unsigned int nlayouts = 0;
25
26 LAYOUTS
27
28 /* extern */
29
30 void
31 arrange(void) {
32         Client *c;
33
34         for(c = clients; c; c = c->next)
35                 if(isvisible(c))
36                         unban(c);
37                 else
38                         ban(c);
39         lt->arrange();
40         focus(NULL);
41         restack();
42 }
43
44 void
45 focusnext(const char *arg) {
46         Client *c;
47
48         if(!sel)
49                 return;
50         for(c = sel->next; c && !isvisible(c); c = c->next);
51         if(!c)
52                 for(c = clients; c && !isvisible(c); c = c->next);
53         if(c) {
54                 focus(c);
55                 restack();
56         }
57 }
58
59 void
60 focusprev(const char *arg) {
61         Client *c;
62
63         if(!sel)
64                 return;
65         for(c = sel->prev; c && !isvisible(c); c = c->prev);
66         if(!c) {
67                 for(c = clients; c && c->next; c = c->next);
68                 for(; c && !isvisible(c); c = c->prev);
69         }
70         if(c) {
71                 focus(c);
72                 restack();
73         }
74 }
75
76 const char *
77 getsymbol(void)
78 {
79         return lt->symbol;
80 }
81
82 Bool
83 isfloating(void) {
84         return lt->arrange == floating;
85 }
86
87 Bool
88 isarrange(void (*func)())
89 {
90         return func == lt->arrange;
91 }
92
93 void
94 initlayouts(void) {
95         unsigned int i, w;
96
97         lt = &layouts[0];
98         nlayouts = sizeof layouts / sizeof layouts[0];
99         for(blw = i = 0; i < nlayouts; i++) {
100                 w = textw(layouts[i].symbol);
101                 if(w > blw)
102                         blw = w;
103         }
104 }
105
106 Client *
107 nexttiled(Client *c) {
108         for(; c && (c->isfloating || !isvisible(c)); c = c->next);
109         return c;
110 }
111
112 void
113 restack(void) {
114         Client *c;
115         XEvent ev;
116         XWindowChanges wc;
117
118         drawstatus();
119         if(!sel)
120                 return;
121         if(sel->isfloating || lt->arrange == floating)
122                 XRaiseWindow(dpy, sel->win);
123         if(lt->arrange != floating) {
124                 wc.stack_mode = Below;
125                 wc.sibling = barwin;
126                 if(!sel->isfloating) {
127                         XConfigureWindow(dpy, sel->win, CWSibling | CWStackMode, &wc);
128                         wc.sibling = sel->win;
129                 }
130                 for(c = nexttiled(clients); c; c = nexttiled(c->next)) {
131                         if(c == sel)
132                                 continue;
133                         XConfigureWindow(dpy, c->win, CWSibling | CWStackMode, &wc);
134                         wc.sibling = c->win;
135                 }
136         }
137         XSync(dpy, False);
138         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
139 }
140
141 void
142 setlayout(const char *arg) {
143         int i;
144
145         if(!arg) {
146                 lt++;
147                 if(lt == layouts + nlayouts)
148                         lt = layouts;
149         }
150         else {
151                 i = atoi(arg);
152                 if(i < 0 || i >= nlayouts)
153                         return;
154                 lt = &layouts[i];
155         }
156         if(sel)
157                 arrange();
158         else
159                 drawstatus();
160 }
161
162 void
163 togglebar(const char *arg) {
164         if(bpos == BarOff)
165                 bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
166         else
167                 bpos = BarOff;
168         updatebarpos();
169         arrange();
170 }
171
172 void
173 togglemax(const char *arg) {
174         XEvent ev;
175
176         if(!sel || (lt->arrange != floating && !sel->isfloating) || sel->isfixed)
177                 return;
178         if((sel->ismax = !sel->ismax)) {
179                 sel->rx = sel->x;
180                 sel->ry = sel->y;
181                 sel->rw = sel->w;
182                 sel->rh = sel->h;
183                 resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
184         }
185         else
186                 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
187         drawstatus();
188         while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
189 }