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)
46 gcv.graphics_exposures = False;
47 sc->fore_gc = XCreateGC(sc->dd, sc->root, GCGraphicsExposures, &gcv);
49 /* We don't allow different fonts for various window states... */
50 font = RrFontOpen(sc->rr, "Candara, sans", 10, RR_FONTWEIGHT_NORMAL, RR_FONTSLANT_NORMAL);
52 /* this appearance will be used to draw icons */
53 a_icon = RrAppearanceNew(sc->rr, 1);
55 SURF(grad) = RR_SURFACE_PARENTREL;
56 SURF(parentx) = PADDING;
57 SURF(parenty) = PADDING;
58 a_icon->texture[0].type = RR_TEXTURE_RGBA;
60 /* this is the appearance for the background of the panel */
61 background = RrAppearanceNew(sc->rr, 0);
63 SURF(grad) = RR_SURFACE_DIAGONAL;
64 SURF(primary) = RrColorNew(sc->rr, 170, 170, 190);
65 SURF(secondary) = RrColorNew(sc->rr, 100, 100, 160);
67 /* this is the appearance for unfocused tasks,
68 * text needs to be separate appearances so we can align it correctly */
69 unfocused_task = RrAppearanceNew(sc->rr, 0);
71 SURF(parent) = background;
72 SURF(grad) = RR_SURFACE_PARENTREL;
74 SURF(border_color) = RrColorNew(sc->rr, 0, 0, 80);
76 /* ... for iconified tasks, also used for shaded ones currently */
77 iconified_task = RrAppearanceCopy(unfocused_task);
79 SURF(relief) = RR_RELIEF_SUNKEN;
81 SURF(parent) = background; /* RrAppearanceCopy doesn't copy .parent */
83 /* ... for focused tasks */
84 focused_task = RrAppearanceNew(sc->rr, 0);
86 SURF(grad) = RR_SURFACE_CROSS_DIAGONAL;
87 SURF(secondary) = RrColorNew(sc->rr, 70, 80, 110);
88 SURF(primary) = RrColorNew(sc->rr, 130, 160, 250);
89 SURF(relief) = RR_RELIEF_RAISED;
91 /* this is the text used for all normal unfocused tasks */
92 /* we don't set .parent here, but in draw_task, since we
93 * want to combine _task and _text semirandomly.
94 * XXX plz not when themes are here */
95 normal_text = RrAppearanceNew(sc->rr, 1);
97 SURF(grad) = RR_SURFACE_PARENTREL;
98 SETTEXT(font, RR_JUSTIFY_LEFT, RR_ELLIPSIZE_END);
100 /* ... for iconified tasks */
101 iconified_text = RrAppearanceCopy(normal_text);
102 /* ... and for focused tasks, we copy this here (ie not 5 lines down)
103 * so the color isn't copied i actually don't know if that would
104 * hurt so XXX on that */
105 focused_text = RrAppearanceCopy(normal_text);
107 TEXT(color) = RrColorNew(sc->rr, 230, 230, 255);
110 TEXT(color) = RrColorNew(sc->rr, 20, 20, 40);
113 SETSHADOW(2, 2, 100, RrColorNew(sc->rr, 0, 0, 0));
114 TEXT(color) = RrColorNew(sc->rr, 200, 200, 200);
116 shaded_text = RrAppearanceCopy(normal_text);
118 TEXT(color) = RrColorNew(sc->rr, 50, 60, 90);
121 void gui_create_taskbar(screen *sc, taskbar *tb)
123 XSizeHints size_hints;
124 XSetWindowAttributes att;
127 att.event_mask = ButtonPressMask;
129 /* XXX make the height conigurable */
131 tb->y = sc->height - 24;
135 tb->win = XCreateWindow(/* display */ sc->dd,
136 /* parent */ sc->root,
139 /* XXX Maybe just use scr_width here? */
143 /* depth */ CopyFromParent,
144 /* class */ InputOutput,
145 /* visual */ CopyFromParent,
146 /*value mask*/ CWEventMask,
150 /* reside on ALL desktops */
151 xprop_set_num(sc, tb->win, _NET_WM_DESKTOP, 0xFFFFFFFF);
152 xprop_set_atom(sc, tb->win, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DOCK);
153 xprop_set_atom(sc, tb->win, _NET_WM_STATE, _NET_WM_STATE_BELOW);
154 xprop_set_string(sc, tb->win, WM_NAME, "rspanel");
156 /* make sure the WM obays our window position */
157 size_hints.flags = PPosition;
158 /*XSetWMNormalHints (sc->dd, tb->win, &size_hints); */
159 XChangeProperty(sc->dd, tb->win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32,
160 PropModeReplace, (unsigned char *)&size_hints,
161 sizeof(XSizeHints) / 4);
163 xclhints.res_name = "rspanel";
164 xclhints.res_class = "RSPanel";
165 XSetClassHint(sc->dd, tb->win, &xclhints);
167 XMapWindow(sc->dd, tb->win);
170 void gui_draw_task(screen *sc, taskbar *tb, task *tk, int redraw)
178 else if (tk->focused)
189 else if (tk->focused)
194 i = icon_get_best(tk->icons, tk->nicons, ICON_SIZE, ICON_SIZE);
197 RrTextureRGBA *d = &a_icon->texture[0].data.rgba;
198 a_icon->surface.parent = b;
200 d->height = i->height;
201 d->alpha = tk->iconified ? 0x80 : tk->shaded ? 0xB0 : 0xff;
205 a->surface.parent = b;
206 a->surface.parentx = ICON_SIZE+2*PADDING;
207 a->texture[0].data.text.string = tk->name;
208 b->surface.parentx = tk->pos_x;
210 RrPaintPixmap(b, tk->width, tb->h);
211 RrPaintPixmap(a, tk->width-3*PADDING-ICON_SIZE, tb->h);
214 RrPaintPixmap(a_icon, ICON_SIZE, ICON_SIZE);
215 XCopyArea(sc->dd, a_icon->pixmap, b->pixmap, sc->fore_gc, 0, 0,
216 ICON_SIZE, ICON_SIZE, PADDING, PADDING);
219 XCopyArea(sc->dd, a->pixmap, b->pixmap, sc->fore_gc, 0, 0,
220 tk->width-3*PADDING-ICON_SIZE, tb->h, ICON_SIZE+2*PADDING, 0);
221 XCopyArea(sc->dd, b->pixmap, tb->bg, sc->fore_gc, 0, 0,
222 tk->width, tb->h, tk->pos_x, 0);
224 a_icon->texture[1].type = RR_TEXTURE_NONE;
225 XFreePixmap(sc->dd, a->pixmap);
226 XFreePixmap(sc->dd, b->pixmap);
227 XFreePixmap(sc->dd, a_icon->pixmap);
229 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
230 XClearWindow(sc->dd, tb->win);
234 void gui_draw_taskbar(screen *sc, taskbar *tb)
243 pager_size = TEXTPAD;
247 width = tb->w - (pager_size + GRILL_WIDTH);
248 #warning only rerender if width changed!
249 if (tb->bg) XFreePixmap(sc->dd, tb->bg);
250 tb->bg = XCreatePixmap(sc->dd, sc->root, tb->w, tb->h, RrDepth(sc->rr));
252 XFreePixmap(sc->dd, RrPaintPixmap(background, tb->w, tb->h));
253 XCopyArea(sc->dd, background->pixmap, tb->bg, sc->fore_gc, 0, 0, tb->w, tb->h, 0, 0);
255 /* find the number of visible tasks */
256 for (tk = tb->task_list; tk; tk = tk->next) {
265 taskw = width / num_tasks;
266 if (taskw > MAX_TASK_WIDTH)
267 taskw = MAX_TASK_WIDTH;
269 for (tk = tb->task_list; tk; tk = tk->next) {
273 tk->width = taskw - 1;
274 gui_draw_task(sc, tb, tk, FALSE);
275 set_icon_geometry(sc, tb, tk);
280 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
281 XClearWindow(sc->dd, tb->win);
284 void gui_move_taskbar(screen *sc, taskbar *tb)
289 tb->x = TEXTPAD - tb->w;
292 tb->y = sc->height - tb->h;
294 XMoveWindow(sc->dd, tb->win, tb->x, tb->y);
297 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk)
301 coords[0] = tb->x + tk->pos_x;
303 coords[2] = MAX(tk->width, 1);
306 xprop_set_array(sc, tk->win, _NET_WM_ICON_GEOMETRY, coords, 4);