Xinqi Bao's Git

cleaned up settags-handling
[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 unsigned int ltidx = 0; /* default */
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 layouts[ltidx].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 layouts[ltidx].symbol;
80 }
81
82 Bool
83 isfloating(void) {
84 return layouts[ltidx].arrange == floating;
85 }
86
87 Bool
88 isarrange(void (*func)())
89 {
90 return func == layouts[ltidx].arrange;
91 }
92
93 void
94 initlayouts(void) {
95 unsigned int i, w;
96
97 /* TODO deserialize ltidx if present */
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 || isfloating())
122 XRaiseWindow(dpy, sel->win);
123 if(!isfloating()) {
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 if(++ltidx == nlayouts)
147 ltidx = 0;;
148 }
149 else {
150 i = atoi(arg);
151 if(i < 0 || i >= nlayouts)
152 return;
153 ltidx = i;
154 }
155 if(sel)
156 arrange();
157 else
158 drawstatus();
159 }
160
161 void
162 togglebar(const char *arg) {
163 if(bpos == BarOff)
164 bpos = (BARPOS == BarOff) ? BarTop : BARPOS;
165 else
166 bpos = BarOff;
167 updatebarpos();
168 arrange();
169 }
170
171 void
172 togglemax(const char *arg) {
173 XEvent ev;
174
175 if(!sel || (!isfloating() && !sel->isfloating) || sel->isfixed)
176 return;
177 if((sel->ismax = !sel->ismax)) {
178 sel->rx = sel->x;
179 sel->ry = sel->y;
180 sel->rw = sel->w;
181 sel->rh = sel->h;
182 resize(sel, wax, way, waw - 2 * sel->border, wah - 2 * sel->border, True);
183 }
184 else
185 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
186 drawstatus();
187 while(XCheckMaskEvent(dpy, EnterWindowMask, &ev));
188 }