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"
31 extern AwesomeConf globalconf
;
34 statusbar_update_position(Statusbar
*statusbar
)
36 Area area
= get_screen_area(statusbar
->screen
,
38 &globalconf
.screens
[statusbar
->screen
].padding
);
40 XMapRaised(globalconf
.display
, statusbar
->window
);
41 switch(statusbar
->position
)
44 XMoveWindow(globalconf
.display
, statusbar
->window
,
48 XMoveWindow(globalconf
.display
, statusbar
->window
,
49 area
.x
, (area
.y
+ area
.height
) - statusbar
->width
);
52 XMoveWindow(globalconf
.display
, statusbar
->window
,
53 area
.x
+ (area
.width
- statusbar
->height
), area
.y
);
56 XMoveWindow(globalconf
.display
, statusbar
->window
,
57 area
.x
, area
.height
- statusbar
->height
);
60 XUnmapWindow(globalconf
.display
, statusbar
->window
);
66 statusbar_draw(Statusbar
*statusbar
)
68 int phys_screen
= get_phys_screen(statusbar
->screen
);
69 Widget
*widget
, *last_drawn
= NULL
;
70 int left
= 0, right
= 0;
71 Area rectangle
= { 0, 0, 0, 0 };
73 /* don't waste our time */
74 if(statusbar
->position
== Off
)
77 XFreePixmap(globalconf
.display
, statusbar
->drawable
);
79 DrawCtx
*ctx
= draw_get_context(phys_screen
,
83 rectangle
.width
= statusbar
->width
;
84 rectangle
.height
= statusbar
->height
;
85 draw_rectangle(ctx
, rectangle
, True
,
86 globalconf
.screens
[statusbar
->screen
].colors_normal
[ColBG
]);
88 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
89 if (widget
->alignment
== AlignLeft
)
91 widget
->cache
.needs_update
= False
;
92 left
+= widget
->draw(widget
, ctx
, left
, (left
+ right
));
95 /* renders right widget from last to first */
96 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
97 if (widget
->alignment
== AlignRight
&& last_drawn
== widget
->next
)
99 widget
->cache
.needs_update
= False
;
100 right
+= widget
->draw(widget
, ctx
, right
, (left
+ right
));
102 widget
= statusbar
->widgets
;
105 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
106 if (widget
->alignment
== AlignFlex
)
108 widget
->cache
.needs_update
= False
;
109 left
+= widget
->draw(widget
, ctx
, left
, (left
+ right
));
112 if(statusbar
->position
== Right
113 || statusbar
->position
== Left
)
115 if(statusbar
->position
== Right
)
116 statusbar
->drawable
= draw_rotate(ctx
, phys_screen
, M_PI_2
, statusbar
->height
, 0);
118 statusbar
->drawable
= draw_rotate(ctx
, phys_screen
, - M_PI_2
, 0, statusbar
->width
);
120 draw_free_context(ctx
);
124 statusbar
->drawable
= ctx
->drawable
;
125 /* just delete the struct, don't delete the drawable */
129 statusbar_display(statusbar
);
133 statusbar_display(Statusbar
*statusbar
)
135 int phys_screen
= get_phys_screen(statusbar
->screen
);
137 /* don't waste our time */
138 if(statusbar
->position
== Off
)
141 if(statusbar
->position
== Right
142 || statusbar
->position
== Left
)
143 XCopyArea(globalconf
.display
, statusbar
->drawable
,
145 DefaultGC(globalconf
.display
, phys_screen
), 0, 0,
147 statusbar
->width
, 0, 0);
149 XCopyArea(globalconf
.display
, statusbar
->drawable
,
151 DefaultGC(globalconf
.display
, phys_screen
), 0, 0,
152 statusbar
->width
, statusbar
->height
, 0, 0);
156 statusbar_init(Statusbar
*statusbar
, int screen
)
159 XSetWindowAttributes wa
;
160 int phys_screen
= get_phys_screen(screen
);
161 Area area
= get_screen_area(screen
,
162 globalconf
.screens
[screen
].statusbar
,
163 &globalconf
.screens
[screen
].padding
);
165 if(statusbar
->height
<= 0)
167 /* 1.5 as default factor, it fits nice but no one know why */
168 statusbar
->height
= globalconf
.screens
[screen
].font
->height
* 1.5;
170 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
172 statusbar
->height
= MAX(statusbar
->height
, widget
->font
->height
* 1.5);
175 if(statusbar
->width
<= 0)
177 if(statusbar
->position
== Right
|| statusbar
->position
== Left
)
178 statusbar
->width
= area
.height
;
180 statusbar
->width
= area
.width
;
183 statusbar
->screen
= screen
;
185 wa
.event_mask
= SubstructureRedirectMask
| SubstructureNotifyMask
186 | EnterWindowMask
| LeaveWindowMask
| StructureNotifyMask
;
187 wa
.cursor
= globalconf
.cursor
[CurNormal
];
188 wa
.override_redirect
= 1;
189 wa
.background_pixmap
= ParentRelative
;
190 wa
.event_mask
= ButtonPressMask
| ExposureMask
;
191 if(statusbar
->dposition
== Right
|| statusbar
->dposition
== Left
)
192 statusbar
->window
= XCreateWindow(globalconf
.display
,
193 RootWindow(globalconf
.display
,
199 DefaultDepth(globalconf
.display
,
202 DefaultVisual(globalconf
.display
,
209 statusbar
->window
= XCreateWindow(globalconf
.display
,
210 RootWindow(globalconf
.display
,
216 DefaultDepth(globalconf
.display
,
219 DefaultVisual(globalconf
.display
,
226 statusbar
->drawable
= XCreatePixmap(globalconf
.display
,
227 RootWindow(globalconf
.display
, phys_screen
),
228 statusbar
->width
, statusbar
->height
,
229 DefaultDepth(globalconf
.display
, phys_screen
));
232 XDefineCursor(globalconf
.display
,
234 globalconf
.cursor
[CurNormal
]);
236 widget_calculate_alignments(statusbar
->widgets
);
238 statusbar_update_position(statusbar
);
239 XMapRaised(globalconf
.display
, statusbar
->window
);
241 statusbar_draw(statusbar
);
248 Statusbar
*statusbar
;
251 for(screen
= 0; screen
< globalconf
.nscreens
; screen
++)
252 for(statusbar
= globalconf
.screens
[screen
].statusbar
;
254 statusbar
= statusbar
->next
)
255 for(widget
= statusbar
->widgets
; widget
; widget
= widget
->next
)
256 if(widget
->cache
.needs_update
)
258 statusbar_draw(statusbar
);
264 statusbar_get_position_from_str(const char *pos
)
266 if(!a_strncmp(pos
, "off", 3))
268 else if(!a_strncmp(pos
, "bottom", 6))
270 else if(!a_strncmp(pos
, "right", 5))
272 else if(!a_strncmp(pos
, "left", 4))
278 get_statusbar_byname(int screen
, const char *name
)
282 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
283 if(!a_strcmp(sb
->name
, name
))
290 statusbar_toggle(Statusbar
*statusbar
)
292 if(statusbar
->position
== Off
)
293 statusbar
->position
= (statusbar
->dposition
== Off
) ? Top
: statusbar
->dposition
;
295 statusbar
->position
= Off
;
297 statusbar_update_position(statusbar
);
301 * \param screen Screen ID
302 * \param arg statusbar name
303 * \ingroup ui_callback
306 uicb_statusbar_toggle(int screen
, char *arg
)
308 Statusbar
*sb
= get_statusbar_byname(screen
, arg
);
311 statusbar_toggle(sb
);
313 for(sb
= globalconf
.screens
[screen
].statusbar
; sb
; sb
= sb
->next
)
314 statusbar_toggle(sb
);
319 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80