introduce get_current_tags() and deprecate get_current_{tag,layout}()
[awesome.git] / statusbar.c
blob098bcbedfbf3dcb2a6b707526e08f6ce1f1e79db
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 "layout.h"
26 #include "statusbar.h"
27 #include "draw.h"
28 #include "screen.h"
29 #include "util.h"
30 #include "tag.h"
31 #include "widget.h"
33 extern AwesomeConf globalconf;
35 void
36 statusbar_draw(int screen)
38 int phys_screen = get_phys_screen(screen);
39 VirtScreen vscreen;
40 Widget *widget, *last_drawn = NULL;
41 int left = 0, right = 0;
43 vscreen = globalconf.screens[screen];
44 /* don't waste our time */
45 if(vscreen.statusbar->position == BarOff)
46 return;
48 DrawCtx *ctx = draw_get_context(globalconf.display, phys_screen,
49 vscreen.statusbar->width,
50 vscreen.statusbar->height);
51 draw_rectangle(ctx,
54 vscreen.statusbar->width,
55 vscreen.statusbar->height,
56 True,
57 vscreen.colors_normal[ColBG]);
58 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
59 if (widget->alignment == AlignLeft)
60 left += widget->draw(widget, ctx, left, (left + right));
62 /* renders right widget from last to first */
63 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
64 if (widget->alignment == AlignRight && last_drawn == widget->next)
66 right += widget->draw(widget, ctx, right, (left + right));
67 last_drawn = widget;
68 widget = vscreen.statusbar->widgets;
71 for(widget = vscreen.statusbar->widgets; widget; widget = widget->next)
72 if (widget->alignment == AlignFlex)
73 left += widget->draw(widget, ctx, left, (left + right));
75 if(vscreen.statusbar->position == BarRight ||
76 vscreen.statusbar->position == BarLeft)
78 Drawable d;
79 if(vscreen.statusbar->position == BarRight)
80 d = draw_rotate(ctx,
81 phys_screen,
82 M_PI_2,
83 vscreen.statusbar->height,
84 0);
85 else
86 d = draw_rotate(ctx,
87 phys_screen,
88 - M_PI_2,
90 vscreen.statusbar->width);
91 XCopyArea(globalconf.display, d,
92 vscreen.statusbar->window,
93 DefaultGC(globalconf.display, phys_screen), 0, 0,
94 vscreen.statusbar->height,
95 vscreen.statusbar->width, 0, 0);
96 XFreePixmap(globalconf.display, d);
98 else
99 XCopyArea(globalconf.display, ctx->drawable,
100 vscreen.statusbar->window,
101 DefaultGC(globalconf.display, phys_screen), 0, 0,
102 vscreen.statusbar->width, vscreen.statusbar->height, 0, 0);
104 draw_free_context(ctx);
105 XSync(globalconf.display, False);
108 void
109 statusbar_init(int screen)
111 XSetWindowAttributes wa;
112 int phys_screen = get_phys_screen(screen);
113 Area area = get_screen_area(screen,
114 NULL,
115 &globalconf.screens[screen].padding);
116 Statusbar *statusbar = globalconf.screens[screen].statusbar;
118 statusbar->height = globalconf.screens[screen].font->height * 1.5;
120 if(statusbar->position == BarRight || statusbar->position == BarLeft)
121 statusbar->width = area.height;
122 else
123 statusbar->width = area.width;
125 statusbar->screen = screen;
127 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
128 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
129 wa.cursor = globalconf.cursor[CurNormal];
130 wa.override_redirect = 1;
131 wa.background_pixmap = ParentRelative;
132 wa.event_mask = ButtonPressMask | ExposureMask;
133 if(statusbar->dposition == BarRight || statusbar->dposition == BarLeft)
134 statusbar->window = XCreateWindow(globalconf.display,
135 RootWindow(globalconf.display,
136 phys_screen),
137 0, 0,
138 statusbar->height,
139 statusbar->width,
141 DefaultDepth(globalconf.display,
142 phys_screen),
143 CopyFromParent,
144 DefaultVisual(globalconf.display,
145 phys_screen),
146 CWOverrideRedirect |
147 CWBackPixmap |
148 CWEventMask,
149 &wa);
150 else
151 statusbar->window = XCreateWindow(globalconf.display,
152 RootWindow(globalconf.display,
153 phys_screen),
154 0, 0,
155 statusbar->width,
156 statusbar->height,
158 DefaultDepth(globalconf.display,
159 phys_screen),
160 CopyFromParent,
161 DefaultVisual(globalconf.display,
162 phys_screen),
163 CWOverrideRedirect |
164 CWBackPixmap |
165 CWEventMask,
166 &wa);
167 XDefineCursor(globalconf.display,
168 statusbar->window,
169 globalconf.cursor[CurNormal]);
171 widget_calculate_alignments(statusbar->widgets);
173 statusbar_update_position(screen);
174 XMapRaised(globalconf.display, statusbar->window);
177 void
178 statusbar_update_position(int screen)
180 XEvent ev;
181 Statusbar *statusbar = globalconf.screens[screen].statusbar;
182 Area area = get_screen_area(statusbar->screen,
183 NULL,
184 &globalconf.screens[screen].padding);
186 XMapRaised(globalconf.display, statusbar->window);
187 switch (statusbar->position)
189 default:
190 XMoveWindow(globalconf.display,
191 statusbar->window,
192 area.x,
193 area.y);
194 break;
195 case BarRight:
196 XMoveWindow(globalconf.display,
197 statusbar->window,
198 area.x + (area.width - statusbar->height),
199 area.y);
200 break;
201 case BarBot:
202 XMoveWindow(globalconf.display,
203 statusbar->window,
204 area.x,
205 area.height - statusbar->height);
206 break;
207 case BarOff:
208 XUnmapWindow(globalconf.display, statusbar->window);
209 break;
211 XSync(globalconf.display, False);
212 while(XCheckMaskEvent(globalconf.display, EnterWindowMask, &ev));
216 statusbar_get_position_from_str(const char * pos)
218 if(!a_strncmp(pos, "off", 3))
219 return BarOff;
220 else if(!a_strncmp(pos, "bottom", 6))
221 return BarBot;
222 else if(!a_strncmp(pos, "right", 5))
223 return BarRight;
224 else if(!a_strncmp(pos, "left", 4))
225 return BarLeft;
226 return BarTop;
229 /** Toggle statusbar
230 * \param screen Screen ID
231 * \param arg Unused
232 * \ingroup ui_callback
234 void
235 uicb_statusbar_toggle(int screen, char *arg __attribute__ ((unused)))
237 if(globalconf.screens[screen].statusbar->position == BarOff)
238 globalconf.screens[screen].statusbar->position = (globalconf.screens[screen].statusbar->dposition == BarOff) ? BarTop : globalconf.screens[screen].statusbar->dposition;
239 else
240 globalconf.screens[screen].statusbar->position = BarOff;
241 statusbar_update_position(screen);
242 arrange(screen);
245 /** Set statusbar position
246 * \param screen Screen ID
247 * \param arg off | bottom | right | left | top
248 * \ingroup ui_callback
250 void
251 uicb_statusbar_set_position(int screen, char *arg)
253 globalconf.screens[screen].statusbar->dposition =
254 globalconf.screens[screen].statusbar->position =
255 statusbar_get_position_from_str(arg);
256 statusbar_update_position(screen);
259 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=80