better fix for font height problem
[awesome.git] / layout.c
blob6bbd097f585300c4b7703f39bc113ed2516179f8
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 /* extern */
33 extern Client *clients, *sel; /* global client list */
35 /** Arrange windows following current selected layout
36 * \param disp display ref
37 * \param drawcontext drawcontext ref
38 * \param awesomeconf awesome config
40 void
41 arrange(Display * disp, DC *drawcontext, awesome_config *awesomeconf)
43 Client *c;
45 for(c = clients; c; c = c->next)
47 if(isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags))
48 unban(c);
49 /* we don't touch other screens windows */
50 else if(c->screen == awesomeconf->screen)
51 ban(c);
53 awesomeconf->current_layout->arrange(disp, awesomeconf);
54 focus(disp, drawcontext, NULL, True, awesomeconf);
55 restack(disp, drawcontext, awesomeconf);
58 void
59 uicb_focusnext(Display *disp __attribute__ ((unused)),
60 DC *drawcontext,
61 awesome_config * awesomeconf,
62 const char *arg __attribute__ ((unused)))
64 Client *c;
66 if(!sel)
67 return;
68 for(c = sel->next; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
69 if(!c)
70 for(c = clients; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
71 if(c)
73 focus(c->display, drawcontext, c, True, awesomeconf);
74 restack(c->display, drawcontext, awesomeconf);
78 void
79 uicb_focusprev(Display *disp __attribute__ ((unused)),
80 DC *drawcontext,
81 awesome_config *awesomeconf,
82 const char *arg __attribute__ ((unused)))
84 Client *c;
86 if(!sel)
87 return;
88 for(c = sel->prev; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
89 if(!c)
91 for(c = clients; c && c->next; c = c->next);
92 for(; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
94 if(c)
96 focus(c->display, drawcontext, c, True, awesomeconf);
97 restack(c->display, drawcontext, awesomeconf);
101 void
102 loadawesomeprops(Display *disp, awesome_config * awesomeconf)
104 int i;
105 char *prop;
107 prop = p_new(char, awesomeconf->ntags + 1);
109 if(xgettextprop(disp, RootWindow(disp, awesomeconf->phys_screen), AWESOMEPROPS_ATOM(disp), prop, awesomeconf->ntags + 1))
110 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
111 awesomeconf->tags[i].selected = prop[i] == '1';
113 p_delete(&prop);
116 void
117 restack(Display * disp, DC * drawcontext, awesome_config *awesomeconf)
119 Client *c;
120 XEvent ev;
121 XWindowChanges wc;
123 drawstatusbar(disp, drawcontext, awesomeconf);
124 if(!sel)
125 return;
126 if(sel->isfloating || IS_ARRANGE(layout_floating))
127 XRaiseWindow(disp, sel->win);
128 if(!IS_ARRANGE(layout_floating))
130 wc.stack_mode = Below;
131 wc.sibling = awesomeconf->statusbar.window;
132 if(!sel->isfloating)
134 XConfigureWindow(disp, sel->win, CWSibling | CWStackMode, &wc);
135 wc.sibling = sel->win;
137 for(c = clients; c; c = c->next)
139 if(!IS_TILED(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags) || c == sel)
140 continue;
141 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
142 wc.sibling = c->win;
145 XSync(disp, False);
146 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
149 void
150 saveawesomeprops(Display *disp, awesome_config *awesomeconf)
152 int i;
153 char *prop;
155 prop = p_new(char, awesomeconf->ntags + 1);
156 for(i = 0; i < awesomeconf->ntags; i++)
157 prop[i] = awesomeconf->tags[i].selected ? '1' : '0';
158 prop[i] = '\0';
159 XChangeProperty(disp, RootWindow(disp, awesomeconf->phys_screen),
160 AWESOMEPROPS_ATOM(disp), XA_STRING, 8,
161 PropModeReplace, (unsigned char *) prop, i);
162 p_delete(&prop);
165 void
166 uicb_setlayout(Display *disp,
167 DC *drawcontext,
168 awesome_config * awesomeconf,
169 const char *arg)
171 int i;
172 Client *c;
174 if(arg)
176 for(i = 0; i < awesomeconf->nlayouts && &awesomeconf->layouts[i] != awesomeconf->current_layout; i++);
177 i = compute_new_value_from_arg(arg, (double) i);
178 if(i < 0 || i >= awesomeconf->nlayouts)
179 i = 0;
181 else
182 i = 0;
184 awesomeconf->current_layout = &awesomeconf->layouts[i];
186 for(c = clients; c; c = c->next)
187 c->ftview = True;
189 if(sel)
190 arrange(disp, drawcontext, awesomeconf);
191 else
192 drawstatusbar(disp, drawcontext, awesomeconf);
194 saveawesomeprops(disp, awesomeconf);
196 for(i = 0; i < awesomeconf->ntags; i++)
197 if (awesomeconf->tags[i].selected)
198 awesomeconf->tags[i].layout = awesomeconf->current_layout;
201 static void
202 maximize(int x, int y, int w, int h, DC *drawcontext, awesome_config *awesomeconf)
204 if(!sel)
205 return;
207 if((sel->ismax = !sel->ismax))
209 sel->wasfloating = sel->isfloating;
210 sel->isfloating = True;
211 sel->rx = sel->x;
212 sel->ry = sel->y;
213 sel->rw = sel->w;
214 sel->rh = sel->h;
215 resize(sel, x, y, w, h, awesomeconf, True);
217 else if(sel->wasfloating)
218 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, awesomeconf, True);
219 else
220 sel->isfloating = False;
222 arrange(sel->display, drawcontext, awesomeconf);
225 void
226 uicb_togglemax(Display *disp,
227 DC *drawcontext,
228 awesome_config *awesomeconf,
229 const char *arg __attribute__ ((unused)))
231 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, &awesomeconf->statusbar);
233 maximize(si[awesomeconf->screen].x_org, si[awesomeconf->screen].y_org,
234 si[awesomeconf->screen].width - 2 * awesomeconf->borderpx,
235 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
236 drawcontext, awesomeconf);
237 XFree(si);
240 void
241 uicb_toggleverticalmax(Display *disp,
242 DC *drawcontext,
243 awesome_config *awesomeconf,
244 const char *arg __attribute__ ((unused)))
246 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, &awesomeconf->statusbar);
248 if(sel)
249 maximize(sel->x, si[awesomeconf->screen].y_org,
250 sel->w, si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
251 drawcontext, awesomeconf);
252 XFree(si);
256 void
257 uicb_togglehorizontalmax(Display *disp,
258 DC *drawcontext,
259 awesome_config *awesomeconf,
260 const char *arg __attribute__ ((unused)))
262 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, &awesomeconf->statusbar);
264 if(sel)
265 maximize(si[awesomeconf->screen].x_org, sel->y,
266 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx, sel->h,
267 drawcontext, awesomeconf);
268 XFree(si);
271 void
272 uicb_zoom(Display *disp __attribute__ ((unused)),
273 DC *drawcontext __attribute__ ((unused)),
274 awesome_config *awesomeconf,
275 const char *arg __attribute__ ((unused)))
277 if(!sel)
278 return;
279 detach(sel);
280 attach(sel);
281 focus(sel->display, drawcontext, sel, True, awesomeconf);
282 arrange(sel->display, drawcontext, awesomeconf);