allow tiled window to be resize/moved, setting them to the floating state
[awesome.git] / layout.c
blob9b23c4b7cc979152e45d10928cad0ddc5949c00d
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 "util.h"
29 #include "statusbar.h"
30 #include "layouts/floating.h"
32 /* extern */
33 extern Client *clients, *sel; /* global client list */
35 void
36 arrange(Display * disp, int screen, DC *drawcontext, awesome_config *awesomeconf)
38 Client *c;
40 for(c = clients; c; c = c->next)
42 if(c->screen != screen)
43 continue;
44 if(isvisible(c, screen, awesomeconf->selected_tags, awesomeconf->ntags))
45 unban(c);
46 else
47 ban(c);
49 awesomeconf->current_layout->arrange(disp, screen, awesomeconf);
50 focus(disp, screen, drawcontext, NULL, True, awesomeconf);
51 restack(disp, screen, drawcontext, awesomeconf);
54 void
55 uicb_focusnext(Display *disp __attribute__ ((unused)),
56 int screen,
57 DC *drawcontext,
58 awesome_config * awesomeconf,
59 const char *arg __attribute__ ((unused)))
61 Client *c;
63 if(!sel)
64 return;
65 for(c = sel->next; c && !isvisible(c, screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
66 if(!c)
67 for(c = clients; c && !isvisible(c, screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
68 if(c)
70 focus(c->display, screen, drawcontext, c, True, awesomeconf);
71 restack(c->display, screen, drawcontext, awesomeconf);
75 void
76 uicb_focusprev(Display *disp __attribute__ ((unused)),
77 int screen,
78 DC *drawcontext,
79 awesome_config *awesomeconf,
80 const char *arg __attribute__ ((unused)))
82 Client *c;
84 if(!sel)
85 return;
86 for(c = sel->prev; c && !isvisible(c, screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
87 if(!c)
89 for(c = clients; c && c->next; c = c->next);
90 for(; c && !isvisible(c, screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
92 if(c)
94 focus(c->display, screen, drawcontext, c, True, awesomeconf);
95 restack(c->display, screen, drawcontext, awesomeconf);
99 void
100 loadawesomeprops(Display *disp, int screen, awesome_config * awesomeconf)
102 int i;
103 char *prop;
105 prop = p_new(char, awesomeconf->ntags + 1);
107 if(xgettextprop(disp, RootWindow(disp, screen), AWESOMEPROPS_ATOM(disp), prop, awesomeconf->ntags + 1))
108 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
109 awesomeconf->selected_tags[i] = prop[i] == '1';
111 p_delete(&prop);
114 void
115 restack(Display * disp, int screen, DC * drawcontext, awesome_config *awesomeconf)
117 Client *c;
118 XEvent ev;
119 XWindowChanges wc;
121 drawstatusbar(disp, screen, drawcontext, awesomeconf);
122 if(!sel)
123 return;
124 if(sel->isfloating || IS_ARRANGE(floating))
125 XRaiseWindow(disp, sel->win);
126 if(!IS_ARRANGE(floating))
128 wc.stack_mode = Below;
129 wc.sibling = awesomeconf->statusbar.window;
130 if(!sel->isfloating)
132 XConfigureWindow(disp, sel->win, CWSibling | CWStackMode, &wc);
133 wc.sibling = sel->win;
135 for(c = clients; c; c = c->next)
137 if(!IS_TILED(c, screen, awesomeconf->selected_tags, awesomeconf->ntags) || c == sel)
138 continue;
139 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
140 wc.sibling = c->win;
143 XSync(disp, False);
144 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
147 void
148 saveawesomeprops(Display *disp, int screen, awesome_config *awesomeconf)
150 int i;
151 char *prop;
153 prop = p_new(char, awesomeconf->ntags + 1);
154 for(i = 0; i < awesomeconf->ntags; i++)
155 prop[i] = awesomeconf->selected_tags[i] ? '1' : '0';
156 prop[i] = '\0';
157 XChangeProperty(disp, RootWindow(disp, screen),
158 AWESOMEPROPS_ATOM(disp), XA_STRING, 8,
159 PropModeReplace, (unsigned char *) prop, i);
160 p_delete(&prop);
163 void
164 uicb_setlayout(Display *disp,
165 int screen,
166 DC *drawcontext,
167 awesome_config * awesomeconf,
168 const char *arg)
170 int i, j;
171 Client *c;
173 if(!arg)
175 if(!(++awesomeconf->current_layout)->symbol)
176 awesomeconf->current_layout = &awesomeconf->layouts[0];
178 else
180 i = strtol(arg, NULL, 10);
181 if(i < 0 || i >= awesomeconf->nlayouts)
182 return;
183 awesomeconf->current_layout = &awesomeconf->layouts[i];
186 for(c = clients; c; c = c->next)
187 c->ftview = True;
189 if(sel)
190 arrange(disp, screen, drawcontext, awesomeconf);
191 else
192 drawstatusbar(disp, DefaultScreen(disp), drawcontext, awesomeconf);
194 saveawesomeprops(disp, screen, awesomeconf);
196 for(j = 0; j < awesomeconf->ntags; j++)
197 if (awesomeconf->selected_tags[j])
198 awesomeconf->tag_layouts[j] = awesomeconf->current_layout;
201 static void
202 maximize(int x, int y, int w, int h, DC *drawcontext, awesome_config *awesomeconf)
204 XEvent ev;
206 if(!sel)
207 return;
209 if((sel->ismax = !sel->ismax))
211 sel->wasfloating = sel->isfloating;
212 sel->isfloating = True;
213 sel->rx = sel->x;
214 sel->ry = sel->y;
215 sel->rw = sel->w;
216 sel->rh = sel->h;
217 resize(sel, x, y, w, h, True);
219 else if(sel->isfloating)
220 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
221 else
222 sel->isfloating = False;
224 drawstatusbar(sel->display, sel->screen, drawcontext, awesomeconf);
226 while(XCheckMaskEvent(sel->display, EnterWindowMask, &ev));
229 void
230 uicb_togglemax(Display *disp,
231 int screen __attribute__ ((unused)),
232 DC *drawcontext,
233 awesome_config *awesomeconf,
234 const char *arg __attribute__ ((unused)))
236 maximize(get_windows_area_x(awesomeconf->statusbar),
237 get_windows_area_y(awesomeconf->statusbar),
238 get_windows_area_width(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
239 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
240 drawcontext,
241 awesomeconf);
244 void
245 uicb_toggleverticalmax(Display *disp,
246 int screen __attribute__ ((unused)),
247 DC *drawcontext,
248 awesome_config *awesomeconf,
249 const char *arg __attribute__ ((unused)))
251 if(sel)
252 maximize(sel->x,
253 get_windows_area_y(awesomeconf->statusbar),
254 sel->w,
255 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
256 drawcontext,
257 awesomeconf);
261 void
262 uicb_togglehorizontalmax(Display *disp,
263 int screen __attribute__ ((unused)),
264 DC *drawcontext,
265 awesome_config *awesomeconf,
266 const char *arg __attribute__ ((unused)))
268 if(sel)
269 maximize(get_windows_area_x(awesomeconf->statusbar),
270 sel->y,
271 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
272 sel->h,
273 drawcontext,
274 awesomeconf);
277 void
278 uicb_zoom(Display *disp __attribute__ ((unused)),
279 int screen __attribute__ ((unused)),
280 DC *drawcontext __attribute__ ((unused)),
281 awesome_config *awesomeconf,
282 const char *arg __attribute__ ((unused)))
284 if(!sel)
285 return;
286 detach(sel);
287 attach(sel);
288 focus(sel->display, sel->screen, drawcontext, sel, True, awesomeconf);
289 arrange(sel->display, sel->screen, drawcontext, awesomeconf);