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.
23 #include <xcb/xcb_aux.h>
30 #include "layouts/floating.h"
32 extern AwesomeConf globalconf
;
35 titlebar_text(client_t
*c
)
39 if(globalconf
.focus
->client
== c
)
40 text
= c
->titlebar
.text_focus
;
42 text
= c
->titlebar
.text_urgent
;
44 text
= c
->titlebar
.text_normal
;
46 return client_markup_parse(c
, text
, a_strlen(text
));
50 titlebar_size(client_t
*c
)
52 return draw_text_extents(globalconf
.connection
, globalconf
.default_screen
,
53 globalconf
.screens
[c
->screen
].styles
.normal
.font
, titlebar_text(c
));
56 /** Initialize a titlebar: create the simple_window_t.
57 * We still need to update its geometry to have it placed correctly.
61 titlebar_init(client_t
*c
)
63 int width
= 0, height
= 0;
65 if(!c
->titlebar
.height
)
66 c
->titlebar
.height
= MAX(MAX(draw_text_extents(globalconf
.connection
, globalconf
.default_screen
,
67 globalconf
.screens
[c
->screen
].styles
.focus
.font
,
68 client_markup_parse(c
, c
->titlebar
.text_focus
, a_strlen(c
->titlebar
.text_focus
))).height
,
69 draw_text_extents(globalconf
.connection
, globalconf
.default_screen
,
70 globalconf
.screens
[c
->screen
].styles
.normal
.font
,
71 client_markup_parse(c
, c
->titlebar
.text_normal
, a_strlen(c
->titlebar
.text_normal
))).height
),
72 draw_text_extents(globalconf
.connection
, globalconf
.default_screen
,
73 globalconf
.screens
[c
->screen
].styles
.urgent
.font
,
74 client_markup_parse(c
, c
->titlebar
.text_urgent
, a_strlen(c
->titlebar
.text_urgent
))).height
);
76 switch(c
->titlebar
.position
)
81 c
->titlebar
.position
= Off
;
85 if(!c
->titlebar
.width
)
86 width
= c
->geometry
.width
+ 2 * c
->border
;
88 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
89 height
= c
->titlebar
.height
;
93 if(!c
->titlebar
.width
)
94 height
= c
->geometry
.height
+ 2 * c
->border
;
96 height
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
97 width
= c
->titlebar
.height
;
100 c
->titlebar
.sw
= simplewindow_new(globalconf
.connection
,
101 c
->phys_screen
, 0, 0,
103 xcb_map_window(globalconf
.connection
, c
->titlebar
.sw
->window
);
106 /** Add the titlebar geometry to a geometry.
107 * \param t the titlebar
108 * \param geometry the geometry
109 * \return a new geometry bigger if the titlebar is visible
112 titlebar_geometry_add(titlebar_t
*t
, area_t geometry
)
120 geometry
.y
-= t
->sw
->geometry
.height
;
121 geometry
.height
+= t
->sw
->geometry
.height
;
124 geometry
.height
+= t
->sw
->geometry
.height
;
127 geometry
.x
-= t
->sw
->geometry
.width
;
128 geometry
.width
+= t
->sw
->geometry
.width
;
131 geometry
.width
+= t
->sw
->geometry
.width
;
140 /** Remove the titlebar geometry to a geometry.
141 * \param t the titlebar
142 * \param geometry the geometry
143 * \return a new geometry smaller if the titlebar is visible
146 titlebar_geometry_remove(titlebar_t
*t
, area_t geometry
)
154 geometry
.y
+= t
->sw
->geometry
.height
;
155 geometry
.height
-= t
->sw
->geometry
.height
;
158 geometry
.height
-= t
->sw
->geometry
.height
;
161 geometry
.x
+= t
->sw
->geometry
.width
;
162 geometry
.width
-= t
->sw
->geometry
.width
;
165 geometry
.width
-= t
->sw
->geometry
.width
;
174 /** Draw the titlebar content.
175 * \param c the client
178 titlebar_draw(client_t
*c
)
180 xcb_drawable_t dw
= 0;
190 s
= xcb_aux_get_screen(globalconf
.connection
,
191 c
->titlebar
.sw
->phys_screen
);
193 switch(c
->titlebar
.position
)
199 dw
= xcb_generate_id(globalconf
.connection
);
200 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
,
203 c
->titlebar
.sw
->geometry
.height
,
204 c
->titlebar
.sw
->geometry
.width
);
205 ctx
= draw_context_new(globalconf
.connection
, c
->titlebar
.sw
->phys_screen
,
206 c
->titlebar
.sw
->geometry
.height
,
207 c
->titlebar
.sw
->geometry
.width
,
209 geometry
.width
= c
->titlebar
.sw
->geometry
.height
;
210 geometry
.height
= c
->titlebar
.sw
->geometry
.width
;
213 ctx
= draw_context_new(globalconf
.connection
, c
->titlebar
.sw
->phys_screen
,
214 c
->titlebar
.sw
->geometry
.width
,
215 c
->titlebar
.sw
->geometry
.height
,
216 c
->titlebar
.sw
->drawable
);
217 geometry
= c
->titlebar
.sw
->geometry
;
221 text
= titlebar_text(c
);
222 geometry
.x
= geometry
.y
= 0;
223 style
= client_style_get(c
);
224 draw_text(ctx
, geometry
, text
, style
);
227 switch(c
->titlebar
.position
)
230 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
231 - M_PI_2
, 0, c
->titlebar
.sw
->geometry
.height
);
232 xcb_free_pixmap(globalconf
.connection
, dw
);
235 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
236 M_PI_2
, c
->titlebar
.sw
->geometry
.width
, 0);
237 xcb_free_pixmap(globalconf
.connection
, dw
);
242 simplewindow_refresh_drawable(c
->titlebar
.sw
);
244 draw_context_delete(&ctx
);
247 /** Update the titlebar geometry for a floating client.
248 * \param c the client
251 titlebar_update_geometry_floating(client_t
*c
)
253 int width
, x_offset
= 0, y_offset
= 0;
258 switch(c
->titlebar
.position
)
265 if(!c
->titlebar
.width
)
266 width
= c
->geometry
.width
+ 2 * c
->border
;
268 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
269 switch(c
->titlebar
.align
)
274 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
277 x_offset
= (c
->geometry
.width
- width
) / 2;
280 simplewindow_move_resize(c
->titlebar
.sw
,
281 c
->geometry
.x
+ x_offset
,
282 c
->geometry
.y
- c
->titlebar
.sw
->geometry
.height
,
284 c
->titlebar
.sw
->geometry
.height
);
287 if(!c
->titlebar
.width
)
288 width
= c
->geometry
.width
+ 2 * c
->border
;
290 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
291 switch(c
->titlebar
.align
)
296 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
299 x_offset
= (c
->geometry
.width
- width
) / 2;
302 simplewindow_move_resize(c
->titlebar
.sw
,
303 c
->geometry
.x
+ x_offset
,
304 c
->geometry
.y
+ c
->geometry
.height
+ 2 * c
->border
,
306 c
->titlebar
.sw
->geometry
.height
);
309 if(!c
->titlebar
.width
)
310 width
= c
->geometry
.height
+ 2 * c
->border
;
312 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
313 switch(c
->titlebar
.align
)
318 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
321 y_offset
= (c
->geometry
.height
- width
) / 2;
324 simplewindow_move_resize(c
->titlebar
.sw
,
325 c
->geometry
.x
- c
->titlebar
.sw
->geometry
.width
,
326 c
->geometry
.y
+ y_offset
,
327 c
->titlebar
.sw
->geometry
.width
,
331 if(!c
->titlebar
.width
)
332 width
= c
->geometry
.height
+ 2 * c
->border
;
334 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
335 switch(c
->titlebar
.align
)
340 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
343 y_offset
= (c
->geometry
.height
- width
) / 2;
346 simplewindow_move_resize(c
->titlebar
.sw
,
347 c
->geometry
.x
+ c
->geometry
.width
+ 2 * c
->border
,
348 c
->geometry
.y
+ y_offset
,
349 c
->titlebar
.sw
->geometry
.width
,
358 /** Update the titlebar geometry for a tiled client.
359 * \param c the client
360 * \param geometry the geometry the client will receive
363 titlebar_update_geometry(client_t
*c
, area_t geometry
)
365 int width
, x_offset
= 0 , y_offset
= 0;
370 switch(c
->titlebar
.position
)
377 if(!c
->titlebar
.width
)
378 width
= geometry
.width
+ 2 * c
->border
;
380 width
= MIN(c
->titlebar
.width
, geometry
.width
);
381 switch(c
->titlebar
.align
)
386 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
389 x_offset
= (geometry
.width
- width
) / 2;
392 simplewindow_move_resize(c
->titlebar
.sw
,
393 geometry
.x
+ x_offset
,
396 c
->titlebar
.sw
->geometry
.height
);
399 if(!c
->titlebar
.width
)
400 width
= geometry
.width
+ 2 * c
->border
;
402 width
= MIN(c
->titlebar
.width
, geometry
.width
);
403 switch(c
->titlebar
.align
)
408 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
411 x_offset
= (geometry
.width
- width
) / 2;
414 simplewindow_move_resize(c
->titlebar
.sw
,
415 geometry
.x
+ x_offset
,
416 geometry
.y
+ geometry
.height
417 - c
->titlebar
.sw
->geometry
.height
+ 2 * c
->border
,
419 c
->titlebar
.sw
->geometry
.height
);
422 if(!c
->titlebar
.width
)
423 width
= geometry
.height
+ 2 * c
->border
;
425 width
= MIN(c
->titlebar
.width
, geometry
.height
);
426 switch(c
->titlebar
.align
)
431 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
434 y_offset
= (geometry
.height
- width
) / 2;
437 simplewindow_move_resize(c
->titlebar
.sw
,
439 geometry
.y
+ y_offset
,
440 c
->titlebar
.sw
->geometry
.width
,
444 if(!c
->titlebar
.width
)
445 width
= geometry
.height
+ 2 * c
->border
;
447 width
= MIN(c
->titlebar
.width
, geometry
.height
);
448 switch(c
->titlebar
.align
)
453 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
456 y_offset
= (geometry
.height
- width
) / 2;
459 simplewindow_move_resize(c
->titlebar
.sw
,
460 geometry
.x
+ geometry
.width
461 - c
->titlebar
.sw
->geometry
.width
+ 2 * c
->border
,
462 geometry
.y
+ y_offset
,
463 c
->titlebar
.sw
->geometry
.width
,
472 titlebar_position_set(titlebar_t
*t
, position_t p
)
477 if((t
->position
= p
))
478 xcb_map_window(globalconf
.connection
, t
->sw
->window
);
480 xcb_unmap_window(globalconf
.connection
, t
->sw
->window
);
483 /** Toggle the visibility of the focused window's titlebar.
484 * \param screen screen number (unused)
485 * \param arg unused argument
486 * \ingroup ui_callback
489 uicb_client_toggletitlebar(int screen
__attribute__ ((unused
)), char *arg
__attribute__ ((unused
)))
491 client_t
*c
= globalconf
.focus
->client
;
493 if(!c
|| !c
->titlebar
.sw
)
496 if(!c
->titlebar
.position
)
497 titlebar_position_set(&c
->titlebar
, c
->titlebar
.dposition
);
499 titlebar_position_set(&c
->titlebar
, Off
);
501 if(c
->isfloating
|| layout_get_current(screen
)->arrange
== layout_floating
)
502 titlebar_update_geometry_floating(c
);
504 globalconf
.screens
[c
->screen
].need_arrange
= true;
507 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80