statusbar drawable is no more stored but dynamicaly created; this fix a problem with...
[awesome.git] / layout.c
blob779537c6bc8890b1dc6ba5ad29bc179af5316d01
1 /*
2 * layout.c - layout management
4 * Copyright © 2007 Julien Danjou <julien@danjou.info>
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 "screen.h"
26 #include "layout.h"
27 #include "tag.h"
28 #include "util.h"
29 #include "statusbar.h"
30 #include "layouts/floating.h"
32 /** Find the index of the first currently selected tag
33 * \param tags the array of tags to search
34 * \param ntags number of elements in above array
35 * \return tag
37 Tag *
38 get_current_tag(Tag *tags, int ntags)
40 int i;
42 for(i = 0; i < ntags; i++)
43 if(tags[i].selected == True)
44 return &tags[i];
46 return NULL;
49 /** Arrange windows following current selected layout
50 * \param disp display ref
51 * \param awesomeconf awesome config
53 void
54 arrange(awesome_config *awesomeconf)
56 Client *c;
57 Tag *curtag = get_current_tag(awesomeconf->tags, awesomeconf->ntags);
59 for(c = *awesomeconf->clients; c; c = c->next)
61 if(isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags))
62 client_unban(c);
63 /* we don't touch other screens windows */
64 else if(c->screen == awesomeconf->screen)
65 client_ban(c);
68 curtag->layout->arrange(awesomeconf);
69 focus(curtag->client_sel, True, awesomeconf);
70 restack(awesomeconf);
73 Layout *
74 get_current_layout(Tag *tags, int ntags)
76 Tag *curtag;
78 if ((curtag = get_current_tag(tags, ntags)))
79 return curtag->layout;
81 return NULL;
84 void
85 uicb_focusnext(awesome_config * awesomeconf,
86 const char *arg __attribute__ ((unused)))
88 Client *c, *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
90 if(!sel)
91 return;
92 for(c = sel->next; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
93 if(!c)
94 for(c = *awesomeconf->clients; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
95 if(c)
97 focus(c, True, awesomeconf);
98 restack(awesomeconf);
102 void
103 uicb_focusprev(awesome_config *awesomeconf,
104 const char *arg __attribute__ ((unused)))
106 Client *c, *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
108 if(!sel)
109 return;
110 for(c = sel->prev; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
111 if(!c)
113 for(c = *awesomeconf->clients; c && c->next; c = c->next);
114 for(; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
116 if(c)
118 focus(c, True, awesomeconf);
119 restack(awesomeconf);
123 void
124 loadawesomeprops(awesome_config * awesomeconf)
126 int i;
127 char *prop;
129 prop = p_new(char, awesomeconf->ntags + 1);
131 if(xgettextprop(awesomeconf->display, RootWindow(awesomeconf->display, awesomeconf->phys_screen),
132 AWESOMEPROPS_ATOM(awesomeconf->display), prop, awesomeconf->ntags + 1))
133 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
134 if(prop[i] == '1')
135 awesomeconf->tags[i].selected = True;
136 else
137 awesomeconf->tags[i].selected = False;
139 p_delete(&prop);
142 void
143 restack(awesome_config *awesomeconf)
145 Client *c, *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
146 XEvent ev;
147 XWindowChanges wc;
149 drawstatusbar(awesomeconf);
150 if(!sel)
151 return;
152 if(awesomeconf->allow_lower_floats)
153 XRaiseWindow(awesomeconf->display, sel->win);
154 else
156 if(sel->isfloating ||
157 get_current_layout(awesomeconf->tags, awesomeconf->ntags)->arrange == layout_floating)
158 XRaiseWindow(sel->display, sel->win);
159 if(!(get_current_layout(awesomeconf->tags, awesomeconf->ntags)->arrange == layout_floating))
161 wc.stack_mode = Below;
162 wc.sibling = awesomeconf->statusbar.window;
163 if(!sel->isfloating)
165 XConfigureWindow(sel->display, sel->win, CWSibling | CWStackMode, &wc);
166 wc.sibling = sel->win;
168 for(c = *awesomeconf->clients; c; c = c->next)
170 if(!IS_TILED(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags) || c == sel)
171 continue;
172 XConfigureWindow(awesomeconf->display, c->win, CWSibling | CWStackMode, &wc);
173 wc.sibling = c->win;
177 if(awesomeconf->focus_move_pointer)
178 XWarpPointer(awesomeconf->display, None, sel->win, 0, 0, 0, 0, sel->w / 2, sel->h / 2);
179 XSync(awesomeconf->display, False);
180 while(XCheckMaskEvent(awesomeconf->display, EnterWindowMask, &ev));
183 void
184 saveawesomeprops(awesome_config *awesomeconf)
186 int i;
187 char *prop;
189 prop = p_new(char, awesomeconf->ntags + 1);
190 for(i = 0; i < awesomeconf->ntags; i++)
191 prop[i] = awesomeconf->tags[i].selected ? '1' : '0';
192 prop[i] = '\0';
193 XChangeProperty(awesomeconf->display, RootWindow(awesomeconf->display, awesomeconf->phys_screen),
194 AWESOMEPROPS_ATOM(awesomeconf->display), XA_STRING, 8,
195 PropModeReplace, (unsigned char *) prop, i);
196 p_delete(&prop);
199 void
200 uicb_setlayout(awesome_config * awesomeconf,
201 const char *arg)
203 int i, j;
205 if(arg)
207 /* compute current index */
208 for(i = 0; i < awesomeconf->nlayouts &&
209 &awesomeconf->layouts[i] != get_current_layout(awesomeconf->tags, awesomeconf->ntags); i++);
210 i = compute_new_value_from_arg(arg, (double) i);
211 if(i >= awesomeconf->nlayouts)
212 i = 0;
213 else if(i < 0)
214 i = awesomeconf->nlayouts - 1;
216 else
217 i = 0;
219 for(j = 0; j < awesomeconf->ntags; j++)
220 if (awesomeconf->tags[j].selected)
221 awesomeconf->tags[j].layout = &awesomeconf->layouts[i];
223 if(get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel)
224 arrange(awesomeconf);
225 else
226 drawstatusbar(awesomeconf);
228 saveawesomeprops(awesomeconf);
231 static void
232 maximize(int x, int y, int w, int h, awesome_config *awesomeconf)
234 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
236 if(!sel)
237 return;
239 if((sel->ismax = !sel->ismax))
241 sel->wasfloating = sel->isfloating;
242 sel->isfloating = True;
243 client_resize(sel, x, y, w, h, awesomeconf, True, True);
245 else if(sel->wasfloating)
246 client_resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, awesomeconf, True, False);
247 else
248 sel->isfloating = False;
250 arrange(awesomeconf);
253 void
254 uicb_togglemax(awesome_config *awesomeconf,
255 const char *arg __attribute__ ((unused)))
257 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
259 maximize(si[awesomeconf->screen].x_org, si[awesomeconf->screen].y_org,
260 si[awesomeconf->screen].width - 2 * awesomeconf->borderpx,
261 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
262 awesomeconf);
263 p_delete(&si);
266 void
267 uicb_toggleverticalmax(awesome_config *awesomeconf,
268 const char *arg __attribute__ ((unused)))
270 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
271 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
273 if(sel)
274 maximize(sel->x,
275 si[awesomeconf->screen].y_org,
276 sel->w,
277 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
278 awesomeconf);
279 p_delete(&si);
283 void
284 uicb_togglehorizontalmax(awesome_config *awesomeconf,
285 const char *arg __attribute__ ((unused)))
287 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
288 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
290 if(sel)
291 maximize(si[awesomeconf->screen].x_org,
292 sel->y,
293 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
294 sel->h,
295 awesomeconf);
296 p_delete(&si);
299 void
300 uicb_zoom(awesome_config *awesomeconf,
301 const char *arg __attribute__ ((unused)))
303 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
305 if(!sel)
306 return;
308 client_detach(awesomeconf->clients, sel);
309 client_attach(awesomeconf->clients, sel);
311 focus(sel, True, awesomeconf);
312 arrange(awesomeconf);
315 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99