bug fix: fix bug when resizing with mouse
[awesome.git] / layout.c
blobf01446db121e87e253493144b2137d0602da7235
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 "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 void
36 arrange(Display * disp, DC *drawcontext, awesome_config *awesomeconf)
38 Client *c;
40 for(c = clients; c; c = c->next)
42 if(isvisible(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags))
43 unban(c);
44 /* we don't touch other screens windows */
45 else if(c->screen == awesomeconf->screen)
46 ban(c);
48 awesomeconf->current_layout->arrange(disp, awesomeconf);
49 focus(disp, drawcontext, NULL, True, awesomeconf);
50 restack(disp, drawcontext, awesomeconf);
53 void
54 uicb_focusnext(Display *disp __attribute__ ((unused)),
55 DC *drawcontext,
56 awesome_config * awesomeconf,
57 const char *arg __attribute__ ((unused)))
59 Client *c;
61 if(!sel)
62 return;
63 for(c = sel->next; c && !isvisible(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
64 if(!c)
65 for(c = clients; c && !isvisible(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->next);
66 if(c)
68 focus(c->display, drawcontext, c, True, awesomeconf);
69 restack(c->display, drawcontext, awesomeconf);
73 void
74 uicb_focusprev(Display *disp __attribute__ ((unused)),
75 DC *drawcontext,
76 awesome_config *awesomeconf,
77 const char *arg __attribute__ ((unused)))
79 Client *c;
81 if(!sel)
82 return;
83 for(c = sel->prev; c && !isvisible(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
84 if(!c)
86 for(c = clients; c && c->next; c = c->next);
87 for(; c && !isvisible(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags); c = c->prev);
89 if(c)
91 focus(c->display, drawcontext, c, True, awesomeconf);
92 restack(c->display, drawcontext, awesomeconf);
96 void
97 loadawesomeprops(Display *disp, awesome_config * awesomeconf)
99 int i;
100 char *prop;
102 prop = p_new(char, awesomeconf->ntags + 1);
104 if(xgettextprop(disp, RootWindow(disp, awesomeconf->screen), AWESOMEPROPS_ATOM(disp), prop, awesomeconf->ntags + 1))
105 for(i = 0; i < awesomeconf->ntags && prop[i]; i++)
106 awesomeconf->selected_tags[i] = prop[i] == '1';
108 p_delete(&prop);
111 void
112 restack(Display * disp, DC * drawcontext, awesome_config *awesomeconf)
114 Client *c;
115 XEvent ev;
116 XWindowChanges wc;
118 drawstatusbar(disp, awesomeconf->screen, drawcontext, awesomeconf);
119 if(!sel)
120 return;
121 if(sel->isfloating || IS_ARRANGE(floating))
122 XRaiseWindow(disp, sel->win);
123 if(!IS_ARRANGE(floating))
125 wc.stack_mode = Below;
126 wc.sibling = awesomeconf->statusbar.window;
127 if(!sel->isfloating)
129 XConfigureWindow(disp, sel->win, CWSibling | CWStackMode, &wc);
130 wc.sibling = sel->win;
132 for(c = clients; c; c = c->next)
134 if(!IS_TILED(c, awesomeconf->screen, awesomeconf->selected_tags, awesomeconf->ntags) || c == sel)
135 continue;
136 XConfigureWindow(disp, c->win, CWSibling | CWStackMode, &wc);
137 wc.sibling = c->win;
140 XSync(disp, False);
141 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
144 void
145 saveawesomeprops(Display *disp, awesome_config *awesomeconf)
147 int i;
148 char *prop;
150 prop = p_new(char, awesomeconf->ntags + 1);
151 for(i = 0; i < awesomeconf->ntags; i++)
152 prop[i] = awesomeconf->selected_tags[i] ? '1' : '0';
153 prop[i] = '\0';
154 XChangeProperty(disp, RootWindow(disp, awesomeconf->screen),
155 AWESOMEPROPS_ATOM(disp), XA_STRING, 8,
156 PropModeReplace, (unsigned char *) prop, i);
157 p_delete(&prop);
160 void
161 uicb_setlayout(Display *disp,
162 DC *drawcontext,
163 awesome_config * awesomeconf,
164 const char *arg)
166 int i, j;
167 Client *c;
169 if(!arg)
171 if(!(++awesomeconf->current_layout)->symbol)
172 awesomeconf->current_layout = awesomeconf->layouts;
174 else
176 i = strtol(arg, NULL, 10);
177 if(i < 0 || i >= awesomeconf->nlayouts)
178 return;
179 awesomeconf->current_layout = &awesomeconf->layouts[i];
182 for(c = clients; c; c = c->next)
183 c->ftview = True;
185 if(sel)
186 arrange(disp, drawcontext, awesomeconf);
187 else
188 drawstatusbar(disp, awesomeconf->screen, drawcontext, awesomeconf);
190 saveawesomeprops(disp, awesomeconf);
192 for(j = 0; j < awesomeconf->ntags; j++)
193 if (awesomeconf->selected_tags[j])
194 awesomeconf->tag_layouts[j] = awesomeconf->current_layout;
197 static void
198 maximize(Display *disp, int x, int y, int w, int h, DC *drawcontext, awesome_config *awesomeconf)
200 if(!sel)
201 return;
203 if((sel->ismax = !sel->ismax))
205 sel->wasfloating = sel->isfloating;
206 sel->isfloating = True;
207 sel->rx = sel->x;
208 sel->ry = sel->y;
209 sel->rw = sel->w;
210 sel->rh = sel->h;
211 resize(sel, x, y, w, h, True);
213 else if(sel->isfloating)
214 resize(sel, sel->rx, sel->ry, sel->rw, sel->rh, True);
215 else
216 sel->isfloating = False;
218 restack(disp, drawcontext, awesomeconf);
221 void
222 uicb_togglemax(Display *disp,
223 DC *drawcontext,
224 awesome_config *awesomeconf,
225 const char *arg __attribute__ ((unused)))
227 int dummy;
228 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, awesomeconf->statusbar, &dummy);
230 maximize(disp, si[awesomeconf->screen].x_org, si[awesomeconf->screen].y_org,
231 si[awesomeconf->screen].width - 2 * awesomeconf->borderpx,
232 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
233 drawcontext, awesomeconf);
236 void
237 uicb_toggleverticalmax(Display *disp,
238 DC *drawcontext,
239 awesome_config *awesomeconf,
240 const char *arg __attribute__ ((unused)))
242 int dummy;
243 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, awesomeconf->statusbar, &dummy);
245 if(sel)
246 maximize(disp, sel->x, si[awesomeconf->screen].y_org,
247 sel->w, si[awesomeconf->screen].height - 2 * awesomeconf->borderpx,
248 drawcontext, awesomeconf);
252 void
253 uicb_togglehorizontalmax(Display *disp,
254 DC *drawcontext,
255 awesome_config *awesomeconf,
256 const char *arg __attribute__ ((unused)))
258 int dummy;
259 ScreenInfo *si = get_screen_info(disp, awesomeconf->screen, awesomeconf->statusbar, &dummy);
261 if(sel)
262 maximize(disp, si[awesomeconf->screen].x_org, sel->y,
263 si[awesomeconf->screen].height - 2 * awesomeconf->borderpx, sel->h,
264 drawcontext, 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, drawcontext, sel, True, awesomeconf);
278 arrange(sel->display, drawcontext, awesomeconf);