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.
26 #include "layouts/floating.h"
28 extern AwesomeConf globalconf
;
30 /** Initialize a titlebar: create the SimpleWindow.
31 * We still need to update its geometry to have it placed correctly.
35 titlebar_init(Client
*c
)
39 if(!c
->titlebar
.height
)
40 c
->titlebar
.height
= 1.5 * MAX(c
->titlebar
.styles
.normal
.font
->height
,
41 MAX(c
->titlebar
.styles
.focus
.font
->height
,
42 c
->titlebar
.styles
.urgent
.font
->height
));
44 switch(c
->titlebar
.position
)
49 c
->titlebar
.position
= Off
;
53 if(!c
->titlebar
.width
)
54 width
= c
->geometry
.width
+ 2 * c
->border
;
56 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
57 c
->titlebar
.sw
= simplewindow_new(globalconf
.display
,
59 width
, c
->titlebar
.height
, 0);
63 if(!c
->titlebar
.width
)
64 width
= c
->geometry
.height
+ 2 * c
->border
;
66 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
67 c
->titlebar
.sw
= simplewindow_new(globalconf
.display
,
69 c
->titlebar
.height
, width
, 0);
74 XMapWindow(globalconf
.display
, c
->titlebar
.sw
->window
);
77 /** Add the titlebar geometry to a geometry.
78 * \param t the titlebar
79 * \param geometry the geometry
80 * \return a new geometry bigger if the titlebar is visible
83 titlebar_geometry_add(Titlebar
*t
, area_t geometry
)
91 geometry
.y
-= t
->sw
->geometry
.height
;
92 geometry
.height
+= t
->sw
->geometry
.height
;
95 geometry
.height
+= t
->sw
->geometry
.height
;
98 geometry
.x
-= t
->sw
->geometry
.width
;
99 geometry
.width
+= t
->sw
->geometry
.width
;
102 geometry
.width
+= t
->sw
->geometry
.width
;
111 /** Remove the titlebar geometry to a geometry.
112 * \param t the titlebar
113 * \param geometry the geometry
114 * \return a new geometry smaller if the titlebar is visible
117 titlebar_geometry_remove(Titlebar
*t
, area_t geometry
)
125 geometry
.y
+= t
->sw
->geometry
.height
;
126 geometry
.height
-= t
->sw
->geometry
.height
;
129 geometry
.height
-= t
->sw
->geometry
.height
;
132 geometry
.x
+= t
->sw
->geometry
.width
;
133 geometry
.width
-= t
->sw
->geometry
.width
;
136 geometry
.width
-= t
->sw
->geometry
.width
;
145 /** Draw the titlebar content.
146 * \param c the client
149 titlebar_draw(Client
*c
)
159 switch(c
->titlebar
.position
)
165 dw
= XCreatePixmap(globalconf
.display
,
166 RootWindow(globalconf
.display
, c
->titlebar
.sw
->phys_screen
),
167 c
->titlebar
.sw
->geometry
.height
,
168 c
->titlebar
.sw
->geometry
.width
,
169 DefaultDepth(globalconf
.display
, c
->titlebar
.sw
->phys_screen
));
170 ctx
= draw_context_new(globalconf
.display
, c
->titlebar
.sw
->phys_screen
,
171 c
->titlebar
.sw
->geometry
.height
,
172 c
->titlebar
.sw
->geometry
.width
,
174 geometry
.width
= c
->titlebar
.sw
->geometry
.height
;
175 geometry
.height
= c
->titlebar
.sw
->geometry
.width
;
178 ctx
= draw_context_new(globalconf
.display
, c
->titlebar
.sw
->phys_screen
,
179 c
->titlebar
.sw
->geometry
.width
,
180 c
->titlebar
.sw
->geometry
.height
,
181 c
->titlebar
.sw
->drawable
);
182 geometry
= c
->titlebar
.sw
->geometry
;
186 /* Check if the client is focused/urgent/normal */
187 if(globalconf
.focus
->client
== c
)
188 style
= c
->titlebar
.styles
.focus
;
190 style
= c
->titlebar
.styles
.urgent
;
192 style
= c
->titlebar
.styles
.normal
;
194 geometry
.x
= geometry
.y
= 0;
196 draw_text(ctx
, geometry
, c
->titlebar
.text_align
, style
.font
->height
/ 2,
199 switch(c
->titlebar
.position
)
202 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
203 - M_PI_2
, 0, c
->titlebar
.sw
->geometry
.height
);
204 XFreePixmap(globalconf
.display
, dw
);
207 draw_rotate(ctx
, c
->titlebar
.sw
->drawable
, ctx
->height
, ctx
->width
,
208 M_PI_2
, c
->titlebar
.sw
->geometry
.width
, 0);
209 XFreePixmap(globalconf
.display
, dw
);
214 simplewindow_refresh_drawable(c
->titlebar
.sw
, c
->titlebar
.sw
->phys_screen
);
216 draw_context_delete(&ctx
);
219 /** Update the titlebar geometry for a floating client.
220 * \param c the client
223 titlebar_update_geometry_floating(Client
*c
)
225 int width
, x_offset
= 0, y_offset
= 0;
230 switch(c
->titlebar
.position
)
237 if(!c
->titlebar
.width
)
238 width
= c
->geometry
.width
+ 2 * c
->border
;
240 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
241 switch(c
->titlebar
.align
)
246 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
249 x_offset
= (c
->geometry
.width
- width
) / 2;
252 simplewindow_move_resize(c
->titlebar
.sw
,
253 c
->geometry
.x
+ x_offset
,
254 c
->geometry
.y
- c
->titlebar
.sw
->geometry
.height
,
256 c
->titlebar
.sw
->geometry
.height
);
259 if(!c
->titlebar
.width
)
260 width
= c
->geometry
.width
+ 2 * c
->border
;
262 width
= MIN(c
->titlebar
.width
, c
->geometry
.width
);
263 switch(c
->titlebar
.align
)
268 x_offset
= 2 * c
->border
+ c
->geometry
.width
- width
;
271 x_offset
= (c
->geometry
.width
- width
) / 2;
274 simplewindow_move_resize(c
->titlebar
.sw
,
275 c
->geometry
.x
+ x_offset
,
276 c
->geometry
.y
+ c
->geometry
.height
+ 2 * c
->border
,
278 c
->titlebar
.sw
->geometry
.height
);
281 if(!c
->titlebar
.width
)
282 width
= c
->geometry
.height
+ 2 * c
->border
;
284 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
285 switch(c
->titlebar
.align
)
290 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
293 y_offset
= (c
->geometry
.height
- width
) / 2;
296 simplewindow_move_resize(c
->titlebar
.sw
,
297 c
->geometry
.x
- c
->titlebar
.sw
->geometry
.width
,
298 c
->geometry
.y
+ y_offset
,
299 c
->titlebar
.sw
->geometry
.width
,
303 if(!c
->titlebar
.width
)
304 width
= c
->geometry
.height
+ 2 * c
->border
;
306 width
= MIN(c
->titlebar
.width
, c
->geometry
.height
);
307 switch(c
->titlebar
.align
)
312 y_offset
= 2 * c
->border
+ c
->geometry
.height
- width
;
315 y_offset
= (c
->geometry
.height
- width
) / 2;
318 simplewindow_move_resize(c
->titlebar
.sw
,
319 c
->geometry
.x
+ c
->geometry
.width
+ 2 * c
->border
,
320 c
->geometry
.y
+ y_offset
,
321 c
->titlebar
.sw
->geometry
.width
,
330 /** Update the titlebar geometry for a tiled client.
331 * \param c the client
332 * \param geometry the geometry the client will receive
335 titlebar_update_geometry(Client
*c
, area_t geometry
)
337 int width
, x_offset
= 0 , y_offset
= 0;
342 switch(c
->titlebar
.position
)
349 if(!c
->titlebar
.width
)
350 width
= geometry
.width
+ 2 * c
->border
;
352 width
= MIN(c
->titlebar
.width
, geometry
.width
);
353 switch(c
->titlebar
.align
)
358 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
361 x_offset
= (geometry
.width
- width
) / 2;
364 simplewindow_move_resize(c
->titlebar
.sw
,
365 geometry
.x
+ x_offset
,
368 c
->titlebar
.sw
->geometry
.height
);
371 if(!c
->titlebar
.width
)
372 width
= geometry
.width
+ 2 * c
->border
;
374 width
= MIN(c
->titlebar
.width
, geometry
.width
);
375 switch(c
->titlebar
.align
)
380 x_offset
= 2 * c
->border
+ geometry
.width
- width
;
383 x_offset
= (geometry
.width
- width
) / 2;
386 simplewindow_move_resize(c
->titlebar
.sw
,
387 geometry
.x
+ x_offset
,
388 geometry
.y
+ geometry
.height
389 - c
->titlebar
.sw
->geometry
.height
+ 2 * c
->border
,
391 c
->titlebar
.sw
->geometry
.height
);
394 if(!c
->titlebar
.width
)
395 width
= geometry
.height
+ 2 * c
->border
;
397 width
= MIN(c
->titlebar
.width
, geometry
.height
);
398 switch(c
->titlebar
.align
)
403 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
406 y_offset
= (geometry
.height
- width
) / 2;
409 simplewindow_move_resize(c
->titlebar
.sw
,
411 geometry
.y
+ y_offset
,
412 c
->titlebar
.sw
->geometry
.width
,
416 if(!c
->titlebar
.width
)
417 width
= geometry
.height
+ 2 * c
->border
;
419 width
= MIN(c
->titlebar
.width
, geometry
.height
);
420 switch(c
->titlebar
.align
)
425 y_offset
= 2 * c
->border
+ geometry
.height
- width
;
428 y_offset
= (geometry
.height
- width
) / 2;
431 simplewindow_move_resize(c
->titlebar
.sw
,
432 geometry
.x
+ geometry
.width
433 - c
->titlebar
.sw
->geometry
.width
+ 2 * c
->border
,
434 geometry
.y
+ y_offset
,
435 c
->titlebar
.sw
->geometry
.width
,
443 /** Toggle the visibility of the focused window's titlebar.
444 * \param screen screen number (unused)
445 * \param arg unused argument
446 * \ingroup ui_callback
449 uicb_client_toggletitlebar(int screen
__attribute__ ((unused
)), char *arg
__attribute__ ((unused
)))
451 Client
*c
= globalconf
.focus
->client
;
453 if(!c
|| !c
->titlebar
.sw
)
456 if(!c
->titlebar
.position
)
458 if((c
->titlebar
.position
= c
->titlebar
.dposition
))
459 XMapWindow(globalconf
.display
, c
->titlebar
.sw
->window
);
463 c
->titlebar
.position
= Off
;
464 XUnmapWindow(globalconf
.display
, c
->titlebar
.sw
->window
);
467 if(c
->isfloating
|| layout_get_current(screen
)->arrange
== layout_floating
)
468 titlebar_update_geometry_floating(c
);
470 globalconf
.screens
[c
->screen
].need_arrange
= True
;
473 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80