fix statusbar display when on right
[awesome.git] / statusbar.c
blob03b7c7b758acdac01826f881cabe7ca8f3f3ea35
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 "layouts/tile.h"
32 /** Check if at least a client is tagged with tag number t and is on screen
33 * screen
34 * \param t tag number
35 * \param screen screen number
36 * \return True or False
38 static Bool
39 isoccupied(Client **head, unsigned int t, int screen)
41 Client *c;
43 for(c = *head; c; c = c->next)
44 if(c->tags[t] && c->screen == screen)
45 return True;
46 return False;
49 void
50 drawstatusbar(awesome_config *awesomeconf)
52 int z, i, x = 0, y = 0, w;
53 Client *sel = get_current_tag(awesomeconf->tags, awesomeconf->ntags)->client_sel;
55 for(i = 0; i < awesomeconf->ntags; i++)
57 w = textwidth(awesomeconf->display, awesomeconf->font,
58 awesomeconf->tags[i].name);
59 if(awesomeconf->tags[i].selected)
61 drawtext(awesomeconf->display, awesomeconf->phys_screen,
62 x, y, w,
63 awesomeconf->statusbar.height,
64 awesomeconf->statusbar.drawable,
65 awesomeconf->statusbar.width,
66 awesomeconf->statusbar.height,
67 awesomeconf->font,
68 awesomeconf->tags[i].name, awesomeconf->colors_selected);
69 if(isoccupied(awesomeconf->clients, i, awesomeconf->screen))
70 drawrectangle(awesomeconf->display, awesomeconf->phys_screen,
71 x, y,
72 (awesomeconf->font->height + 2) / 4,
73 (awesomeconf->font->height + 2) / 4,
74 awesomeconf->statusbar.drawable,
75 awesomeconf->statusbar.width,
76 awesomeconf->statusbar.height,
77 sel && sel->tags[i],
78 awesomeconf->colors_selected[ColFG]);
80 else
82 drawtext(awesomeconf->display, awesomeconf->phys_screen,
83 x, y, w,
84 awesomeconf->statusbar.height,
85 awesomeconf->statusbar.drawable,
86 awesomeconf->statusbar.width,
87 awesomeconf->statusbar.height,
88 awesomeconf->font,
89 awesomeconf->tags[i].name, awesomeconf->colors_normal);
90 if(isoccupied(awesomeconf->clients, i, awesomeconf->screen))
91 drawrectangle(awesomeconf->display, awesomeconf->phys_screen,
92 x, y,
93 (awesomeconf->font->height + 2) / 4,
94 (awesomeconf->font->height + 2) / 4,
95 awesomeconf->statusbar.drawable,
96 awesomeconf->statusbar.width,
97 awesomeconf->statusbar.height,
98 sel && sel->tags[i],
99 awesomeconf->colors_normal[ColFG]);
101 x += w;
103 drawtext(awesomeconf->display, awesomeconf->phys_screen,
104 x, y, awesomeconf->statusbar.txtlayoutwidth,
105 awesomeconf->statusbar.height,
106 awesomeconf->statusbar.drawable,
107 awesomeconf->statusbar.width,
108 awesomeconf->statusbar.height,
109 awesomeconf->font,
110 get_current_layout(awesomeconf->tags, awesomeconf->ntags)->symbol,
111 awesomeconf->colors_normal);
112 z = x + awesomeconf->statusbar.txtlayoutwidth;
113 w = textwidth(awesomeconf->display, awesomeconf->font, awesomeconf->statustext);
114 x = awesomeconf->statusbar.width - w;
115 if(x < z)
117 x = z;
118 w = awesomeconf->statusbar.width - z;
120 drawtext(awesomeconf->display, awesomeconf->phys_screen,
121 x, y, w,
122 awesomeconf->statusbar.height,
123 awesomeconf->statusbar.drawable,
124 awesomeconf->statusbar.width,
125 awesomeconf->statusbar.height,
126 awesomeconf->font,
127 awesomeconf->statustext, awesomeconf->colors_normal);
128 if((w = x - z) > awesomeconf->statusbar.height)
130 x = z;
131 if(sel && sel->screen == awesomeconf->screen)
133 drawtext(awesomeconf->display, awesomeconf->phys_screen,
134 x, y, w,
135 awesomeconf->statusbar.height,
136 awesomeconf->statusbar.drawable,
137 awesomeconf->statusbar.width,
138 awesomeconf->statusbar.height,
139 awesomeconf->font,
140 sel->name, awesomeconf->colors_selected);
141 if(sel->isfloating)
142 drawcircle(awesomeconf->display, awesomeconf->phys_screen,
143 x, y,
144 (awesomeconf->font->height + 2) / 4,
145 awesomeconf->statusbar.drawable,
146 awesomeconf->statusbar.width,
147 awesomeconf->statusbar.height,
148 sel->ismax,
149 awesomeconf->colors_selected[ColFG]);
151 else
152 drawtext(awesomeconf->display, awesomeconf->phys_screen,
153 x, y, w,
154 awesomeconf->statusbar.height,
155 awesomeconf->statusbar.drawable,
156 awesomeconf->statusbar.width,
157 awesomeconf->statusbar.height,
158 awesomeconf->font,
159 NULL, awesomeconf->colors_normal);
161 if(awesomeconf->statusbar.position == BarRight
162 || awesomeconf->statusbar.position == BarLeft)
164 if(awesomeconf->statusbar.position == BarRight)
165 draw_rotate(awesomeconf->display, awesomeconf->phys_screen,
166 awesomeconf->statusbar.drawable, awesomeconf->statusbar.width,
167 awesomeconf->statusbar.height, M_PI * 0.5,
168 0, -awesomeconf->statusbar.height);
169 else
170 draw_rotate(awesomeconf->display, awesomeconf->phys_screen,
171 awesomeconf->statusbar.drawable, awesomeconf->statusbar.width,
172 awesomeconf->statusbar.height, M_PI * 0.5,
173 0, -awesomeconf->statusbar.height);
174 XCopyArea(awesomeconf->display, awesomeconf->statusbar.drawable,
175 awesomeconf->statusbar.window,
176 DefaultGC(awesomeconf->display, awesomeconf->phys_screen), 0, 0,
177 awesomeconf->statusbar.height, awesomeconf->statusbar.width, 0, 0);
179 else
180 XCopyArea(awesomeconf->display, awesomeconf->statusbar.drawable,
181 awesomeconf->statusbar.window,
182 DefaultGC(awesomeconf->display, awesomeconf->phys_screen), 0, 0,
183 awesomeconf->statusbar.width, awesomeconf->statusbar.height, 0, 0);
184 XSync(awesomeconf->display, False);
187 void
188 initstatusbar(Display *disp, int screen, Statusbar *statusbar, Cursor cursor, XftFont *font, Layout *layouts, int nlayouts)
190 XSetWindowAttributes wa;
191 int i, phys_screen = get_phys_screen(disp, screen);
192 ScreenInfo *si = get_screen_info(disp, screen, NULL);
194 statusbar->height = font->height * 1.5;
196 if(statusbar->position == BarRight || statusbar->position == BarLeft)
197 statusbar->width = si[screen].height;
198 else
199 statusbar->width = si[screen].width;
201 p_delete(&si);
203 statusbar->screen = screen;
205 wa.event_mask = SubstructureRedirectMask | SubstructureNotifyMask
206 | EnterWindowMask | LeaveWindowMask | StructureNotifyMask;
207 wa.cursor = cursor;
208 wa.override_redirect = 1;
209 wa.background_pixmap = ParentRelative;
210 wa.event_mask = ButtonPressMask | ExposureMask;
211 if(statusbar->dposition == BarRight || statusbar->dposition == BarLeft)
213 statusbar->window = XCreateWindow(disp, RootWindow(disp, phys_screen), 0, 0,
214 statusbar->height,
215 statusbar->width,
216 0, DefaultDepth(disp, phys_screen), CopyFromParent,
217 DefaultVisual(disp, phys_screen),
218 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
219 statusbar->drawable = XCreatePixmap(disp,
220 RootWindow(disp, phys_screen),
221 statusbar->width,
222 statusbar->width,
223 DefaultDepth(disp, phys_screen));
225 else
227 statusbar->window = XCreateWindow(disp, RootWindow(disp, phys_screen), 0, 0,
228 statusbar->width,
229 statusbar->height,
230 0, DefaultDepth(disp, phys_screen), CopyFromParent,
231 DefaultVisual(disp, phys_screen),
232 CWOverrideRedirect | CWBackPixmap | CWEventMask, &wa);
233 statusbar->drawable = XCreatePixmap(disp,
234 RootWindow(disp, phys_screen),
235 statusbar->width,
236 statusbar->height,
237 DefaultDepth(disp, phys_screen));
239 XDefineCursor(disp, statusbar->window, cursor);
240 updatebarpos(disp, *statusbar);
241 XMapRaised(disp, statusbar->window);
243 for(i = 0; i < nlayouts; i++)
244 statusbar->txtlayoutwidth = MAX(statusbar->txtlayoutwidth,
245 (textwidth(disp, font, layouts[i].symbol)));
248 void
249 updatebarpos(Display *disp, Statusbar statusbar)
251 XEvent ev;
252 ScreenInfo *si = get_screen_info(disp, statusbar.screen, NULL);
254 switch (statusbar.position)
256 default:
257 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].y_org);
258 break;
259 case BarRight:
260 XMoveWindow(disp, statusbar.window, si[statusbar.screen].width - statusbar.height, si[statusbar.screen].y_org);
261 break;
262 case BarBot:
263 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].height - statusbar.height);
264 break;
265 case BarOff:
266 XMoveWindow(disp, statusbar.window, si[statusbar.screen].x_org, si[statusbar.screen].y_org - statusbar.height);
267 break;
269 p_delete(&si);
270 XSync(disp, False);
271 while(XCheckMaskEvent(disp, EnterWindowMask, &ev));
274 void
275 uicb_togglebar(awesome_config *awesomeconf,
276 const char *arg __attribute__ ((unused)))
278 if(awesomeconf->statusbar.position == BarOff)
279 awesomeconf->statusbar.position = (awesomeconf->statusbar.dposition == BarOff) ? BarTop : awesomeconf->statusbar.dposition;
280 else
281 awesomeconf->statusbar.position = BarOff;
282 updatebarpos(awesomeconf->display, awesomeconf->statusbar);
283 arrange(awesomeconf);
287 void
288 uicb_setstatustext(awesome_config *awesomeconf, const char *arg)
290 if(!arg)
291 return;
292 a_strncpy(awesomeconf->statustext, sizeof(awesomeconf->statustext), arg, a_strlen(arg));
294 drawstatusbar(awesomeconf);
296 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99