2 * statusbar.c - statusbar functions
4 * Copyright © 2007-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.
25 #include <xcb/xcb_aux.h>
27 #include "statusbar.h"
33 extern AwesomeConf globalconf
;
36 statusbar_position_update(Statusbar
*statusbar
)
41 if(statusbar
->position
== Off
)
43 xcb_unmap_window(globalconf
.connection
, statusbar
->sw
->window
);
47 xutil_map_raised(globalconf
.connection
, statusbar
->sw
->window
);
49 /* Top and Bottom Statusbar have prio */
50 if(statusbar
->position
== Top
|| statusbar
->position
== Bottom
)
51 area
= screen_get_area(statusbar
->screen
,
53 &globalconf
.screens
[statusbar
->screen
].padding
);
55 area
= screen_get_area(statusbar
->screen
,
56 globalconf
.screens
[statusbar
->screen
].statusbar
,
57 &globalconf
.screens
[statusbar
->screen
].padding
);
59 for(sb
= globalconf
.screens
[statusbar
->screen
].statusbar
; sb
&& sb
!= statusbar
; sb
= sb
->next
)
63 if(sb
->position
== statusbar
->position
)
67 if(sb
->position
== statusbar
->position
)
68 area
.height
-= sb
->height
;
71 /* we need to re-add our own value removed in the
72 * screen_get_area computation */
73 if(statusbar
->position
== Left
74 || statusbar
->position
== Right
)
76 area
.x
-= statusbar
->sw
->geometry
.width
;
77 area
.width
+= statusbar
->sw
->geometry
.width
;
81 if(statusbar
->position
== Left
82 || statusbar
->position
== Right
)
83 area
.width
+= statusbar
->sw
->geometry
.width
;
89 switch(statusbar
->position
)
92 simplewindow_move(statusbar
->sw
, area
.x
, area
.y
);
95 simplewindow_move(statusbar
->sw
, area
.x
, (area
.y
+ area
.height
) - statusbar
->sw
->geometry
.height
);
98 simplewindow_move(statusbar
->sw
, area
.x
- statusbar
->sw
->geometry
.width
,
99 (area
.y
+ area
.height
) - statusbar
->sw
->geometry
.height
);
102 simplewindow_move(statusbar
->sw
, area
.x
+ area
.width
, area
.y
);
110 statusbar_draw(Statusbar
*statusbar
)
113 int left
= 0, right
= 0;
114 area_t rectangle
= { 0, 0, 0, 0, NULL
, NULL
};
116 rectangle
.width
= statusbar
->width
;
117 rectangle
.height
= statusbar
->height
;
118 draw_rectangle(statusbar
->ctx
, rectangle
, 1.0, true,
119 globalconf
.screens
[statusbar
->screen
].styles
.normal
.bg
);
121 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
122 if (widget
->alignment
== AlignLeft
)
124 widget
->cache
.needs_update
= false;
125 left
+= widget
->draw(widget
, statusbar
->ctx
, left
, (left
+ right
));
128 /* renders right widget from last to first */
129 for(widget
= *widget_list_last(&statusbar
->widgets
);
131 widget
= widget_list_prev(&statusbar
->widgets
, widget
))
132 if (widget
->alignment
== AlignRight
)
134 widget
->cache
.needs_update
= false;
135 right
+= widget
->draw(widget
, statusbar
->ctx
, right
, (left
+ right
));
138 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
139 if (widget
->alignment
== AlignFlex
)
141 widget
->cache
.needs_update
= false;
142 left
+= widget
->draw(widget
, statusbar
->ctx
, left
, (left
+ right
));
145 switch(statusbar
->position
)
148 draw_rotate(statusbar
->ctx
, statusbar
->sw
->drawable
,
149 statusbar
->ctx
->height
, statusbar
->ctx
->width
,
150 M_PI_2
, statusbar
->height
, 0);
153 draw_rotate(statusbar
->ctx
, statusbar
->sw
->drawable
,
154 statusbar
->ctx
->height
, statusbar
->ctx
->width
,
155 - M_PI_2
, 0, statusbar
->width
);
161 statusbar_display(statusbar
);
165 statusbar_display(Statusbar
*statusbar
)
167 /* don't waste our time */
168 if(statusbar
->position
!= Off
)
169 simplewindow_refresh_drawable(statusbar
->sw
, statusbar
->phys_screen
);
173 statusbar_preinit(Statusbar
*statusbar
)
175 if(statusbar
->height
<= 0)
176 /* 1.5 as default factor, it fits nice but no one knows why */
177 statusbar
->height
= 1.5 * MAX(globalconf
.screens
[statusbar
->screen
].styles
.normal
.font
->height
,
178 MAX(globalconf
.screens
[statusbar
->screen
].styles
.focus
.font
->height
,
179 globalconf
.screens
[statusbar
->screen
].styles
.urgent
.font
->height
));
183 statusbar_init(Statusbar
*statusbar
)
187 xcb_screen_t
*s
= NULL
;
188 int phys_screen
= screen_virttophys(statusbar
->screen
);
189 area_t area
= screen_get_area(statusbar
->screen
,
190 globalconf
.screens
[statusbar
->screen
].statusbar
,
191 &globalconf
.screens
[statusbar
->screen
].padding
);
193 statusbar
->phys_screen
= phys_screen
;
195 /* Top and Bottom Statusbar have prio */
196 for(sb
= globalconf
.screens
[statusbar
->screen
].statusbar
; sb
; sb
= sb
->next
)
201 area
.width
+= sb
->height
;
207 if(statusbar
->width
<= 0)
209 if(statusbar
->position
== Right
|| statusbar
->position
== Left
)
210 statusbar
->width
= area
.height
;
212 statusbar
->width
= area
.width
;
215 switch(statusbar
->position
)
220 simplewindow_new(globalconf
.connection
, phys_screen
, 0, 0,
221 statusbar
->height
, statusbar
->width
, 0);
225 simplewindow_new(globalconf
.connection
, phys_screen
, 0, 0,
226 statusbar
->width
, statusbar
->height
, 0);
230 widget_calculate_alignments(statusbar
->widgets
);
232 statusbar_position_update(statusbar
);
234 switch(statusbar
->position
)
240 s
= xcb_aux_get_screen(globalconf
.connection
, phys_screen
);
242 /* we need a new pixmap this way [ ] to render */
243 dw
= xcb_generate_id(globalconf
.connection
);
244 xcb_create_pixmap(globalconf
.connection
,
246 xutil_root_window(globalconf
.connection
, phys_screen
),
247 statusbar
->width
, statusbar
->height
);
248 statusbar
->ctx
= draw_context_new(globalconf
.connection
,
255 statusbar
->ctx
= draw_context_new(globalconf
.connection
,
259 statusbar
->sw
->drawable
);
264 statusbar_draw(statusbar
);
271 Statusbar
*statusbar
;
274 for(screen
= 0; screen
< globalconf
.screens_info
->nscreen
; screen
++)
275 for(statusbar
= globalconf
.screens
[screen
].statusbar
;
277 statusbar
= statusbar
->next
)
278 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
279 if(widget
->cache
.needs_update
)
281 statusbar_draw(statusbar
);
287 statusbar_getbyname(int screen
, const char *name
)
291 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
292 if(!a_strcmp(sb
->name
, name
))
299 statusbar_toggle(Statusbar
*statusbar
)
301 if(statusbar
->position
== Off
)
302 statusbar
->position
= (statusbar
->dposition
== Off
) ? Top
: statusbar
->dposition
;
304 statusbar
->position
= Off
;
306 globalconf
.screens
[statusbar
->screen
].need_arrange
= true;
309 /** Toggle the statusbar on or off.
310 * Argument must be a statusbar name, or no argument for all statusbars.
311 * \param screen Screen ID
312 * \param arg statusbar name
313 * \ingroup ui_callback
316 uicb_statusbar_toggle(int screen
, char *arg
)
318 Statusbar
*sb
= statusbar_getbyname(screen
, arg
);
321 statusbar_toggle(sb
);
323 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
324 statusbar_toggle(sb
);
326 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
327 statusbar_position_update(sb
);
330 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80