fix rearrange
[awesome.git] / statusbar.c
blob4b7b1902296b403322738d7b97313f15bb118182
1 /*
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.
22 #include <stdio.h>
23 #include <math.h>
25 #include "statusbar.h"
26 #include "screen.h"
27 #include "util.h"
28 #include "tag.h"
29 #include "widget.h"
31 extern AwesomeConf globalconf;
33 static void
34 statusbar_draw(Statusbar *statusbar)
36 int phys_screen = get_phys_screen(statusbar->screen);
37 Widget *widget, *last_drawn = NULL;
38 int left = 0, right = 0;
40 /* don't waste our time */
41 if(statusbar->position == Off)
42 return;
44 XFreePixmap(globalconf.display, statusbar->drawable);
46 DrawCtx *ctx = draw_get_context(phys_screen,
47 statusbar->width,
48 statusbar->height);
50 draw_rectangle(ctx, 0, 0, statusbar->width, statusbar->height, True,
51 globalconf.screens[statusbar->screen].colors_normal[ColBG]);
53 for(widget = statusbar->widgets; widget; widget = widget->next)
54 if (widget->alignment == AlignLeft)
55 left += widget->draw(widget, ctx, left, (left + right));
57 /* renders right widget from last to first */
58 for(widget = statusbar->widgets; widget; widget = widget->next)
59 if (widget->alignment == AlignRight && last_drawn == widget->next)
61 right += widget->draw(widget, ctx, right, (left + right));
62 last_drawn = widget;
63 widget = statusbar->widgets;
66 for(widget = statusbar->widgets; widget; widget = widget->next)
67 if (widget->alignment == AlignFlex)
68 left += widget->draw(widget, ctx, left, (left + right));
70 if(statusbar->position == Right
71 || statusbar->position == Left)
73 Drawable d;
74 if(statusbar->position == Right)
75 d = draw_rotate(ctx, phys_screen, M_PI_2, statusbar->height, 0);
76 else
77 d = draw_rotate(ctx, phys_screen, - M_PI_2, 0, statusbar->width);
79 statusbar->drawable = d;
80 draw_free_context(ctx);
82 else
84 statusbar->drawable = ctx->drawable;
85 /* just delete the struct, don't delete the drawable */
86 p_delete(&ctx);
89 statusbar_display(statusbar);
92 void
93 statusbar_draw_all(int screen)
95 Statusbar *statusbar;
97 for(statusbar = globalconf.screens[screen].statusbar; statusbar; statusbar = statusbar->next)
98 statusbar_draw(statusbar);
101 void
102 statusbar_display(Statusbar *statusbar)
104 int phys_screen = get_phys_screen(statusbar->screen);
106 /* don't waste our time */
107 if(statusbar->position == Off)
108 return;
110 if(statusbar->position == Right
111 || statusbar->position == Left)
112 XCopyArea(globalconf.display, statusbar->drawable,
113 statusbar->window,
114 DefaultGC(globalconf.display, phys_screen), 0, 0,
115 statusbar->height,
116 statusbar->width, 0, 0);
117 else
118 XCopyArea(globalconf.display, statusbar->drawable,
119 statusbar->window,
120 DefaultGC(globalconf.display, phys_screen), 0, 0,
121 statusbar->width, statusbar->height, 0, 0);
124 void
125 statusbar_init(Statusbar *statusbar, int screen)
127 Widget *widget;
128 XSetWindowAttributes wa;
129 int phys_screen = get_phys_screen(screen);
130 Area area = get_screen_area(statusbar->screen,
131 NULL,
132 &globalconf.screens[screen].padding);
134 if(statusbar->height <= 0)
136 /* 1.5 as default factor, it fits nice but no one know why */
137 statusbar->height = globalconf.screens[screen].font->height * 1.5;
139 for(widget = statusbar->widgets; widget; widget = widget->next)
140 if(widget->font)
141 statusbar->height = MAX(statusbar->height, widget->font->height * 1.5);
144 if(statusbar->width <= 0)
146 if(statusbar->position == Right || statusbar->position == Left)
147 statusbar->width = area.height;
148 else
149 statusbar->width = area.width;
152 statusbar->screen = screen;
154 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
155 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
156 wa.cursor = globalconf.cursor[CurNormal];
157 wa.override_redirect = 1;
158 wa.background_pixmap = ParentRelative;
159 wa.event_mask = ButtonPressMask | ExposureMask;
160 if(statusbar->dposition == Right || statusbar->dposition == Left)
161 statusbar->window = XCreateWindow(globalconf.display,
162 RootWindow(globalconf.display,
163 phys_screen),
164 0, 0,
165 statusbar->height,
166 statusbar->width,
168 DefaultDepth(globalconf.display,
169 phys_screen),
170 CopyFromParent,
171 DefaultVisual(globalconf.display,
172 phys_screen),
173 CWOverrideRedirect |
174 CWBackPixmap |
175 CWEventMask,
176 &wa);
177 else
178 statusbar->window = XCreateWindow(globalconf.display,
179 RootWindow(globalconf.display,
180 phys_screen),
181 0, 0,
182 statusbar->width,
183 statusbar->height,
185 DefaultDepth(globalconf.display,
186 phys_screen),
187 CopyFromParent,
188 DefaultVisual(globalconf.display,
189 phys_screen),
190 CWOverrideRedirect |
191 CWBackPixmap |
192 CWEventMask,
193 &wa);
195 statusbar->drawable = XCreatePixmap(globalconf.display,
196 RootWindow(globalconf.display, phys_screen),
197 statusbar->width, statusbar->height,
198 DefaultDepth(globalconf.display, phys_screen));
201 XDefineCursor(globalconf.display,
202 statusbar->window,
203 globalconf.cursor[CurNormal]);
205 widget_calculate_alignments(statusbar->widgets);
207 statusbar_update_position(statusbar);
208 XMapRaised(globalconf.display, statusbar->window);
210 statusbar_draw(statusbar);
213 void
214 statusbar_update_position(Statusbar *statusbar)
216 XEvent ev;
217 Area area = get_screen_area(statusbar->screen,
218 NULL,
219 &globalconf.screens[statusbar->screen].padding);
221 XMapRaised(globalconf.display, statusbar->window);
222 switch(statusbar->position)
224 default:
225 XMoveWindow(globalconf.display, statusbar->window,
226 area.x, area.y);
227 break;
228 case Left:
229 XMoveWindow(globalconf.display, statusbar->window,
230 area.x, (area.y + area.height) - statusbar->width);
231 break;
232 case Right:
233 XMoveWindow(globalconf.display, statusbar->window,
234 area.x + (area.width - statusbar->height), area.y);
235 break;
236 case Bottom:
237 XMoveWindow(globalconf.display, statusbar->window,
238 area.x, area.height - statusbar->height);
239 break;
240 case Off:
241 XUnmapWindow(globalconf.display, statusbar->window);
242 break;
244 XSync(globalconf.display, False);
245 while(XCheckMaskEvent(globalconf.display, EnterWindowMask, &ev));
248 Position
249 statusbar_get_position_from_str(const char *pos)
251 if(!a_strncmp(pos, "off", 3))
252 return Off;
253 else if(!a_strncmp(pos, "bottom", 6))
254 return Bottom;
255 else if(!a_strncmp(pos, "right", 5))
256 return Right;
257 else if(!a_strncmp(pos, "left", 4))
258 return Left;
259 return Top;
262 static Statusbar *
263 get_statusbar_byname(int screen, const char *name)
265 Statusbar *sb;
267 for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next)
268 if(!a_strcmp(sb->name, name))
269 return sb;
271 return NULL;
275 static void
276 statusbar_toggle(Statusbar *statusbar)
278 if(statusbar->position == Off)
279 statusbar->position = (statusbar->dposition == Off) ? Top : statusbar->dposition;
280 else
281 statusbar->position = Off;
283 statusbar_update_position(statusbar);
286 /** Toggle statusbar
287 * \param screen Screen ID
288 * \param arg Unused
289 * \ingroup ui_callback
291 void
292 uicb_statusbar_toggle(int screen, char *arg)
294 Statusbar *sb = get_statusbar_byname(screen, arg);
296 if(sb)
297 statusbar_toggle(sb);
298 else
299 for(sb = globalconf.screens[screen].statusbar; sb; sb = sb->next)
300 statusbar_toggle(sb);
302 arrange(screen);
305 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80