7 #include <openbox/theme.h>
11 static RrAppearance *background;
12 static RrAppearance *focused_task;
13 static RrAppearance *iconified_task;
14 static RrAppearance *unfocused_task;
15 static RrAppearance *normal_text;
16 static RrAppearance *iconified_text;
17 static RrAppearance *shaded_text;
18 static RrAppearance *focused_text;
19 static RrAppearance *a_icon;
20 static RrColor *normal_text_color;
21 static RrColor *focused_text_color;
23 /* you can edit these */
24 #define MAX_TASK_WIDTH 500
25 #define HEIGHT (24 - sc->theme->obwidth)
27 #define ICON_SIZE (HEIGHT - sc->theme->obwidth - PADDING*2)
28 #define ICON_SPACE (ICON_SIZE + PADDING*2)
30 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk);
32 #define SURF(x) with->surface.x
33 #define TEXT(x) with->texture[0].data.text.x
34 #define USE(x) (with = x)
35 #define SETTEXT(x, y, z) with->texture[0].type = RR_TEXTURE_TEXT; \
36 with->texture[0].data.text.font = x; \
37 with->texture[0].data.text.justify = y; \
38 with->texture[0].data.text.ellipsize = z;
39 #define SETSHADOW(y, z, u, v) with->texture[0].data.text.shadow_offset_x = y; \
40 with->texture[0].data.text.shadow_offset_y = z; \
41 with->texture[0].data.text.shadow_alpha = u; \
42 with->texture[0].data.text.shadow_color = v;
44 void gui_init(screen *sc)
48 gcv.graphics_exposures = False;
49 sc->fore_gc = XCreateGC(sc->dd, sc->root, GCGraphicsExposures, &gcv);
51 gui_load_theme(sc, NULL);
54 void gui_load_theme(screen *sc, taskbar *tb)
60 printf("loading theme\n");
62 RrAppearanceFree(background);
63 RrAppearanceFree(focused_task);
64 RrAppearanceFree(iconified_task);
65 RrAppearanceFree(unfocused_task);
66 RrAppearanceFree(normal_text);
67 RrAppearanceFree(iconified_text);
68 RrAppearanceFree(shaded_text);
69 RrAppearanceFree(focused_text);
70 RrAppearanceFree(a_icon);
71 RrColorFree(normal_text_color);
72 RrColorFree(focused_text_color);
74 name = xprop_get_utf8(sc, sc->root, _OB_THEME);
75 RrThemeFree(sc->theme);
76 sc->theme = RrThemeNew(sc->rr, name, TRUE, NULL, NULL, NULL, NULL, NULL);
78 /* We don't allow different fonts for various window states... */
79 font = RrFontOpen(sc->rr, "Candara, sans", 10,
80 RR_FONTWEIGHT_NORMAL, RR_FONTSLANT_NORMAL);
82 /* this appearance will be used to draw icons */
83 a_icon = RrAppearanceNew(sc->rr, 1);
85 SURF(grad) = RR_SURFACE_PARENTREL;
86 a_icon->texture[0].type = RR_TEXTURE_RGBA;
88 /* this is the appearance for the background of the panel */
89 background = RrAppearanceCopy(sc->theme->osd_hilite_bg);
91 /* this is the appearance for unfocused tasks,
92 * text needs to be separate appearances so we can align it correctly */
93 unfocused_task = RrAppearanceNew(sc->rr, 0);
95 SURF(parent) = background;
96 SURF(grad) = RR_SURFACE_PARENTREL;
98 /* ... for iconified tasks, also used for shaded ones currently */
99 iconified_task = RrAppearanceCopy(unfocused_task);
101 SURF(parent) = background; /* RrAppearanceCopy doesn't copy .parent */
103 /* ... for focused tasks */
104 focused_task = RrAppearanceCopy(sc->theme->a_hover_focused_max);
106 SURF(parent) = background;
108 /* this is the text used for all normal unfocused tasks */
109 /* we don't set .parent here, but in draw_task, since we
110 * want to combine _task and _text semirandomly.
111 * XXX plz not when themes are here */
112 normal_text = RrAppearanceCopy(sc->theme->osd_hilite_label);
113 normal_text_color = RrColorNew(sc->rr,
114 RrColorRed(sc->theme->osd_color),
115 RrColorGreen(sc->theme->osd_color),
116 RrColorBlue(sc->theme->osd_color));
118 TEXT(color) = normal_text_color;
119 TEXT(ellipsize) = RR_ELLIPSIZE_END;
121 /* ... for iconified tasks */
122 iconified_text = RrAppearanceCopy(normal_text);
123 shaded_text = RrAppearanceCopy(normal_text);
125 focused_text = RrAppearanceCopy(normal_text);
128 RrColorRed(sc->theme->titlebut_hover_focused_color),
129 RrColorGreen(sc->theme->titlebut_hover_focused_color),
130 RrColorBlue(sc->theme->titlebut_hover_focused_color));
132 TEXT(color) = focused_text_color;
133 TEXT(ellipsize) = RR_ELLIPSIZE_END;
137 if (tb) tb->draww = tb->drawh = 0; /* make sure the taskbar redraws */
140 void gui_create_taskbar(screen *sc, taskbar *tb)
142 XSizeHints size_hints;
143 XSetWindowAttributes att;
146 att.event_mask = ButtonPressMask;
148 /* XXX make this stuff configurable */
149 tb->w = sc->width * 0.65;
152 tb->x = (sc->width - tb->w) / 2;
153 tb->y = sc->height - tb->h;
155 tb->win = XCreateWindow(/* display */ sc->dd,
156 /* parent */ sc->root,
162 /* depth */ CopyFromParent,
163 /* class */ InputOutput,
164 /* visual */ CopyFromParent,
165 /*value mask*/ CWEventMask,
167 tb->bgwin = XCreateWindow(/* display */ sc->dd,
168 /* parent */ tb->win,
174 /* depth */ CopyFromParent,
175 /* class */ InputOutput,
176 /* visual */ CopyFromParent,
181 /* reside on ALL desktops */
182 xprop_set_num(sc, tb->win, _NET_WM_DESKTOP, 0xFFFFFFFF);
183 xprop_set_atom(sc, tb->win, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DOCK);
184 xprop_set_atom(sc, tb->win, _NET_WM_STATE, _NET_WM_STATE_BELOW);
185 xprop_set_string(sc, tb->win, WM_NAME, "rspanel");
187 /* make sure the WM obays our window position */
188 size_hints.flags = PPosition;
189 size_hints.x = tb->x;
190 size_hints.y = tb->y;
191 /*XSetWMNormalHints (sc->dd, tb->win, &size_hints); */
192 XChangeProperty(sc->dd, tb->win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32,
193 PropModeReplace, (unsigned char *)&size_hints,
194 sizeof(XSizeHints) / 4);
196 xclhints.res_name = "rspanel";
197 xclhints.res_class = "RSPanel";
198 XSetClassHint(sc->dd, tb->win, &xclhints);
200 XMapWindow(sc->dd, tb->win);
201 XMapWindow(sc->dd, tb->bgwin);
204 void gui_draw_task(screen *sc, taskbar *tb, task *tk, int redraw)
214 else if (tk->focused)
225 else if (tk->focused)
231 name = g_strconcat("(", tk->name, ")", NULL);
233 name = g_strdup(tk->name);
235 i = icon_get_best(tk->icons, tk->nicons, ICON_SIZE, ICON_SIZE);
238 RrTextureRGBA *d = &a_icon->texture[0].data.rgba;
239 icon_space = ICON_SPACE;
240 a_icon->surface.parent = b;
241 a_icon->surface.parentx = (icon_space - ICON_SIZE) / 2;
242 a_icon->surface.parenty = (tb->drawh - ICON_SIZE) / 2;
244 d->height = i->height;
245 d->alpha = tk->iconified ? 0x70 : tk->shaded ? 0xB0 : 0xff;
248 icon_space = PADDING;
250 a->surface.parent = b;
251 a->surface.parentx = icon_space;
252 a->texture[0].data.text.string = name;
253 b->surface.parentx = tk->pos_x;
255 RrPaintPixmap(b, tk->width, tb->drawh);
256 RrPaintPixmap(a, tk->width-icon_space-PADDING, tb->drawh);
259 RrPaintPixmap(a_icon, ICON_SIZE, ICON_SIZE);
260 XCopyArea(sc->dd, a_icon->pixmap, b->pixmap, sc->fore_gc, 0, 0,
261 ICON_SIZE, ICON_SIZE,
262 (icon_space - ICON_SIZE) / 2,
263 (tb->drawh - ICON_SIZE) / 2);
266 XCopyArea(sc->dd, a->pixmap, b->pixmap, sc->fore_gc, 0, 0,
267 tk->width-icon_space-PADDING, tb->drawh,
269 XCopyArea(sc->dd, b->pixmap, tb->bg, sc->fore_gc, 0, 0,
270 tk->width, tb->drawh, tk->pos_x, 0);
272 XFreePixmap(sc->dd, a->pixmap);
273 XFreePixmap(sc->dd, b->pixmap);
274 XFreePixmap(sc->dd, a_icon->pixmap);
276 XSetWindowBackgroundPixmap(sc->dd, tb->bgwin, tb->bg);
277 XClearWindow(sc->dd, tb->bgwin);
283 void gui_draw_taskbar(screen *sc, taskbar *tb)
293 pager_size = GRILL_WIDTH;
299 tb->draww = tb->w - sc->theme->obwidth * 2;
300 tb->drawh = tb->h - sc->theme->obwidth;
301 XMoveResizeWindow(sc->dd, tb->bgwin, 0,
302 (tb->at_top ? -sc->theme->obwidth : 0),
303 tb->draww, tb->drawh);
306 width = tb->draww - (pager_size + GRILL_WIDTH);
308 /* only re-render if the size has changed */
309 if (tb->draww != ow || tb->drawh != oh) {
310 if (tb->bg) XFreePixmap(sc->dd, tb->bg);
311 tb->bg = XCreatePixmap(sc->dd, sc->root, tb->draww, tb->drawh,
313 XFreePixmap(sc->dd, RrPaintPixmap(background, tb->draww, tb->drawh));
314 XCopyArea(sc->dd, background->pixmap, tb->bg, sc->fore_gc, 0, 0,
315 tb->draww, tb->drawh, 0, 0);
318 /* find the number of visible tasks */
319 for (tk = tb->task_list; tk; tk = tk->next) {
328 taskw = width / num_tasks;
330 for (tk = tb->task_list; tk; tk = tk->next) {
334 /* use up extra pixels in the last task */
336 tk->width = MIN(width - x, MAX_TASK_WIDTH);
338 tk->width = MIN(taskw, MAX_TASK_WIDTH);
339 gui_draw_task(sc, tb, tk, FALSE);
340 set_icon_geometry(sc, tb, tk);
345 XSetWindowBackgroundPixmap(sc->dd, tb->bgwin, tb->bg);
346 XClearWindow(sc->dd, tb->bgwin);
347 XSetWindowBorderWidth(sc->dd, tb->bgwin, sc->theme->obwidth);
348 XSetWindowBorder(sc->dd, tb->bgwin,
349 RrColorPixel(sc->theme->osd_border_color));
352 void gui_move_taskbar(screen *sc, taskbar *tb)
357 tb->x = TEXTPAD - tb->w;
360 tb->y = sc->height - tb->h;
362 XMoveWindow(sc->dd, tb->win, tb->x, tb->y);
364 gui_draw_taskbar(sc, tb);
367 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk)
371 coords[0] = tb->x + tk->pos_x;
373 coords[2] = MAX(tk->width, 1);
376 xprop_set_array(sc, tk->win, _NET_WM_ICON_GEOMETRY, coords, 4);