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;
21 /* you can edit these */
22 #define MAX_TASK_WIDTH 500
24 #define ICON_SIZE ((tb->h)-(2*PADDING))
26 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk);
28 #define SURF(x) with->surface.x
29 #define TEXT(x) with->texture[0].data.text.x
30 #define USE(x) (with = x)
31 #define SETTEXT(x, y, z) with->texture[0].type = RR_TEXTURE_TEXT; \
32 with->texture[0].data.text.font = x; \
33 with->texture[0].data.text.justify = y; \
34 with->texture[0].data.text.ellipsize = z;
35 #define SETSHADOW(y, z, u, v) with->texture[0].data.text.shadow_offset_x = y; \
36 with->texture[0].data.text.shadow_offset_y = z; \
37 with->texture[0].data.text.shadow_alpha = u; \
38 with->texture[0].data.text.shadow_color = v;
40 void gui_init(screen *sc)
44 gcv.graphics_exposures = False;
45 sc->fore_gc = XCreateGC(sc->dd, sc->root, GCGraphicsExposures, &gcv);
50 void gui_load_theme(screen *sc)
55 static int loaded = 0;
57 printf("loading theme\n");
59 if (loaded) return; /* only run this once for now */
62 name = xprop_get_utf8(sc, sc->root, _OB_THEME);
63 RrThemeFree(sc->theme);
64 sc->theme = RrThemeNew(sc->rr, name, TRUE, NULL, NULL, NULL, NULL, NULL);
66 /* We don't allow different fonts for various window states... */
67 font = RrFontOpen(sc->rr, "Candara, sans", 10,
68 RR_FONTWEIGHT_NORMAL, RR_FONTSLANT_NORMAL);
70 /* this appearance will be used to draw icons */
71 a_icon = RrAppearanceNew(sc->rr, 1);
73 SURF(grad) = RR_SURFACE_PARENTREL;
74 SURF(parentx) = PADDING;
75 SURF(parenty) = PADDING;
76 a_icon->texture[0].type = RR_TEXTURE_RGBA;
78 /* this is the appearance for the background of the panel */
79 background = RrAppearanceNew(sc->rr, 0);
81 SURF(grad) = RR_SURFACE_DIAGONAL;
82 SURF(primary) = RrColorNew(sc->rr, 170, 170, 190);
83 SURF(secondary) = RrColorNew(sc->rr, 100, 100, 160);
85 /* this is the appearance for unfocused tasks,
86 * text needs to be separate appearances so we can align it correctly */
87 unfocused_task = RrAppearanceNew(sc->rr, 0);
89 SURF(parent) = background;
90 SURF(grad) = RR_SURFACE_PARENTREL;
91 SURF(relief) = RR_RELIEF_RAISED;
92 SURF(bevel) = RR_BEVEL_2;
94 /* ... for iconified tasks, also used for shaded ones currently */
95 iconified_task = RrAppearanceCopy(unfocused_task);
97 SURF(relief) = RR_RELIEF_FLAT;
98 SURF(parent) = background; /* RrAppearanceCopy doesn't copy .parent */
100 /* ... for focused tasks */
101 focused_task = RrAppearanceNew(sc->rr, 0);
103 SURF(grad) = RR_SURFACE_CROSS_DIAGONAL;
104 SURF(secondary) = RrColorNew(sc->rr, 70, 80, 110);
105 SURF(primary) = RrColorNew(sc->rr, 130, 160, 250);
106 SURF(relief) = RR_RELIEF_SUNKEN;
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 = RrAppearanceNew(sc->rr, 1);
114 SURF(grad) = RR_SURFACE_PARENTREL;
115 SETTEXT(font, RR_JUSTIFY_LEFT, RR_ELLIPSIZE_END);
117 /* ... for iconified tasks */
118 iconified_text = RrAppearanceCopy(normal_text);
119 /* ... and for focused tasks, we copy this here (ie not 5 lines down)
120 * so the color isn't copied i actually don't know if that would
121 * hurt so XXX on that */
122 focused_text = RrAppearanceCopy(normal_text);
124 TEXT(color) = RrColorNew(sc->rr, 230, 230, 255);
127 TEXT(color) = RrColorNew(sc->rr, 20, 20, 40);
130 SETSHADOW(2, 2, 100, RrColorNew(sc->rr, 0, 0, 0));
131 TEXT(color) = RrColorNew(sc->rr, 200, 200, 200);
133 shaded_text = RrAppearanceCopy(normal_text);
135 TEXT(color) = RrColorNew(sc->rr, 50, 60, 90);
140 void gui_create_taskbar(screen *sc, taskbar *tb)
142 XSizeHints size_hints;
143 XSetWindowAttributes att;
146 att.event_mask = ButtonPressMask;
148 /* XXX make the height conigurable */
150 tb->y = sc->height - 24;
154 tb->win = XCreateWindow(/* display */ sc->dd,
155 /* parent */ sc->root,
161 /* depth */ CopyFromParent,
162 /* class */ InputOutput,
163 /* visual */ CopyFromParent,
164 /*value mask*/ CWEventMask,
168 /* reside on ALL desktops */
169 xprop_set_num(sc, tb->win, _NET_WM_DESKTOP, 0xFFFFFFFF);
170 xprop_set_atom(sc, tb->win, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DOCK);
171 xprop_set_atom(sc, tb->win, _NET_WM_STATE, _NET_WM_STATE_BELOW);
172 xprop_set_string(sc, tb->win, WM_NAME, "rspanel");
174 /* make sure the WM obays our window position */
175 size_hints.flags = PPosition;
176 size_hints.x = tb->x;
177 size_hints.y = tb->y;
178 /*XSetWMNormalHints (sc->dd, tb->win, &size_hints); */
179 XChangeProperty(sc->dd, tb->win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32,
180 PropModeReplace, (unsigned char *)&size_hints,
181 sizeof(XSizeHints) / 4);
183 xclhints.res_name = "rspanel";
184 xclhints.res_class = "RSPanel";
185 XSetClassHint(sc->dd, tb->win, &xclhints);
187 XMapWindow(sc->dd, tb->win);
190 void gui_draw_task(screen *sc, taskbar *tb, task *tk, int redraw)
199 else if (tk->focused)
210 else if (tk->focused)
215 i = icon_get_best(tk->icons, tk->nicons, ICON_SIZE, ICON_SIZE);
218 RrTextureRGBA *d = &a_icon->texture[0].data.rgba;
219 a_icon->surface.parent = b;
221 d->height = i->height;
222 d->alpha = tk->iconified ? 0x80 : tk->shaded ? 0xB0 : 0xff;
224 icon_size = ICON_SIZE + PADDING;
227 a->surface.parent = b;
228 a->surface.parentx = icon_size + PADDING;
229 a->texture[0].data.text.string = tk->name;
230 b->surface.parentx = tk->pos_x;
232 RrPaintPixmap(b, tk->width, tb->h);
233 RrPaintPixmap(a, tk->width-(2*PADDING+icon_size), tb->h);
236 RrPaintPixmap(a_icon, ICON_SIZE, ICON_SIZE);
237 XCopyArea(sc->dd, a_icon->pixmap, b->pixmap, sc->fore_gc, 0, 0,
238 ICON_SIZE, ICON_SIZE, PADDING, PADDING);
241 XCopyArea(sc->dd, a->pixmap, b->pixmap, sc->fore_gc, 0, 0,
242 tk->width-(2*PADDING+icon_size), tb->h, icon_size + PADDING, 0);
243 XCopyArea(sc->dd, b->pixmap, tb->bg, sc->fore_gc, 0, 0,
244 tk->width, tb->h, tk->pos_x, 0);
246 XFreePixmap(sc->dd, a->pixmap);
247 XFreePixmap(sc->dd, b->pixmap);
248 XFreePixmap(sc->dd, a_icon->pixmap);
250 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
251 XClearWindow(sc->dd, tb->win);
255 void gui_draw_taskbar(screen *sc, taskbar *tb)
264 pager_size = TEXTPAD;
268 width = tb->w - (pager_size + GRILL_WIDTH);
269 #warning only rerender if width changed!
270 if (tb->bg) XFreePixmap(sc->dd, tb->bg);
271 tb->bg = XCreatePixmap(sc->dd, sc->root, tb->w, tb->h, RrDepth(sc->rr));
273 XFreePixmap(sc->dd, RrPaintPixmap(background, tb->w, tb->h));
274 XCopyArea(sc->dd, background->pixmap, tb->bg, sc->fore_gc, 0, 0,
277 /* find the number of visible tasks */
278 for (tk = tb->task_list; tk; tk = tk->next) {
287 taskw = width / num_tasks;
288 if (taskw > MAX_TASK_WIDTH)
289 taskw = MAX_TASK_WIDTH;
291 for (tk = tb->task_list; tk; tk = tk->next) {
295 tk->width = taskw - 1;
296 gui_draw_task(sc, tb, tk, FALSE);
297 set_icon_geometry(sc, tb, tk);
302 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
303 XClearWindow(sc->dd, tb->win);
306 void gui_move_taskbar(screen *sc, taskbar *tb)
311 tb->x = TEXTPAD - tb->w;
314 tb->y = sc->height - tb->h;
316 XMoveWindow(sc->dd, tb->win, tb->x, tb->y);
319 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk)
323 coords[0] = tb->x + tk->pos_x;
325 coords[2] = MAX(tk->width, 1);
328 xprop_set_array(sc, tk->win, _NET_WM_ICON_GEOMETRY, coords, 4);