add screen args to focus()
[awesome.git] / layout.c
blobee5fcfae652d28b97a317440aaeb1dc366de51ec
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, DC *drawcontext, awesome_config *awesomeconf)
38 Client *c;
40 for(c = clients; c; c = c->next)
41 if(isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags))
42 unban(c);
43 else
44 ban(c);
45 awesomeconf->current_layout->arrange(disp, awesomeconf);
46 focus(disp, DefaultScreen(disp), drawcontext, NULL, True, awesomeconf);
47 restack(disp, drawcontext, awesomeconf);
50 void
51 uicb_focusnext(Display *disp __attribute__ ((unused)),
52 DC *drawcontext,
53 awesome_config * awesomeconf,
54 const char *arg __attribute__ ((unused)))
56 Client *c;
58 if(!sel)
59 return;
60 for(c = sel->next; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
61 if(!c)
62 for(c = clients; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
63 if(c)
65 focus(c->display, c->screen, drawcontext, c, True, awesomeconf);
66 restack(c->display, drawcontext, awesomeconf);
70 void
71 uicb_focusprev(Display *disp __attribute__ ((unused)),
72 DC *drawcontext,
73 awesome_config *awesomeconf,
74 const char *arg __attribute__ ((unused)))
76 Client *c;
78 if(!sel)
79 return;
80 for(c = sel->prev; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
81 if(!c)
83 for(c = clients; c && c->next; c = c->next);
84 for(; c && !isvisible(c, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
86 if(c)
88 focus(c->display, c->screen, drawcontext, c, True, awesomeconf);
89 restack(c->display, drawcontext, awesomeconf);
93 void
94 loadawesomeprops(Display *disp, int screen, awesome_config * awesomeconf)
96 int i;
97 char *prop;
99 prop = p_new(char, awesomeconf->ntags + 1);
101 if(xgettextprop(disp, RootWindow(disp, screen), AWESOMEPROPS_ATOM(disp), prop, awesomeconf->ntags + 1))
102 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
103 awesomeconf->selected_tags[i] = prop[i] == '1';
105 p_delete(&prop);
108 void
109 restack(Display * disp, DC * drawcontext, awesome_config *awesomeconf)
111 Client *c;
112 XEvent ev;
113 XWindowChanges wc;
115 drawstatusbar(disp, drawcontext, awesomeconf);
116 if(!sel)
117 return;
118 if(sel->isfloating || IS_ARRANGE(floating))
119 XRaiseWindow(disp, sel->win);
120 if(!IS_ARRANGE(floating))
122 wc.stack_mode = Below;
123 wc.sibling = awesomeconf->statusbar.window;
124 if(!sel->isfloating)
126 XConfigureWindow(disp, sel->win, CWSibling | CWStackMode, &wc);
127 wc.sibling = sel->win;
129 for(c = clients; c; c = c->next)
131 if(!IS_TILED(c, awesomeconf->selected_tags, awesomeconf->ntags) || c == sel)
132 continue;
133 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
134 wc.sibling = c->win;
137 XSync(disp, False);
138 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
141 void
142 saveawesomeprops(Display *disp, int screen, awesome_config *awesomeconf)
144 int i;
145 char *prop;
147 prop = p_new(char, awesomeconf->ntags + 1);
148 for(i = 0; i < awesomeconf->ntags; i++)
149 prop[i] = awesomeconf->selected_tags[i] ? '1' : '0';
150 prop[i] = '\0';
151 XChangeProperty(disp, RootWindow(disp, screen),
152 AWESOMEPROPS_ATOM(disp), XA_STRING, 8,
153 PropModeReplace, (unsigned char *) prop, i);
154 p_delete(&prop);
157 void
158 uicb_setlayout(Display *disp,
159 DC *drawcontext,
160 awesome_config * awesomeconf,
161 const char *arg)
163 int i, j;
164 Client *c;
166 if(!arg)
168 if(!(++awesomeconf->current_layout)->symbol)
169 awesomeconf->current_layout = &awesomeconf->layouts[0];
171 else
173 i = strtol(arg, NULL, 10);
174 if(i < 0 || i >= awesomeconf->nlayouts)
175 return;
176 awesomeconf->current_layout = &awesomeconf->layouts[i];
179 for(c = clients; c; c = c->next)
180 c->ftview = True;
182 if(sel)
183 arrange(disp, drawcontext, awesomeconf);
184 else
185 drawstatusbar(disp, drawcontext, awesomeconf);
187 saveawesomeprops(disp, DefaultScreen(disp), awesomeconf);
189 for(j = 0; j < awesomeconf->ntags; j++)
190 if (awesomeconf->selected_tags[j])
191 awesomeconf->tag_layouts[j] = awesomeconf->current_layout;
194 static void
195 maximize(int x, int y, int w, int h, DC *drawcontext, awesome_config *awesomeconf)
197 XEvent ev;
199 if(!sel)
200 return;
202 if((sel->ismax = !sel->ismax))
204 sel->wasfloating = sel->isfloating;
205 sel->isfloating = True;
206 sel->rx = sel->x;
207 sel->ry = sel->y;
208 sel->rw = sel->w;
209 sel->rh = sel->h;
210 resize(sel, x, y, w, h, True);
212 else if(sel->isfloating)
213 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
214 else
215 sel->isfloating = False;
217 drawstatusbar(sel->display, drawcontext, awesomeconf);
219 while(XCheckMaskEvent(sel->display, EnterWindowMask, &ev));
222 void
223 uicb_togglemax(Display *disp,
224 DC *drawcontext,
225 awesome_config *awesomeconf,
226 const char *arg __attribute__ ((unused)))
228 maximize(get_windows_area_x(awesomeconf->statusbar),
229 get_windows_area_y(awesomeconf->statusbar),
230 get_windows_area_width(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
231 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
232 drawcontext,
233 awesomeconf);
236 void
237 uicb_toggleverticalmax(Display *disp,
238 DC *drawcontext,
239 awesome_config *awesomeconf,
240 const char *arg __attribute__ ((unused)))
242 if(sel)
243 maximize(sel->x,
244 get_windows_area_y(awesomeconf->statusbar),
245 sel->w,
246 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
247 drawcontext,
248 awesomeconf);
252 void
253 uicb_togglehorizontalmax(Display *disp,
254 DC *drawcontext,
255 awesome_config *awesomeconf,
256 const char *arg __attribute__ ((unused)))
258 if(sel)
259 maximize(get_windows_area_x(awesomeconf->statusbar),
260 sel->y,
261 get_windows_area_height(disp, awesomeconf->statusbar) - 2 * awesomeconf->borderpx,
262 sel->h,
263 drawcontext,
264 awesomeconf);
267 void
268 uicb_zoom(Display *disp __attribute__ ((unused)),
269 DC *drawcontext __attribute__ ((unused)),
270 awesome_config *awesomeconf,
271 const char *arg __attribute__ ((unused)))
273 if(!sel)
274 return;
275 detach(sel);
276 attach(sel);
277 focus(sel->display, sel->screen, drawcontext, sel, True, awesomeconf);
278 arrange(sel->display, drawcontext, awesomeconf);