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
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, we don't
53 * set the type of the texture to RGBA here, because we toggle
54 * that so obrender doesn't try to draw an icon when the app
56 /* XXX don't do that */
57 a_icon = RrAppearanceNew(sc->rr, 1);
59 SURF(grad) = RR_SURFACE_PARENTREL;
61 /* this is the appearance for the background of the panel */
62 background = RrAppearanceNew(sc->rr, 0);
64 SURF(grad) = RR_SURFACE_DIAGONAL;
65 SURF(primary) = RrColorNew(sc->rr, 170, 170, 190);
66 SURF(secondary) = RrColorNew(sc->rr, 100, 100, 160);
68 /* this is the appearance for unfocused tasks,
69 * text needs to be separate appearances so we can align it correctly */
70 unfocused_task = RrAppearanceNew(sc->rr, 0);
72 SURF(parent) = background;
73 SURF(grad) = RR_SURFACE_PARENTREL;
75 SURF(border_color) = RrColorNew(sc->rr, 0, 0, 80);
77 /* ... for iconified tasks, also used for shaded ones currently */
78 iconified_task = RrAppearanceCopy(unfocused_task);
80 SURF(relief) = RR_RELIEF_SUNKEN;
82 SURF(parent) = background; /* RrAppearanceCopy doesn't copy .parent */
84 /* ... for focused tasks */
85 focused_task = RrAppearanceNew(sc->rr, 0);
87 SURF(grad) = RR_SURFACE_CROSS_DIAGONAL;
88 SURF(secondary) = RrColorNew(sc->rr, 70, 80, 110);
89 SURF(primary) = RrColorNew(sc->rr, 130, 160, 250);
90 SURF(relief) = RR_RELIEF_RAISED;
92 /* this is the text used for all normal unfocused tasks */
93 /* we don't set .parent here, but in draw_task, since we
94 * want to combine _task and _text semirandomly.
95 * XXX plz not when themes are here */
96 normal_text = RrAppearanceNew(sc->rr, 1);
98 SURF(grad) = RR_SURFACE_PARENTREL;
99 SETTEXT(font, RR_JUSTIFY_LEFT, RR_ELLIPSIZE_END);
101 /* ... for iconified tasks */
102 iconified_text = RrAppearanceCopy(normal_text);
103 /* ... and for focused tasks, we copy this here (ie not 5 lines down)
104 * so the color isn't copied i actually don't know if that would
105 * hurt so XXX on that */
106 focused_text = RrAppearanceCopy(normal_text);
108 TEXT(color) = RrColorNew(sc->rr, 230, 230, 255);
111 TEXT(color) = RrColorNew(sc->rr, 20, 20, 40);
114 SETSHADOW(2, 2, 100, RrColorNew(sc->rr, 0, 0, 0));
115 TEXT(color) = RrColorNew(sc->rr, 200, 200, 200);
117 shaded_text = RrAppearanceCopy(normal_text);
119 TEXT(color) = RrColorNew(sc->rr, 50, 60, 90);
122 void gui_create_taskbar(screen *sc, taskbar *tb)
124 XSizeHints size_hints;
125 XSetWindowAttributes att;
128 att.event_mask = ButtonPressMask;
130 /* XXX make the height conigurable */
132 tb->y = sc->height - 24;
136 tb->win = XCreateWindow(/* display */ sc->dd,
137 /* parent */ sc->root,
140 /* XXX Maybe just use scr_width here? */
144 /* depth */ CopyFromParent,
145 /* class */ InputOutput,
146 /* visual */ CopyFromParent,
147 /*value mask*/ CWEventMask,
151 /* reside on ALL desktops */
152 xprop_set_num(sc, tb->win, _NET_WM_DESKTOP, 0xFFFFFFFF);
153 xprop_set_atom(sc, tb->win, _NET_WM_WINDOW_TYPE, _NET_WM_WINDOW_TYPE_DOCK);
154 xprop_set_atom(sc, tb->win, _NET_WM_STATE, _NET_WM_STATE_BELOW);
155 xprop_set_string(sc, tb->win, WM_NAME, "rspanel");
157 /* make sure the WM obays our window position */
158 size_hints.flags = PPosition;
159 /*XSetWMNormalHints (sc->dd, tb->win, &size_hints); */
160 XChangeProperty(sc->dd, tb->win, XA_WM_NORMAL_HINTS, XA_WM_SIZE_HINTS, 32,
161 PropModeReplace, (unsigned char *)&size_hints,
162 sizeof(XSizeHints) / 4);
164 xclhints.res_name = "rspanel";
165 xclhints.res_class = "RSPanel";
166 XSetClassHint(sc->dd, tb->win, &xclhints);
168 XMapWindow(sc->dd, tb->win);
172 #define ICON_SIZE ((tb->h)-(2*PADDING))
173 void gui_draw_task(screen *sc, taskbar *tb, task *tk, int redraw)
181 else if (tk->focused)
192 else if (tk->focused)
197 i = icon_get_best(tk->icons, tk->nicons, ICON_SIZE, ICON_SIZE);
200 RrTexture *c = &a_icon->texture[0];
201 RrTextureRGBA *d = &c->data.rgba;
202 c->type = RR_TEXTURE_RGBA;
203 a_icon->surface.parent = b;
204 a_icon->surface.parentx = PADDING;
205 a_icon->surface.parenty = PADDING;
207 d->height = i->height;
208 d->alpha = tk->iconified ? 0x80 : tk->shaded ? 0xB0 : 0xff;
212 a->surface.parent = b;
213 a->surface.parentx = ICON_SIZE+2*PADDING;
214 a->texture[0].data.text.string = tk->name;
215 b->surface.parentx = tk->pos_x;
217 RrPaintPixmap(b, tk->width, tb->h);
218 RrPaintPixmap(a, tk->width-3*PADDING-ICON_SIZE, tb->h);
221 RrPaintPixmap(a_icon, ICON_SIZE, ICON_SIZE);
222 XCopyArea(sc->dd, a_icon->pixmap, b->pixmap, sc->fore_gc, 0, 0,
223 ICON_SIZE, ICON_SIZE, PADDING, PADDING);
226 XCopyArea(sc->dd, a->pixmap, b->pixmap, sc->fore_gc, 0, 0,
227 tk->width-3*PADDING-ICON_SIZE, tb->h, ICON_SIZE+2*PADDING, 0);
228 XCopyArea(sc->dd, b->pixmap, tb->bg, sc->fore_gc, 0, 0,
229 tk->width, tb->h, tk->pos_x, 0);
231 a_icon->texture[1].type = RR_TEXTURE_NONE;
232 XFreePixmap(sc->dd, a->pixmap);
233 XFreePixmap(sc->dd, b->pixmap);
234 XFreePixmap(sc->dd, a_icon->pixmap);
236 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
237 XClearWindow(sc->dd, tb->win);
241 void gui_draw_taskbar(screen *sc, taskbar *tb)
250 pager_size = TEXTPAD;
254 width = tb->w - (pager_size + GRILL_WIDTH);
255 #warning only rerender if width changed!
256 if (tb->bg) XFreePixmap(sc->dd, tb->bg);
257 tb->bg = XCreatePixmap(sc->dd, sc->root, tb->w, tb->h, RrDepth(sc->rr));
259 XFreePixmap(sc->dd, RrPaintPixmap(background, tb->w, tb->h));
260 XCopyArea(sc->dd, background->pixmap, tb->bg, sc->fore_gc, 0, 0, tb->w, tb->h, 0, 0);
262 /* find the number of visible tasks */
263 for (tk = tb->task_list; tk; tk = tk->next) {
272 taskw = width / num_tasks;
273 if (taskw > MAX_TASK_WIDTH)
274 taskw = MAX_TASK_WIDTH;
276 for (tk = tb->task_list; tk; tk = tk->next) {
280 tk->width = taskw - 1;
281 gui_draw_task(sc, tb, tk, FALSE);
282 set_icon_geometry(sc, tb, tk);
287 XSetWindowBackgroundPixmap(sc->dd, tb->win, tb->bg);
288 XClearWindow(sc->dd, tb->win);
291 void gui_move_taskbar(screen *sc, taskbar *tb)
296 tb->x = TEXTPAD - tb->w;
299 tb->y = sc->height - tb->h;
301 XMoveWindow(sc->dd, tb->win, tb->x, tb->y);
304 static void set_icon_geometry(screen *sc, taskbar *tb, task *tk)
308 coords[0] = tb->x + tk->pos_x;
310 coords[2] = MAX(tk->width, 1);
313 xprop_set_array(sc, tk->win, _NET_WM_ICON_GEOMETRY, coords, 4);