arrange() does not need Display as arg
[awesome.git] / layout.c
blob2e781dbbf980fa2ce5660e6d3c622acf39605110
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 /** Arrange windows following current selected layout
33 * \param disp display ref
34 * \param awesomeconf awesome config
36 void
37 arrange(awesome_config *awesomeconf)
39 Client *c;
41 for(c = *awesomeconf->clients; c; c = c->next)
43 if(isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags))
44 unban(c);
45 /* we don't touch other screens windows */
46 else if(c->screen == awesomeconf->screen)
47 ban(c);
49 awesomeconf->current_layout->arrange(awesomeconf);
50 focus(awesomeconf->display, NULL, True, awesomeconf);
51 restack(awesomeconf->display, awesomeconf);
54 void
55 uicb_focusnext(awesome_config * awesomeconf,
56 const char *arg __attribute__ ((unused)))
58 Client *c;
60 if(!*awesomeconf->client_sel)
61 return;
62 for(c = (*awesomeconf->client_sel)->next; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
63 if(!c)
64 for(c = *awesomeconf->clients; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->next);
65 if(c)
67 focus(c->display, c, True, awesomeconf);
68 restack(c->display, awesomeconf);
72 void
73 uicb_focusprev(awesome_config *awesomeconf,
74 const char *arg __attribute__ ((unused)))
76 Client *c;
78 if(!*awesomeconf->client_sel)
79 return;
80 for(c = (*awesomeconf->client_sel)->prev; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
81 if(!c)
83 for(c = *awesomeconf->clients; c && c->next; c = c->next);
84 for(; c && !isvisible(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags); c = c->prev);
86 if(c)
88 focus(c->display, c, True, awesomeconf);
89 restack(c->display, awesomeconf);
93 void
94 loadawesomeprops(awesome_config * awesomeconf)
96 int i;
97 char *prop;
99 prop = p_new(char, awesomeconf->ntags + 1);
101 if(xgettextprop(awesomeconf->display, RootWindow(awesomeconf->display, awesomeconf->phys_screen),
102 AWESOMEPROPS_ATOM(awesomeconf->display), prop, awesomeconf->ntags + 1))
103 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
104 if(prop[i] == '1')
106 awesomeconf->tags[i].selected = True;
107 awesomeconf->current_layout = awesomeconf->tags[i].layout;
109 else
110 awesomeconf->tags[i].selected = False;
112 p_delete(&prop);
115 void
116 restack(Display * disp, awesome_config *awesomeconf)
118 Client *c;
119 XEvent ev;
120 XWindowChanges wc;
122 drawstatusbar(awesomeconf);
123 if(!*awesomeconf->client_sel)
124 return;
125 if(awesomeconf->allow_lower_floats)
126 XRaiseWindow(disp, (*awesomeconf->client_sel)->win);
127 else
129 if((*awesomeconf->client_sel)->isfloating || IS_ARRANGE(0, layout_floating))
130 XRaiseWindow(disp, (*awesomeconf->client_sel)->win);
131 if(!IS_ARRANGE(0, layout_floating))
133 wc.stack_mode = Below;
134 wc.sibling = awesomeconf->statusbar.window;
135 if(!(*awesomeconf->client_sel)->isfloating)
137 XConfigureWindow(disp, (*awesomeconf->client_sel)->win, CWSibling | CWStackMode, &wc);
138 wc.sibling = (*awesomeconf->client_sel)->win;
140 for(c = *awesomeconf->clients; c; c = c->next)
142 if(!IS_TILED(c, awesomeconf->screen, awesomeconf->tags, awesomeconf->ntags) || c == *awesomeconf->client_sel)
143 continue;
144 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
145 wc.sibling = c->win;
149 if(awesomeconf->focus_move_pointer)
150 XWarpPointer(disp, None, (*awesomeconf->client_sel)->win, 0, 0, 0, 0, (*awesomeconf->client_sel)->w / 2, (*awesomeconf->client_sel)->h / 2);
151 XSync(disp, False);
152 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
155 void
156 saveawesomeprops(awesome_config *awesomeconf)
158 int i;
159 char *prop;
161 prop = p_new(char, awesomeconf->ntags + 1);
162 for(i = 0; i < awesomeconf->ntags; i++)
163 prop[i] = awesomeconf->tags[i].selected ? '1' : '0';
164 prop[i] = '\0';
165 XChangeProperty(awesomeconf->display, RootWindow(awesomeconf->display, awesomeconf->phys_screen),
166 AWESOMEPROPS_ATOM(awesomeconf->display), XA_STRING, 8,
167 PropModeReplace, (unsigned char *) prop, i);
168 p_delete(&prop);
171 void
172 uicb_setlayout(awesome_config * awesomeconf,
173 const char *arg)
175 int i;
176 Client *c;
178 if(arg)
180 for(i = 0; i < awesomeconf->nlayouts && &awesomeconf->layouts[i] != awesomeconf->current_layout; i++);
181 i = compute_new_value_from_arg(arg, (double) i);
182 if(i >= awesomeconf->nlayouts)
183 i = 0;
184 else if(i < 0)
185 i = awesomeconf->nlayouts - 1;
187 else
188 i = 0;
190 awesomeconf->current_layout = &awesomeconf->layouts[i];
192 for(c = *awesomeconf->clients; c; c = c->next)
193 c->ftview = True;
195 if(*awesomeconf->client_sel)
196 arrange(awesomeconf);
197 else
198 drawstatusbar(awesomeconf);
200 saveawesomeprops(awesomeconf);
202 for(i = 0; i < awesomeconf->ntags; i++)
203 if (awesomeconf->tags[i].selected)
204 awesomeconf->tags[i].layout = awesomeconf->current_layout;
207 static void
208 maximize(int x, int y, int w, int h, awesome_config *awesomeconf)
210 if(!*awesomeconf->client_sel)
211 return;
213 if(((*awesomeconf->client_sel)->ismax = !(*awesomeconf->client_sel)->ismax))
215 (*awesomeconf->client_sel)->wasfloating = (*awesomeconf->client_sel)->isfloating;
216 (*awesomeconf->client_sel)->isfloating = True;
217 (*awesomeconf->client_sel)->rx = (*awesomeconf->client_sel)->x;
218 (*awesomeconf->client_sel)->ry = (*awesomeconf->client_sel)->y;
219 (*awesomeconf->client_sel)->rw = (*awesomeconf->client_sel)->w;
220 (*awesomeconf->client_sel)->rh = (*awesomeconf->client_sel)->h;
221 resize(*awesomeconf->client_sel, x, y, w, h, awesomeconf, True);
223 else if((*awesomeconf->client_sel)->wasfloating)
224 resize(*awesomeconf->client_sel,
225 (*awesomeconf->client_sel)->rx,
226 (*awesomeconf->client_sel)->ry,
227 (*awesomeconf->client_sel)->rw,
228 (*awesomeconf->client_sel)->rh,
229 awesomeconf, True);
230 else
231 (*awesomeconf->client_sel)->isfloating = False;
233 arrange(awesomeconf);
236 void
237 uicb_togglemax(awesome_config *awesomeconf,
238 const char *arg __attribute__ ((unused)))
240 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
242 maximize(si[awesomeconf->screen].x_org, si[awesomeconf->screen].y_org,
243 si[awesomeconf->screen].width - 2 * awesomeconf->borderpx,
244 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
245 awesomeconf);
246 p_delete(&si);
249 void
250 uicb_toggleverticalmax(awesome_config *awesomeconf,
251 const char *arg __attribute__ ((unused)))
253 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
255 if(*awesomeconf->client_sel)
256 maximize((*awesomeconf->client_sel)->x,
257 si[awesomeconf->screen].y_org,
258 (*awesomeconf->client_sel)->w,
259 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
260 awesomeconf);
261 p_delete(&si);
265 void
266 uicb_togglehorizontalmax(awesome_config *awesomeconf,
267 const char *arg __attribute__ ((unused)))
269 ScreenInfo *si = get_screen_info(awesomeconf->display, awesomeconf->screen, &awesomeconf->statusbar);
271 if(*awesomeconf->client_sel)
272 maximize(si[awesomeconf->screen].x_org,
273 (*awesomeconf->client_sel)->y,
274 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
275 (*awesomeconf->client_sel)->h,
276 awesomeconf);
277 p_delete(&si);
280 void
281 uicb_zoom(awesome_config *awesomeconf,
282 const char *arg __attribute__ ((unused)))
284 if(!*awesomeconf->client_sel)
285 return;
286 detach(awesomeconf->clients, *awesomeconf->client_sel);
287 attach(awesomeconf->clients, *awesomeconf->client_sel);
288 focus(awesomeconf->display, *awesomeconf->client_sel, True, awesomeconf);
289 arrange(awesomeconf);
292 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99