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>
29 #include "layouts/floating.h"
31 extern AwesomeConf globalconf
;
33 /** Initialize a titlebar: create the SimpleWindow.
34 * We still need to update its geometry to have it placed correctly.
38 titlebar_init(Client
*c
)
42 if(!c
->titlebar
.height
)
43 c
->titlebar
.height
= 1.5 * MAX(c
->titlebar
.styles
.normal
.font
->height
,
44 MAX(c
->titlebar
.styles
.focus
.font
->height
,
45 c
->titlebar
.styles
.urgent
.font
->height
));
47 switch(c
->titlebar
.position
)
52 c
->titlebar
.position
= Off
;
56 if(!c
->titlebar
.width
)
57 width
= c
->geometry
.width
+ 2 * c
->border
;
59 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
60 c
->titlebar
.sw
= simplewindow_new(globalconf
.connection
,
62 width
, c
->titlebar
.height
, 0);
66 if(!c
->titlebar
.width
)
67 width
= c
->geometry
.height
+ 2 * c
->border
;
69 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
70 c
->titlebar
.sw
= simplewindow_new(globalconf
.connection
,
72 c
->titlebar
.height
, width
, 0);
77 xcb_map_window(globalconf
.connection
, c
->titlebar
.sw
->window
);
80 /** Add the titlebar geometry to a geometry.
81 * \param t the titlebar
82 * \param geometry the geometry
83 * \return a new geometry bigger if the titlebar is visible
86 titlebar_geometry_add(Titlebar
*t
, area_t geometry
)
94 geometry
.y
-= t
->sw
->geometry
.height
;
95 geometry
.height
+= t
->sw
->geometry
.height
;
98 geometry
.height
+= t
->sw
->geometry
.height
;
101 geometry
.x
-= t
->sw
->geometry
.width
;
102 geometry
.width
+= t
->sw
->geometry
.width
;
105 geometry
.width
+= t
->sw
->geometry
.width
;
114 /** Remove the titlebar geometry to a geometry.
115 * \param t the titlebar
116 * \param geometry the geometry
117 * \return a new geometry smaller if the titlebar is visible
120 titlebar_geometry_remove(Titlebar
*t
, area_t geometry
)
128 geometry
.y
+= t
->sw
->geometry
.height
;
129 geometry
.height
-= t
->sw
->geometry
.height
;
132 geometry
.height
-= t
->sw
->geometry
.height
;
135 geometry
.x
+= t
->sw
->geometry
.width
;
136 geometry
.width
-= t
->sw
->geometry
.width
;
139 geometry
.width
-= t
->sw
->geometry
.width
;
148 /** Draw the titlebar content.
149 * \param c the client
152 titlebar_draw(Client
*c
)
154 xcb_drawable_t dw
= 0;
163 s
= xcb_aux_get_screen(globalconf
.connection
,
164 c
->titlebar
.sw
->phys_screen
);
166 switch(c
->titlebar
.position
)
172 dw
= xcb_generate_id(globalconf
.connection
);
173 xcb_create_pixmap(globalconf
.connection
, s
->root_depth
,
175 xutil_root_window(globalconf
.connection
, c
->titlebar
.sw
->phys_screen
),
176 c
->titlebar
.sw
->geometry
.height
,
177 c
->titlebar
.sw
->geometry
.width
);
178 ctx
= draw_context_new(globalconf
.connection
, c
->titlebar
.sw
->phys_screen
,
179 c
->titlebar
.sw
->geometry
.height
,
180 c
->titlebar
.sw
->geometry
.width
,
182 geometry
.width
= c
->titlebar
.sw
->geometry
.height
;
183 geometry
.height
= c
->titlebar
.sw
->geometry
.width
;
186 ctx
= draw_context_new(globalconf
.connection
, c
->titlebar
.sw
->phys_screen
,
187 c
->titlebar
.sw
->geometry
.width
,
188 c
->titlebar
.sw
->geometry
.height
,
189 c
->titlebar
.sw
->drawable
);
190 geometry
= c
->titlebar
.sw
->geometry
;
194 /* Check if the client is focused/urgent/normal */
195 if(globalconf
.focus
->client
== c
)
196 style
= c
->titlebar
.styles
.focus
;
198 style
= c
->titlebar
.styles
.urgent
;
200 style
= c
->titlebar
.styles
.normal
;
202 geometry
.x
= geometry
.y
= 0;
204 draw_text(ctx
, geometry
, c
->titlebar
.text_align
, style
.font
->height
/ 2,
207 switch(c
->titlebar
.position
)
210 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
211 - M_PI_2
, 0, c
->titlebar
.sw
->geometry
.height
);
212 xcb_free_pixmap(globalconf
.connection
, dw
);
215 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
216 M_PI_2
, c
->titlebar
.sw
->geometry
.width
, 0);
217 xcb_free_pixmap(globalconf
.connection
, dw
);
222 simplewindow_refresh_drawable(c
->titlebar
.sw
, c
->titlebar
.sw
->phys_screen
);
224 draw_context_delete(&ctx
);
227 /** Update the titlebar geometry for a floating client.
228 * \param c the client
231 titlebar_update_geometry_floating(Client
*c
)
233 int width
, x_offset
= 0, y_offset
= 0;
238 switch(c
->titlebar
.position
)
245 if(!c
->titlebar
.width
)
246 width
= c
->geometry
.width
+ 2 * c
->border
;
248 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
249 switch(c
->titlebar
.align
)
254 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
257 x_offset
= (c
->geometry
.width
- width
) / 2;
260 simplewindow_move_resize(c
->titlebar
.sw
,
261 c
->geometry
.x
+ x_offset
,
262 c
->geometry
.y
- c
->titlebar
.sw
->geometry
.height
,
264 c
->titlebar
.sw
->geometry
.height
);
267 if(!c
->titlebar
.width
)
268 width
= c
->geometry
.width
+ 2 * c
->border
;
270 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
271 switch(c
->titlebar
.align
)
276 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
279 x_offset
= (c
->geometry
.width
- width
) / 2;
282 simplewindow_move_resize(c
->titlebar
.sw
,
283 c
->geometry
.x
+ x_offset
,
284 c
->geometry
.y
+ c
->geometry
.height
+ 2 * c
->border
,
286 c
->titlebar
.sw
->geometry
.height
);
289 if(!c
->titlebar
.width
)
290 width
= c
->geometry
.height
+ 2 * c
->border
;
292 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
293 switch(c
->titlebar
.align
)
298 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
301 y_offset
= (c
->geometry
.height
- width
) / 2;
304 simplewindow_move_resize(c
->titlebar
.sw
,
305 c
->geometry
.x
- c
->titlebar
.sw
->geometry
.width
,
306 c
->geometry
.y
+ y_offset
,
307 c
->titlebar
.sw
->geometry
.width
,
311 if(!c
->titlebar
.width
)
312 width
= c
->geometry
.height
+ 2 * c
->border
;
314 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
315 switch(c
->titlebar
.align
)
320 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
323 y_offset
= (c
->geometry
.height
- width
) / 2;
326 simplewindow_move_resize(c
->titlebar
.sw
,
327 c
->geometry
.x
+ c
->geometry
.width
+ 2 * c
->border
,
328 c
->geometry
.y
+ y_offset
,
329 c
->titlebar
.sw
->geometry
.width
,
338 /** Update the titlebar geometry for a tiled client.
339 * \param c the client
340 * \param geometry the geometry the client will receive
343 titlebar_update_geometry(Client
*c
, area_t geometry
)
345 int width
, x_offset
= 0 , y_offset
= 0;
350 switch(c
->titlebar
.position
)
357 if(!c
->titlebar
.width
)
358 width
= geometry
.width
+ 2 * c
->border
;
360 width
= MIN(c
->titlebar
.width
, geometry
.width
);
361 switch(c
->titlebar
.align
)
366 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
369 x_offset
= (geometry
.width
- width
) / 2;
372 simplewindow_move_resize(c
->titlebar
.sw
,
373 geometry
.x
+ x_offset
,
376 c
->titlebar
.sw
->geometry
.height
);
379 if(!c
->titlebar
.width
)
380 width
= geometry
.width
+ 2 * c
->border
;
382 width
= MIN(c
->titlebar
.width
, geometry
.width
);
383 switch(c
->titlebar
.align
)
388 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
391 x_offset
= (geometry
.width
- width
) / 2;
394 simplewindow_move_resize(c
->titlebar
.sw
,
395 geometry
.x
+ x_offset
,
396 geometry
.y
+ geometry
.height
397 - c
->titlebar
.sw
->geometry
.height
+ 2 * c
->border
,
399 c
->titlebar
.sw
->geometry
.height
);
402 if(!c
->titlebar
.width
)
403 width
= geometry
.height
+ 2 * c
->border
;
405 width
= MIN(c
->titlebar
.width
, geometry
.height
);
406 switch(c
->titlebar
.align
)
411 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
414 y_offset
= (geometry
.height
- width
) / 2;
417 simplewindow_move_resize(c
->titlebar
.sw
,
419 geometry
.y
+ y_offset
,
420 c
->titlebar
.sw
->geometry
.width
,
424 if(!c
->titlebar
.width
)
425 width
= geometry
.height
+ 2 * c
->border
;
427 width
= MIN(c
->titlebar
.width
, geometry
.height
);
428 switch(c
->titlebar
.align
)
433 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
436 y_offset
= (geometry
.height
- width
) / 2;
439 simplewindow_move_resize(c
->titlebar
.sw
,
440 geometry
.x
+ geometry
.width
441 - c
->titlebar
.sw
->geometry
.width
+ 2 * c
->border
,
442 geometry
.y
+ y_offset
,
443 c
->titlebar
.sw
->geometry
.width
,
452 titlebar_position_set(Titlebar
*t
, Position p
)
457 if((t
->position
= p
))
458 xcb_map_window(globalconf
.connection
, t
->sw
->window
);
460 xcb_unmap_window(globalconf
.connection
, t
->sw
->window
);
463 /** Toggle the visibility of the focused window's titlebar.
464 * \param screen screen number (unused)
465 * \param arg unused argument
466 * \ingroup ui_callback
469 uicb_client_toggletitlebar(int screen
__attribute__ ((unused
)), char *arg
__attribute__ ((unused
)))
471 Client
*c
= globalconf
.focus
->client
;
473 if(!c
|| !c
->titlebar
.sw
)
476 if(!c
->titlebar
.position
)
477 titlebar_position_set(&c
->titlebar
, c
->titlebar
.dposition
);
479 titlebar_position_set(&c
->titlebar
, Off
);
481 if(c
->isfloating
|| layout_get_current(screen
)->arrange
== layout_floating
)
482 titlebar_update_geometry_floating(c
);
484 globalconf
.screens
[c
->screen
].need_arrange
= true;
487 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80