add uicb_setncols(), clean config, really use config in tile.c
[awesome.git] / layout.c
blobe6ce25287785b74957bc90060da1672f927e9a7c
1 /*
2 * layout.c - layout management
3 *
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include <X11/Xatom.h>
23 #include <X11/Xutil.h>
25 #include "awesome.h"
26 #include "layout.h"
27 #include "tag.h"
28 #include "layouts/floating.h"
30 /* extern */
31 extern Client *clients, *sel; /* global client list */
33 void
34 arrange(Display * disp, DC *drawcontext, awesome_config *awesomeconf)
36 Client *c;
38 for(c = clients; c; c = c->next)
39 if(isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags))
40 unban(c);
41 else
42 ban(c);
43 awesomeconf->current_layout->arrange(disp, awesomeconf);
44 focus(disp, drawcontext, NULL, True, awesomeconf);
45 restack(disp, drawcontext, awesomeconf);
48 void
49 uicb_focusnext(Display *disp __attribute__ ((unused)),
50 DC *drawcontext,
51 awesome_config * awesomeconf,
52 const char *arg __attribute__ ((unused)))
54 Client *c;
56 if(!sel)
57 return;
58 for(c = sel->next; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
59 if(!c)
60 for(c = clients; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
61 if(c)
63 focus(c->display, drawcontext, c, True, awesomeconf);
64 restack(c->display, drawcontext, awesomeconf);
68 void
69 uicb_focusprev(Display *disp __attribute__ ((unused)),
70 DC *drawcontext,
71 awesome_config *awesomeconf,
72 const char *arg __attribute__ ((unused)))
74 Client *c;
76 if(!sel)
77 return;
78 for(c = sel->prev; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
79 if(!c)
81 for(c = clients; c && c->next; c = c->next);
82 for(; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
84 if(c)
86 focus(c->display, drawcontext, c, True, awesomeconf);
87 restack(c->display, drawcontext, awesomeconf);
91 void
92 loadawesomeprops(Display *disp, awesome_config * awesomeconf)
94 int i;
95 char *prop;
97 prop = p_new(char, awesomeconf->ntags + 1);
99 if(xgettextprop(disp, DefaultRootWindow(disp), AWESOMEPROPS_ATOM(disp), prop, awesomeconf->ntags + 1))
100 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
101 awesomeconf->selected_tags[i] = prop[i] == '1';
103 p_delete(&prop);
106 void
107 restack(Display * disp, DC * drawcontext, awesome_config *awesomeconf)
109 Client *c;
110 XEvent ev;
111 XWindowChanges wc;
113 drawstatus(disp, drawcontext, awesomeconf);
114 if(!sel)
115 return;
116 if(sel->isfloating || IS_ARRANGE(floating))
117 XRaiseWindow(disp, sel->win);
118 if(!IS_ARRANGE(floating))
120 wc.stack_mode = Below;
121 wc.sibling = awesomeconf->statusbar.window;
122 if(!sel->isfloating)
124 XConfigureWindow(disp, sel->win, CWSibling | CWStackMode, &wc);
125 wc.sibling = sel->win;
127 for(c = clients; c; c = c->next)
129 if(!IS_TILED(c, awesomeconf->selected_tags, awesomeconf->ntags) || c == sel)
130 continue;
131 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
132 wc.sibling = c->win;
135 XSync(disp, False);
136 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
139 void
140 saveawesomeprops(Display *disp, awesome_config *awesomeconf)
142 int i;
143 char *prop;
145 prop = p_new(char, awesomeconf->ntags + 1);
146 for(i = 0; i < awesomeconf->ntags; i++)
147 prop[i] = awesomeconf->selected_tags[i] ? '1' : '0';
148 prop[i] = '\0';
149 XChangeProperty(disp, DefaultRootWindow(disp),
150 AWESOMEPROPS_ATOM(disp), XA_STRING, 8,
151 PropModeReplace, (unsigned char *) prop, i);
152 p_delete(&prop);
155 void
156 uicb_setlayout(Display *disp,
157 DC *drawcontext,
158 awesome_config * awesomeconf,
159 const char *arg)
161 int i, j;
162 Client *c;
164 if(!arg)
166 if(!(++awesomeconf->current_layout)->symbol)
167 awesomeconf->current_layout = &awesomeconf->layouts[0];
169 else
171 i = strtol(arg, NULL, 10);
172 if(i < 0 || i >= awesomeconf->nlayouts)
173 return;
174 awesomeconf->current_layout = &awesomeconf->layouts[i];
177 for(c = clients; c; c = c->next)
178 c->ftview = True;
180 if(sel)
181 arrange(disp, drawcontext, awesomeconf);
182 else
183 drawstatus(disp, drawcontext, awesomeconf);
185 saveawesomeprops(disp, awesomeconf);
187 for(j = 0; j < awesomeconf->ntags; j++)
188 if (awesomeconf->selected_tags[j])
189 awesomeconf->tag_layouts[j] = awesomeconf->current_layout;
192 void
193 uicb_togglebar(Display *disp,
194 DC *drawcontext,
195 awesome_config *awesomeconf,
196 const char *arg __attribute__ ((unused)))
198 if(awesomeconf->statusbar.position == BarOff)
199 awesomeconf->statusbar.position = (awesomeconf->statusbar.position == BarOff) ? BarTop : awesomeconf->statusbar_default_position;
200 else
201 awesomeconf->statusbar.position = BarOff;
202 updatebarpos(disp, awesomeconf->statusbar);
203 arrange(disp, drawcontext, awesomeconf);
206 static void
207 maximize(int x, int y, int w, int h, DC *drawcontext, awesome_config *awesomeconf)
209 XEvent ev;
211 if(!sel)
212 return;
214 if((sel->ismax = !sel->ismax))
216 sel->wasfloating = sel->isfloating;
217 sel->isfloating = True;
218 sel->rx = sel->x;
219 sel->ry = sel->y;
220 sel->rw = sel->w;
221 sel->rh = sel->h;
222 resize(sel, x, y, w, h, True);
224 else if(sel->isfloating)
225 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
226 else
227 sel->isfloating = False;
229 drawstatus(sel->display, drawcontext, awesomeconf);
231 while(XCheckMaskEvent(sel->display, EnterWindowMask, &ev));
234 void
235 uicb_togglemax(Display *disp,
236 DC *drawcontext,
237 awesome_config *awesomeconf,
238 const char *arg __attribute__ ((unused)))
240 maximize(get_windows_area_x(awesomeconf->statusbar),
241 get_windows_area_y(awesomeconf->statusbar),
242 get_windows_area_width(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
243 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
244 drawcontext,
245 awesomeconf);
248 void
249 uicb_toggleverticalmax(Display *disp,
250 DC *drawcontext,
251 awesome_config *awesomeconf,
252 const char *arg __attribute__ ((unused)))
254 if(sel)
255 maximize(sel->x,
256 get_windows_area_y(awesomeconf->statusbar),
257 sel->w,
258 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
259 drawcontext,
260 awesomeconf);
264 void
265 uicb_togglehorizontalmax(Display *disp,
266 DC *drawcontext,
267 awesome_config *awesomeconf,
268 const char *arg __attribute__ ((unused)))
270 if(sel)
271 maximize(get_windows_area_x(awesomeconf->statusbar),
272 sel->y,
273 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
274 sel->h,
275 drawcontext,
276 awesomeconf);
279 void
280 uicb_zoom(Display *disp __attribute__ ((unused)),
281 DC *drawcontext __attribute__ ((unused)),
282 awesome_config *awesomeconf,
283 const char *arg __attribute__ ((unused)))
285 if(!sel)
286 return;
287 detach(sel);
288 attach(sel);
289 focus(sel->display, drawcontext, sel, True, awesomeconf);
290 arrange(sel->display, drawcontext, awesomeconf);