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>
29 #include "statusbar.h"
30 #include "layouts/floating.h"
32 /** Find the index of the first currently selected tag
33 * \param tags the array of tags to search
34 * \param ntags number of elements in above array
38 get_current_tag(Tag
*tags
, int ntags
)
42 for(i
= 0; i
< ntags
; i
++)
43 if(tags
[i
].selected
== True
)
49 /** Arrange windows following current selected layout
50 * \param disp display ref
51 * \param awesomeconf awesome config
54 arrange(awesome_config
*awesomeconf
)
57 Tag
*curtag
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
);
59 for(c
= *awesomeconf
->clients
; c
; c
= c
->next
)
61 if(isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
))
63 /* we don't touch other screens windows */
64 else if(c
->screen
== awesomeconf
->screen
)
68 curtag
->layout
->arrange(awesomeconf
);
69 focus(curtag
->client_sel
, True
, awesomeconf
);
74 get_current_layout(Tag
*tags
, int ntags
)
78 if ((curtag
= get_current_tag(tags
, ntags
)))
79 return curtag
->layout
;
85 uicb_focusnext(awesome_config
* awesomeconf
,
86 const char *arg
__attribute__ ((unused
)))
88 Client
*c
, *sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
92 for(c
= sel
->next
; c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); c
= c
->next
);
94 for(c
= *awesomeconf
->clients
; c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); c
= c
->next
);
97 focus(c
, True
, awesomeconf
);
103 uicb_focusprev(awesome_config
*awesomeconf
,
104 const char *arg
__attribute__ ((unused
)))
106 Client
*c
, *sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
110 for(c
= sel
->prev
; c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); c
= c
->prev
);
113 for(c
= *awesomeconf
->clients
; c
&& c
->next
; c
= c
->next
);
114 for(; c
&& !isvisible(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
); c
= c
->prev
);
118 focus(c
, True
, awesomeconf
);
119 restack(awesomeconf
);
124 loadawesomeprops(awesome_config
* awesomeconf
)
129 prop
= p_new(char, awesomeconf
->ntags
+ 1);
131 if(xgettextprop(awesomeconf
->display
, RootWindow(awesomeconf
->display
, awesomeconf
->phys_screen
),
132 AWESOMEPROPS_ATOM(awesomeconf
->display
), prop
, awesomeconf
->ntags
+ 1))
133 for(i
= 0; i
< awesomeconf
->ntags
&& prop
[i
]; i
++)
135 awesomeconf
->tags
[i
].selected
= True
;
137 awesomeconf
->tags
[i
].selected
= False
;
143 restack(awesome_config
*awesomeconf
)
145 Client
*c
, *sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
149 drawstatusbar(awesomeconf
);
152 if(awesomeconf
->allow_lower_floats
)
153 XRaiseWindow(awesomeconf
->display
, sel
->win
);
156 if(sel
->isfloating
||
157 get_current_layout(awesomeconf
->tags
, awesomeconf
->ntags
)->arrange
== layout_floating
)
158 XRaiseWindow(sel
->display
, sel
->win
);
159 if(!(get_current_layout(awesomeconf
->tags
, awesomeconf
->ntags
)->arrange
== layout_floating
))
161 wc
.stack_mode
= Below
;
162 wc
.sibling
= awesomeconf
->statusbar
.window
;
165 XConfigureWindow(sel
->display
, sel
->win
, CWSibling
| CWStackMode
, &wc
);
166 wc
.sibling
= sel
->win
;
168 for(c
= *awesomeconf
->clients
; c
; c
= c
->next
)
170 if(!IS_TILED(c
, awesomeconf
->screen
, awesomeconf
->tags
, awesomeconf
->ntags
) || c
== sel
)
172 XConfigureWindow(awesomeconf
->display
, c
->win
, CWSibling
| CWStackMode
, &wc
);
177 if(awesomeconf
->focus_move_pointer
)
178 XWarpPointer(awesomeconf
->display
, None
, sel
->win
, 0, 0, 0, 0, sel
->w
/ 2, sel
->h
/ 2);
179 XSync(awesomeconf
->display
, False
);
180 while(XCheckMaskEvent(awesomeconf
->display
, EnterWindowMask
, &ev
));
184 saveawesomeprops(awesome_config
*awesomeconf
)
189 prop
= p_new(char, awesomeconf
->ntags
+ 1);
190 for(i
= 0; i
< awesomeconf
->ntags
; i
++)
191 prop
[i
] = awesomeconf
->tags
[i
].selected
? '1' : '0';
193 XChangeProperty(awesomeconf
->display
, RootWindow(awesomeconf
->display
, awesomeconf
->phys_screen
),
194 AWESOMEPROPS_ATOM(awesomeconf
->display
), XA_STRING
, 8,
195 PropModeReplace
, (unsigned char *) prop
, i
);
200 uicb_setlayout(awesome_config
* awesomeconf
,
207 /* compute current index */
208 for(i
= 0; i
< awesomeconf
->nlayouts
&&
209 &awesomeconf
->layouts
[i
] != get_current_layout(awesomeconf
->tags
, awesomeconf
->ntags
); i
++);
210 i
= compute_new_value_from_arg(arg
, (double) i
);
211 if(i
>= awesomeconf
->nlayouts
)
214 i
= awesomeconf
->nlayouts
- 1;
219 for(j
= 0; j
< awesomeconf
->ntags
; j
++)
220 if (awesomeconf
->tags
[j
].selected
)
221 awesomeconf
->tags
[j
].layout
= &awesomeconf
->layouts
[i
];
223 if(get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
)
224 arrange(awesomeconf
);
226 drawstatusbar(awesomeconf
);
228 saveawesomeprops(awesomeconf
);
232 maximize(int x
, int y
, int w
, int h
, awesome_config
*awesomeconf
)
234 Client
*sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
239 if((sel
->ismax
= !sel
->ismax
))
241 sel
->wasfloating
= sel
->isfloating
;
242 sel
->isfloating
= True
;
243 client_resize(sel
, x
, y
, w
, h
, awesomeconf
, True
, True
);
245 else if(sel
->wasfloating
)
246 client_resize(sel
, sel
->rx
, sel
->ry
, sel
->rw
, sel
->rh
, awesomeconf
, True
, False
);
248 sel
->isfloating
= False
;
250 arrange(awesomeconf
);
254 uicb_togglemax(awesome_config
*awesomeconf
,
255 const char *arg
__attribute__ ((unused
)))
257 ScreenInfo
*si
= get_screen_info(awesomeconf
->display
, awesomeconf
->screen
, &awesomeconf
->statusbar
);
259 maximize(si
[awesomeconf
->screen
].x_org
, si
[awesomeconf
->screen
].y_org
,
260 si
[awesomeconf
->screen
].width
- 2 * awesomeconf
->borderpx
,
261 si
[awesomeconf
->screen
].height
- 2 * awesomeconf
->borderpx
,
267 uicb_toggleverticalmax(awesome_config
*awesomeconf
,
268 const char *arg
__attribute__ ((unused
)))
270 Client
*sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
271 ScreenInfo
*si
= get_screen_info(awesomeconf
->display
, awesomeconf
->screen
, &awesomeconf
->statusbar
);
275 si
[awesomeconf
->screen
].y_org
,
277 si
[awesomeconf
->screen
].height
- 2 * awesomeconf
->borderpx
,
284 uicb_togglehorizontalmax(awesome_config
*awesomeconf
,
285 const char *arg
__attribute__ ((unused
)))
287 Client
*sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
288 ScreenInfo
*si
= get_screen_info(awesomeconf
->display
, awesomeconf
->screen
, &awesomeconf
->statusbar
);
291 maximize(si
[awesomeconf
->screen
].x_org
,
293 si
[awesomeconf
->screen
].height
- 2 * awesomeconf
->borderpx
,
300 uicb_zoom(awesome_config
*awesomeconf
,
301 const char *arg
__attribute__ ((unused
)))
303 Client
*sel
= get_current_tag(awesomeconf
->tags
, awesomeconf
->ntags
)->client_sel
;
308 client_detach(awesomeconf
->clients
, sel
);
309 client_attach(awesomeconf
->clients
, sel
);
311 focus(sel
, True
, awesomeconf
);
312 arrange(awesomeconf
);
315 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99