Add alignment attribute to titlebar
[awesome.git] / titlebar.c
blob090298745929ad909861697e5b410214cbceedd9
1 /*
2 * titlebar.c - titlebar management
4 * Copyright © 2008 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 <math.h>
24 #include "titlebar.h"
25 #include "screen.h"
27 extern AwesomeConf globalconf;
29 void
30 titlebar_init(Client *c)
32 int width;
34 if(c->titlebar.position == Off
35 || c->titlebar.position == Auto)
37 c->titlebar.position = Off;
38 return;
41 if(!c->titlebar.height)
42 c->titlebar.height = 1.5 * MAX(c->titlebar.styles.normal.font->height,
43 MAX(c->titlebar.styles.focus.font->height,
44 c->titlebar.styles.urgent.font->height));
46 switch(c->titlebar.position)
48 case Top:
49 if(!c->titlebar.width)
50 width = c->geometry.width + 2 * c->border;
51 else
52 width = MIN(c->titlebar.width, c->geometry.width);
53 c->titlebar.sw = simplewindow_new(globalconf.display,
54 c->phys_screen,
55 c->geometry.x,
56 c->geometry.y - c->titlebar.height,
57 width,
58 c->titlebar.height,
59 0);
60 break;
61 case Bottom:
62 if(!c->titlebar.width)
63 width = c->geometry.width + 2 * c->border;
64 else
65 width = MIN(c->titlebar.width, c->geometry.width);
66 c->titlebar.sw = simplewindow_new(globalconf.display,
67 c->phys_screen,
68 c->geometry.x,
69 c->geometry.y + c->geometry.height + 2 * c->border,
70 width,
71 c->titlebar.height,
72 0);
73 break;
74 case Left:
75 if(!c->titlebar.width)
76 width = c->geometry.height + 2 * c->border;
77 else
78 width = MIN(c->titlebar.width, c->geometry.height);
79 c->titlebar.sw = simplewindow_new(globalconf.display,
80 c->phys_screen,
81 c->geometry.x - c->titlebar.height,
82 c->geometry.y,
83 c->titlebar.height,
84 width,
85 0);
86 break;
87 case Right:
88 if(!c->titlebar.width)
89 width = c->geometry.height + 2 * c->border;
90 else
91 width = MIN(c->titlebar.width, c->geometry.height);
92 c->titlebar.sw = simplewindow_new(globalconf.display,
93 c->phys_screen,
94 c->geometry.x + c->geometry.width + 2 * c->border,
95 c->geometry.y,
96 c->titlebar.height,
97 width,
98 0);
99 break;
100 default:
101 break;
105 void
106 titlebar_update(Client *c)
108 Drawable dw = 0;
109 DrawCtx *ctx;
110 style_t style;
111 area_t geometry;
113 if(!c->titlebar.sw)
114 return;
116 switch(c->titlebar.position)
118 case Off:
119 return;
120 case Right:
121 case Left:
122 dw = XCreatePixmap(globalconf.display,
123 RootWindow(globalconf.display, c->titlebar.sw->phys_screen),
124 c->titlebar.sw->geometry.height,
125 c->titlebar.sw->geometry.width,
126 DefaultDepth(globalconf.display, c->titlebar.sw->phys_screen));
127 ctx = draw_context_new(globalconf.display, c->titlebar.sw->phys_screen,
128 c->titlebar.sw->geometry.height,
129 c->titlebar.sw->geometry.width,
130 dw);
131 geometry.width = c->titlebar.sw->geometry.height;
132 geometry.height = c->titlebar.sw->geometry.width;
133 break;
134 default:
135 ctx = draw_context_new(globalconf.display, c->titlebar.sw->phys_screen,
136 c->titlebar.sw->geometry.width,
137 c->titlebar.sw->geometry.height,
138 c->titlebar.sw->drawable);
139 geometry = c->titlebar.sw->geometry;
140 break;
144 if(c->isurgent)
145 style = c->titlebar.styles.urgent;
146 else if(globalconf.focus->client == c)
147 style = c->titlebar.styles.focus;
148 else
149 style = c->titlebar.styles.normal;
151 geometry.x = geometry.y = 0;
153 draw_text(ctx, geometry, c->titlebar.text_align, style.font->height / 2,
154 c->name, style);
156 switch(c->titlebar.position)
158 case Left:
159 draw_rotate(ctx, c->titlebar.sw->drawable, ctx->height, ctx->width,
160 - M_PI_2, 0, c->titlebar.sw->geometry.height);
161 XFreePixmap(globalconf.display, dw);
162 break;
163 case Right:
164 draw_rotate(ctx, c->titlebar.sw->drawable, ctx->height, ctx->width,
165 M_PI_2, c->titlebar.sw->geometry.width, 0);
166 XFreePixmap(globalconf.display, dw);
167 default:
168 break;
171 simplewindow_refresh_drawable(c->titlebar.sw, c->titlebar.sw->phys_screen);
173 draw_context_delete(&ctx);
176 void
177 titlebar_update_geometry_floating(Client *c)
179 int width, x_offset = 0, y_offset = 0;
181 if(!c->titlebar.sw)
182 return;
184 switch(c->titlebar.position)
186 default:
187 return;
188 case Top:
189 if(!c->titlebar.width)
190 width = c->geometry.width + 2 * c->border;
191 else
192 width = MIN(c->titlebar.width, c->geometry.width);
193 switch(c->titlebar.align)
195 default:
196 break;
197 case AlignRight:
198 x_offset = 2 * c->border + c->geometry.width - width;
199 break;
200 case AlignCenter:
201 x_offset = (c->geometry.width - width) / 2;
202 break;
204 simplewindow_move_resize(c->titlebar.sw,
205 c->geometry.x + x_offset,
206 c->geometry.y - c->titlebar.sw->geometry.height,
207 width,
208 c->titlebar.sw->geometry.height);
209 break;
210 case Bottom:
211 if(!c->titlebar.width)
212 width = c->geometry.width + 2 * c->border;
213 else
214 width = MIN(c->titlebar.width, c->geometry.width);
215 switch(c->titlebar.align)
217 default:
218 break;
219 case AlignRight:
220 x_offset = 2 * c->border + c->geometry.width - width;
221 break;
222 case AlignCenter:
223 x_offset = (c->geometry.width - width) / 2;
224 break;
226 simplewindow_move_resize(c->titlebar.sw,
227 c->geometry.x + x_offset,
228 c->geometry.y + c->geometry.height + 2 * c->border,
229 width,
230 c->titlebar.sw->geometry.height);
231 break;
232 case Left:
233 if(!c->titlebar.width)
234 width = c->geometry.height + 2 * c->border;
235 else
236 width = MIN(c->titlebar.width, c->geometry.height);
237 switch(c->titlebar.align)
239 default:
240 break;
241 case AlignRight:
242 y_offset = 2 * c->border + c->geometry.height - width;
243 break;
244 case AlignCenter:
245 y_offset = (c->geometry.height - width) / 2;
246 break;
248 simplewindow_move_resize(c->titlebar.sw,
249 c->geometry.x - c->titlebar.sw->geometry.width,
250 c->geometry.y + y_offset,
251 c->titlebar.sw->geometry.width,
252 width);
253 break;
254 case Right:
255 if(!c->titlebar.width)
256 width = c->geometry.height + 2 * c->border;
257 else
258 width = MIN(c->titlebar.width, c->geometry.height);
259 switch(c->titlebar.align)
261 default:
262 break;
263 case AlignRight:
264 y_offset = 2 * c->border + c->geometry.height - width;
265 break;
266 case AlignCenter:
267 y_offset = (c->geometry.height - width) / 2;
268 break;
270 simplewindow_move_resize(c->titlebar.sw,
271 c->geometry.x + c->geometry.width + 2 * c->border,
272 c->geometry.y + y_offset,
273 c->titlebar.sw->geometry.width,
274 width);
275 break;
278 titlebar_update(c);
281 area_t
282 titlebar_update_geometry(Client *c, area_t geometry)
284 int width, x_offset = 0 , y_offset = 0;
286 if(!c->titlebar.sw)
287 return geometry;
289 switch(c->titlebar.position)
291 default:
292 return geometry;
293 case Top:
294 if(!c->titlebar.width)
295 width = geometry.width + 2 * c->border;
296 else
297 width = MIN(c->titlebar.width, geometry.width);
298 switch(c->titlebar.align)
300 default:
301 break;
302 case AlignRight:
303 x_offset = 2 * c->border + geometry.width - width;
304 break;
305 case AlignCenter:
306 x_offset = (geometry.width - width) / 2;
307 break;
309 simplewindow_move_resize(c->titlebar.sw,
310 geometry.x + x_offset,
311 geometry.y,
312 width,
313 c->titlebar.sw->geometry.height);
314 geometry.y += c->titlebar.sw->geometry.height;
315 geometry.height -= c->titlebar.sw->geometry.height;
316 break;
317 case Bottom:
318 if(!c->titlebar.width)
319 width = geometry.width + 2 * c->border;
320 else
321 width = MIN(c->titlebar.width, geometry.width);
322 switch(c->titlebar.align)
324 default:
325 break;
326 case AlignRight:
327 x_offset = 2 * c->border + geometry.width - width;
328 break;
329 case AlignCenter:
330 x_offset = (geometry.width - width) / 2;
331 break;
333 geometry.height -= c->titlebar.sw->geometry.height;
334 simplewindow_move_resize(c->titlebar.sw,
335 geometry.x + x_offset,
336 geometry.y + geometry.height + 2 * c->border,
337 width,
338 c->titlebar.sw->geometry.height);
339 break;
340 case Left:
341 if(!c->titlebar.width)
342 width = geometry.height + 2 * c->border;
343 else
344 width = MIN(c->titlebar.width, geometry.height);
345 switch(c->titlebar.align)
347 default:
348 break;
349 case AlignRight:
350 y_offset = 2 * c->border + geometry.height - width;
351 break;
352 case AlignCenter:
353 y_offset = (geometry.height - width) / 2;
354 break;
356 simplewindow_move_resize(c->titlebar.sw,
357 geometry.x,
358 geometry.y + y_offset,
359 c->titlebar.sw->geometry.width,
360 width);
361 geometry.width -= c->titlebar.sw->geometry.width;
362 geometry.x += c->titlebar.sw->geometry.width;
363 break;
364 case Right:
365 if(!c->titlebar.width)
366 width = geometry.height + 2 * c->border;
367 else
368 width = MIN(c->titlebar.width, geometry.height);
369 switch(c->titlebar.align)
371 default:
372 break;
373 case AlignRight:
374 y_offset = 2 * c->border + geometry.height - width;
375 break;
376 case AlignCenter:
377 y_offset = (geometry.height - width) / 2;
378 break;
380 geometry.width -= c->titlebar.sw->geometry.width;
381 simplewindow_move_resize(c->titlebar.sw,
382 geometry.x + geometry.width + 2 * c->border,
383 geometry.y + y_offset,
384 c->titlebar.sw->geometry.width,
385 width);
386 break;
389 titlebar_update(c);
391 return geometry;
394 /** Toggle window titlebar visibility
395 * \param screen screen number (unused)
396 * \param arg unused argument
397 * \ingroup ui_callback
399 void
400 uicb_client_toggletitlebar(int screen __attribute__ ((unused)),
401 char *arg __attribute__ ((unused)))
403 Client *c = globalconf.focus->client;
405 if(!c || !c->titlebar.sw)
406 return;
408 if(!c->titlebar.position)
409 c->titlebar.position = c->titlebar.dposition;
410 else
412 c->titlebar.position = Off;
413 XUnmapWindow(globalconf.display, c->titlebar.sw->window);
416 globalconf.screens[c->screen].need_arrange = True;
419 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80