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.
30 extern awesome_t globalconf
;
32 /** Get a client by its titlebar.
33 * \param titlebar The titlebar.
37 client_getbytitlebar(wibox_t
*titlebar
)
41 for(c
= globalconf
.clients
; c
; c
= c
->next
)
42 if(c
->titlebar
== titlebar
)
48 /** Get a client by its titlebar window.
49 * \param win The window.
53 client_getbytitlebarwin(xcb_window_t win
)
57 for(c
= globalconf
.clients
; c
; c
= c
->next
)
58 if(c
->titlebar
&& c
->titlebar
->sw
.window
== win
)
65 titlebar_geometry_compute(client_t
*c
, area_t geometry
, area_t
*res
)
67 int width
, x_offset
= 0, y_offset
= 0;
69 switch(c
->titlebar
->position
)
74 width
= MAX(1, geometry
.width
+ 2 * c
->border
- 2 * c
->titlebar
->sw
.border
.width
);
75 switch(c
->titlebar
->align
)
80 x_offset
= 2 * c
->border
+ geometry
.width
- width
- 2 * c
->titlebar
->sw
.border
.width
;
83 x_offset
= (geometry
.width
- width
) / 2;
86 res
->x
= geometry
.x
+ x_offset
;
87 res
->y
= geometry
.y
- c
->titlebar
->sw
.geometry
.height
- 2 * c
->titlebar
->sw
.border
.width
+ c
->border
;
89 res
->height
= c
->titlebar
->sw
.geometry
.height
;
92 width
= MAX(1, geometry
.width
+ 2 * c
->border
- 2 * c
->titlebar
->sw
.border
.width
);
93 switch(c
->titlebar
->align
)
98 x_offset
= 2 * c
->border
+ geometry
.width
- width
- 2 * c
->titlebar
->sw
.border
.width
;
101 x_offset
= (geometry
.width
- width
) / 2;
104 res
->x
= geometry
.x
+ x_offset
;
105 res
->y
= geometry
.y
+ geometry
.height
+ c
->border
;
107 res
->height
= c
->titlebar
->sw
.geometry
.height
;
110 width
= MAX(1, geometry
.height
+ 2 * c
->border
- 2 * c
->titlebar
->sw
.border
.width
);
111 switch(c
->titlebar
->align
)
116 y_offset
= 2 * c
->border
+ geometry
.height
- width
- 2 * c
->titlebar
->sw
.border
.width
;
119 y_offset
= (geometry
.height
- width
) / 2;
122 res
->x
= geometry
.x
- c
->titlebar
->sw
.geometry
.width
+ c
->border
;
123 res
->y
= geometry
.y
+ y_offset
;
124 res
->width
= c
->titlebar
->sw
.geometry
.width
;
128 width
= MAX(1, geometry
.height
+ 2 * c
->border
- 2 * c
->titlebar
->sw
.border
.width
);
129 switch(c
->titlebar
->align
)
134 y_offset
= 2 * c
->border
+ geometry
.height
- width
- 2 * c
->titlebar
->sw
.border
.width
;
137 y_offset
= (geometry
.height
- width
) / 2;
140 res
->x
= geometry
.x
+ geometry
.width
+ c
->border
;
141 res
->y
= geometry
.y
+ y_offset
;
142 res
->width
= c
->titlebar
->sw
.geometry
.width
;
148 /** Create a new titlebar (DEPRECATED).
149 * \param L The Lua VM state.
150 * \return The number of value pushed.
153 * \lparam A table with values: align, position, fg, bg, border_width,
154 * border_color, width and height.
155 * \lreturn A brand new titlebar.
158 luaA_titlebar_new(lua_State
*L
)
162 return luaA_wibox_new(L
);
165 /** Detach a wibox titlebar from its client.
166 * \param c The client.
169 titlebar_client_detach(client_t
*c
)
171 /* If client has a titlebar, kick it out. */
174 wibox_unref(&c
->titlebar
);
175 simplewindow_wipe(&c
->titlebar
->sw
);
176 c
->titlebar
->type
= WIBOX_TYPE_NORMAL
;
177 c
->titlebar
->screen
= SCREEN_UNDEF
;
179 client_need_arrange(c
);
184 /** Attach a wibox to a client as its titlebar.
185 * \param c The client.
186 * \param t The wibox/titlebar.
189 titlebar_client_attach(client_t
*c
, wibox_t
*t
)
191 titlebar_client_detach(c
);
197 /* check if titlebar is already on a client */
198 titlebar_client_detach(client_getbytitlebar(t
));
200 c
->titlebar
= wibox_ref(&t
);
201 t
->type
= WIBOX_TYPE_TITLEBAR
;
202 t
->screen
= c
->screen
;
210 if(!t
->sw
.geometry
.height
)
211 t
->sw
.geometry
.height
= 1.5 * globalconf
.font
->height
;
215 if(!t
->sw
.geometry
.width
)
216 t
->sw
.geometry
.width
= 1.5 * globalconf
.font
->height
;
221 titlebar_geometry_compute(c
, c
->geometry
, &wingeom
);
223 simplewindow_init(&t
->sw
, c
->phys_screen
,
224 wingeom
, 0, t
->sw
.orientation
,
225 &t
->sw
.ctx
.fg
, &t
->sw
.ctx
.bg
);
226 simplewindow_border_color_set(&t
->sw
, &t
->sw
.border
.color
);
228 t
->need_update
= true;
231 xcb_map_window(globalconf
.connection
, t
->sw
.window
);
233 client_need_arrange(c
);
238 /** Titlebar newindex.
239 * \param L The Lua VM state.
240 * \param titlebar The wibox titlebar.
241 * \param tok The attribute token.
242 * \return The number of elements pushed on stack.
245 luaA_titlebar_newindex(lua_State
*L
, wibox_t
*titlebar
, awesome_token_t tok
)
257 if((buf
= luaL_checklstring(L
, 3, &len
)))
258 titlebar
->align
= draw_align_fromstr(buf
, len
);
262 case A_TK_BORDER_WIDTH
:
263 if((i
= luaL_checknumber(L
, 3)) >= 0)
264 simplewindow_border_width_set(&titlebar
->sw
, i
);
268 case A_TK_BORDER_COLOR
:
269 if((buf
= luaL_checklstring(L
, 3, &len
)))
270 if(xcolor_init_reply(xcolor_init_unchecked(&titlebar
->sw
.border
.color
, buf
, len
)))
271 simplewindow_border_color_set(&titlebar
->sw
, &titlebar
->sw
.border
.color
);
274 buf
= luaL_checklstring(L
, 3, &len
);
275 position
= position_fromstr(buf
, len
);
276 if(position
!= titlebar
->position
)
281 switch(titlebar
->position
)
290 tmp
= titlebar
->sw
.geometry
.width
;
291 titlebar
->sw
.geometry
.width
= titlebar
->sw
.geometry
.height
;
292 titlebar
->sw
.geometry
.height
= tmp
;
295 simplewindow_orientation_set(&titlebar
->sw
, North
);
298 switch(titlebar
->position
)
307 tmp
= titlebar
->sw
.geometry
.width
;
308 titlebar
->sw
.geometry
.width
= titlebar
->sw
.geometry
.height
;
309 titlebar
->sw
.geometry
.height
= tmp
;
312 simplewindow_orientation_set(&titlebar
->sw
, South
);
317 switch(titlebar
->position
)
322 tmp
= titlebar
->sw
.geometry
.width
;
323 titlebar
->sw
.geometry
.width
= titlebar
->sw
.geometry
.height
;
324 titlebar
->sw
.geometry
.height
= tmp
;
331 simplewindow_orientation_set(&titlebar
->sw
, East
);
334 titlebar
->position
= position
;
335 if((c
= client_getbytitlebar(titlebar
)))
337 titlebar_update_geometry_floating(c
);
338 /* call geometry hook for client because some like to
339 * set titlebar width in that hook, which make sense */
340 hooks_property(c
, "geometry");
348 if((c
|| (c
= client_getbytitlebar(titlebar
))))
349 client_need_arrange(c
);
354 const struct luaL_reg awesome_titlebar_methods
[] =
356 { "__call", luaA_titlebar_new
},
359 const struct luaL_reg awesome_titlebar_meta
[] =
364 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80