2 * statusbar.c - statusbar functions
4 * Copyright © 2007 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 "statusbar.h"
30 #include "common/util.h"
32 extern AwesomeConf globalconf
;
35 statusbar_update_position(Statusbar
*statusbar
)
39 XMapRaised(globalconf
.display
, statusbar
->sw
->window
);
41 /* Top and Bottom Statusbar have prio */
42 if(statusbar
->position
== Top
|| statusbar
->position
== Bottom
)
43 area
= get_screen_area(statusbar
->screen
,
45 &globalconf
.screens
[statusbar
->screen
].padding
);
47 area
= get_screen_area(statusbar
->screen
,
48 globalconf
.screens
[statusbar
->screen
].statusbar
,
49 &globalconf
.screens
[statusbar
->screen
].padding
);
51 switch(statusbar
->position
)
54 simplewindow_move(statusbar
->sw
, area
.x
, area
.y
);
57 simplewindow_move(statusbar
->sw
, area
.x
, (area
.y
+ area
.height
) - statusbar
->sw
->geometry
.height
);
60 simplewindow_move(statusbar
->sw
, area
.x
- statusbar
->sw
->geometry
.width
,
61 (area
.y
+ area
.height
) - statusbar
->sw
->geometry
.height
);
64 simplewindow_move(statusbar
->sw
, area
.x
+ area
.width
, area
.y
);
67 XUnmapWindow(globalconf
.display
, statusbar
->sw
->window
);
73 statusbar_draw(Statusbar
*statusbar
)
75 int phys_screen
= get_phys_screen(statusbar
->screen
);
76 Widget
*widget
, *last_drawn
= NULL
;
77 int left
= 0, right
= 0;
78 Area rectangle
= { 0, 0, 0, 0 };
81 /* don't waste our time */
82 switch(statusbar
->position
)
89 /* we need a new pixmap this way [ ] to render */
90 XFreePixmap(globalconf
.display
, statusbar
->sw
->drawable
);
91 d
= XCreatePixmap(globalconf
.display
,
92 RootWindow(globalconf
.display
, phys_screen
),
93 statusbar
->width
, statusbar
->height
,
94 DefaultDepth(globalconf
.display
, phys_screen
));
95 statusbar
->sw
->drawable
= d
;
101 DrawCtx
*ctx
= draw_get_context(globalconf
.display
,
105 statusbar
->sw
->drawable
);
107 rectangle
.width
= statusbar
->width
;
108 rectangle
.height
= statusbar
->height
;
109 draw_rectangle(ctx
, rectangle
, True
,
110 globalconf
.screens
[statusbar
->screen
].colors_normal
[ColBG
]);
112 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
113 if (widget
->alignment
== AlignLeft
)
115 widget
->cache
.needs_update
= False
;
116 left
+= widget
->draw(widget
, ctx
, left
, (left
+ right
));
119 /* renders right widget from last to first */
120 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
121 if (widget
->alignment
== AlignRight
&& last_drawn
== widget
->next
)
123 widget
->cache
.needs_update
= False
;
124 right
+= widget
->draw(widget
, ctx
, right
, (left
+ right
));
126 widget
= statusbar
->widgets
;
129 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
130 if (widget
->alignment
== AlignFlex
)
132 widget
->cache
.needs_update
= False
;
133 left
+= widget
->draw(widget
, ctx
, left
, (left
+ right
));
136 switch(statusbar
->position
)
139 d
= draw_rotate(ctx
, phys_screen
, M_PI_2
,
140 statusbar
->height
, 0);
141 XFreePixmap(globalconf
.display
, statusbar
->sw
->drawable
);
142 statusbar
->sw
->drawable
= d
;
145 d
= draw_rotate(ctx
, phys_screen
, - M_PI_2
,
146 0, statusbar
->width
);
147 XFreePixmap(globalconf
.display
, statusbar
->sw
->drawable
);
148 statusbar
->sw
->drawable
= d
;
156 statusbar_display(statusbar
);
160 statusbar_display(Statusbar
*statusbar
)
162 /* don't waste our time */
163 if(statusbar
->position
!= Off
)
164 simplewindow_refresh_drawable(statusbar
->sw
, get_phys_screen(statusbar
->screen
));
168 statusbar_preinit(Statusbar
*statusbar
)
172 if(statusbar
->height
<= 0)
174 /* 1.5 as default factor, it fits nice but no one know why */
175 statusbar
->height
= globalconf
.screens
[statusbar
->screen
].font
->height
* 1.5;
177 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
179 statusbar
->height
= MAX(statusbar
->height
, widget
->font
->height
* 1.5);
184 statusbar_init(Statusbar
*statusbar
)
187 int phys_screen
= get_phys_screen(statusbar
->screen
);
188 Area area
= get_screen_area(statusbar
->screen
,
189 globalconf
.screens
[statusbar
->screen
].statusbar
,
190 &globalconf
.screens
[statusbar
->screen
].padding
);
193 /* Top and Bottom Statusbar have prio */
194 for(sb
= globalconf
.screens
[statusbar
->screen
].statusbar
; sb
; sb
= sb
->next
)
199 area
.width
+= sb
->height
;
205 if(statusbar
->width
<= 0)
207 if(statusbar
->position
== Right
|| statusbar
->position
== Left
)
208 statusbar
->width
= area
.height
;
210 statusbar
->width
= area
.width
;
213 switch(statusbar
->dposition
)
218 simplewindow_new(phys_screen
, 0, 0, statusbar
->height
, statusbar
->width
, 0);
222 simplewindow_new(phys_screen
, 0, 0, statusbar
->width
, statusbar
->height
, 0);
226 widget_calculate_alignments(statusbar
->widgets
);
228 statusbar_update_position(statusbar
);
230 statusbar_draw(statusbar
);
237 Statusbar
*statusbar
;
240 for(screen
= 0; screen
< globalconf
.nscreen
; screen
++)
241 for(statusbar
= globalconf
.screens
[screen
].statusbar
;
243 statusbar
= statusbar
->next
)
244 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
245 if(widget
->cache
.needs_update
)
247 statusbar_draw(statusbar
);
253 statusbar_get_position_from_str(const char *pos
)
255 if(!a_strncmp(pos
, "off", 3))
257 else if(!a_strncmp(pos
, "bottom", 6))
259 else if(!a_strncmp(pos
, "right", 5))
261 else if(!a_strncmp(pos
, "left", 4))
267 get_statusbar_byname(int screen
, const char *name
)
271 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
272 if(!a_strcmp(sb
->name
, name
))
279 statusbar_toggle(Statusbar
*statusbar
)
281 if(statusbar
->position
== Off
)
282 statusbar
->position
= (statusbar
->dposition
== Off
) ? Top
: statusbar
->dposition
;
284 statusbar
->position
= Off
;
286 statusbar_update_position(statusbar
);
287 globalconf
.screens
[statusbar
->screen
].need_arrange
= True
;
291 * \param screen Screen ID
292 * \param arg statusbar name
293 * \ingroup ui_callback
296 uicb_statusbar_toggle(int screen
, char *arg
)
298 Statusbar
*sb
= get_statusbar_byname(screen
, arg
);
301 statusbar_toggle(sb
);
303 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
304 statusbar_toggle(sb
);
307 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80