]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/framerender.c
construct the titlebar without borders
[mikachu/openbox.git] / openbox / framerender.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    framerender.c for the Openbox window manager
4    Copyright (c) 2006        Mikael Magnusson
5    Copyright (c) 2003-2007   Dana Jansens
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "frame.h"
21 #include "openbox.h"
22 #include "screen.h"
23 #include "client.h"
24 #include "framerender.h"
25 #include "render/theme.h"
26
27 static void framerender_label(ObFrame *self, RrAppearance *a);
28 static void framerender_icon(ObFrame *self, RrAppearance *a);
29 static void framerender_max(ObFrame *self, RrAppearance *a);
30 static void framerender_iconify(ObFrame *self, RrAppearance *a);
31 static void framerender_desk(ObFrame *self, RrAppearance *a);
32 static void framerender_shade(ObFrame *self, RrAppearance *a);
33 static void framerender_close(ObFrame *self, RrAppearance *a);
34
35 void framerender_frame(ObFrame *self)
36 {
37     {
38         gulong px;
39
40         px = (self->focused ?
41               RrColorPixel(ob_rr_theme->cb_focused_color) :
42               RrColorPixel(ob_rr_theme->cb_unfocused_color));
43         XSetWindowBackground(ob_display, self->inner, px);
44         XClearWindow(ob_display, self->inner);
45
46         px = (self->focused ?
47               RrColorPixel(ob_rr_theme->frame_focused_border_color) :
48               RrColorPixel(ob_rr_theme->frame_unfocused_border_color));
49         XSetWindowBorder(ob_display, self->handle, px);
50         XSetWindowBorder(ob_display, self->rgrip, px);
51         XSetWindowBorder(ob_display, self->lgrip, px);
52
53         XSetWindowBackground(ob_display, self->leftresize, px);
54         XClearWindow(ob_display, self->leftresize);
55         XSetWindowBackground(ob_display, self->rightresize, px);
56         XClearWindow(ob_display, self->rightresize);
57
58         XSetWindowBackground(ob_display, self->titleleft, px);
59         XClearWindow(ob_display, self->titleleft);
60         XSetWindowBackground(ob_display, self->titletop, px);
61         XClearWindow(ob_display, self->titletop);
62         XSetWindowBackground(ob_display, self->titletopleft, px);
63         XClearWindow(ob_display, self->titletopleft);
64         XSetWindowBackground(ob_display, self->titletopright, px);
65         XClearWindow(ob_display, self->titletopright);
66         XSetWindowBackground(ob_display, self->titleright, px);
67         XClearWindow(ob_display, self->titleright);
68         XSetWindowBackground(ob_display, self->titlebottom, px);
69         XClearWindow(ob_display, self->titlebottom);
70     }
71
72     if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
73         RrAppearance *t, *l, *m, *n, *i, *d, *s, *c;
74         if (self->focused) {
75
76             t = self->a_focused_title;
77             l = self->a_focused_label;
78
79             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
80                  ob_rr_theme->a_disabled_focused_max :
81                  (self->client->max_vert || self->client->max_horz ?
82                   (self->max_press ?
83                    ob_rr_theme->a_toggled_focused_pressed_max :
84                    (self->max_hover ?
85                     ob_rr_theme->a_toggled_hover_focused_max : 
86                     ob_rr_theme->a_toggled_focused_unpressed_max)) :
87                   (self->max_press ?
88                    ob_rr_theme->a_focused_pressed_max :
89                    (self->max_hover ?
90                     ob_rr_theme->a_hover_focused_max : 
91                     ob_rr_theme->a_focused_unpressed_max))));
92             n = self->a_icon;
93             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
94                  ob_rr_theme->a_disabled_focused_iconify :
95                  (self->iconify_press ?
96                   ob_rr_theme->a_focused_pressed_iconify :
97                   (self->iconify_hover ?
98                    ob_rr_theme->a_hover_focused_iconify : 
99                    ob_rr_theme->a_focused_unpressed_iconify)));
100             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
101                  ob_rr_theme->a_disabled_focused_desk :
102                  (self->client->desktop == DESKTOP_ALL ?
103                   (self->desk_press ?
104                    ob_rr_theme->a_toggled_focused_pressed_desk :
105                    (self->desk_hover ?
106                     ob_rr_theme->a_toggled_hover_focused_desk : 
107                     ob_rr_theme->a_toggled_focused_unpressed_desk)) :
108                   (self->desk_press ?
109                    ob_rr_theme->a_focused_pressed_desk :
110                    (self->desk_hover ?
111                     ob_rr_theme->a_hover_focused_desk : 
112                     ob_rr_theme->a_focused_unpressed_desk))));
113             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
114                  ob_rr_theme->a_disabled_focused_shade :
115                  (self->client->shaded ?
116                   (self->shade_press ?
117                    ob_rr_theme->a_toggled_focused_pressed_shade :
118                    (self->shade_hover ?
119                     ob_rr_theme->a_toggled_hover_focused_shade : 
120                     ob_rr_theme->a_toggled_focused_unpressed_shade)) :
121                   (self->shade_press ?
122                    ob_rr_theme->a_focused_pressed_shade :
123                    (self->shade_hover ?
124                     ob_rr_theme->a_hover_focused_shade : 
125                     ob_rr_theme->a_focused_unpressed_shade))));
126             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
127                  ob_rr_theme->a_disabled_focused_close :
128                  (self->close_press ?
129                   ob_rr_theme->a_focused_pressed_close :
130                   (self->close_hover ?
131                    ob_rr_theme->a_hover_focused_close : 
132                    ob_rr_theme->a_focused_unpressed_close)));
133         } else {
134             t = self->a_unfocused_title;
135             l = self->a_unfocused_label;
136             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
137                  ob_rr_theme->a_disabled_unfocused_max :
138                  (self->client->max_vert || self->client->max_horz ?
139                   (self->max_press ?
140                    ob_rr_theme->a_toggled_unfocused_pressed_max :
141                    (self->max_hover ?
142                     ob_rr_theme->a_toggled_hover_unfocused_max : 
143                     ob_rr_theme->a_toggled_unfocused_unpressed_max)) :
144                   (self->max_press ?
145                    ob_rr_theme->a_unfocused_pressed_max :
146                    (self->max_hover ?
147                     ob_rr_theme->a_hover_unfocused_max : 
148                     ob_rr_theme->a_unfocused_unpressed_max))));
149             n = self->a_icon;
150             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
151                  ob_rr_theme->a_disabled_unfocused_iconify :
152                  (self->iconify_press ?
153                   ob_rr_theme->a_unfocused_pressed_iconify :
154                   (self->iconify_hover ?
155                    ob_rr_theme->a_hover_unfocused_iconify : 
156                    ob_rr_theme->a_unfocused_unpressed_iconify)));
157             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
158                  ob_rr_theme->a_disabled_unfocused_desk :
159                  (self->client->desktop == DESKTOP_ALL ?
160                   (self->desk_press ?
161                    ob_rr_theme->a_toggled_unfocused_pressed_desk :
162                    (self->desk_hover ?
163                     ob_rr_theme->a_toggled_hover_unfocused_desk : 
164                     ob_rr_theme->a_toggled_unfocused_unpressed_desk)) :
165                   (self->desk_press ?
166                    ob_rr_theme->a_unfocused_pressed_desk :
167                    (self->desk_hover ?
168                     ob_rr_theme->a_hover_unfocused_desk : 
169                     ob_rr_theme->a_unfocused_unpressed_desk))));
170             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
171                  ob_rr_theme->a_disabled_unfocused_shade :
172                  (self->client->shaded ?
173                   (self->shade_press ?
174                    ob_rr_theme->a_toggled_unfocused_pressed_shade :
175                    (self->shade_hover ?
176                     ob_rr_theme->a_toggled_hover_unfocused_shade : 
177                     ob_rr_theme->a_toggled_unfocused_unpressed_shade)) :
178                   (self->shade_press ?
179                    ob_rr_theme->a_unfocused_pressed_shade :
180                    (self->shade_hover ?
181                     ob_rr_theme->a_hover_unfocused_shade : 
182                     ob_rr_theme->a_unfocused_unpressed_shade))));
183             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
184                  ob_rr_theme->a_disabled_unfocused_close :
185                  (self->close_press ?
186                   ob_rr_theme->a_unfocused_pressed_close :
187                   (self->close_hover ?
188                    ob_rr_theme->a_hover_unfocused_close : 
189                    ob_rr_theme->a_unfocused_unpressed_close)));
190         }
191
192         RrPaint(t, self->title, self->width, ob_rr_theme->title_height);
193
194         ob_rr_theme->a_clear->surface.parent = t;
195         ob_rr_theme->a_clear->surface.parenty = 0;
196
197         ob_rr_theme->a_clear->surface.parentx = ob_rr_theme->grip_width +
198             self->bwidth;
199         RrPaint(ob_rr_theme->a_clear, self->topresize,
200                 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
201                 ob_rr_theme->paddingy + 1);
202
203         ob_rr_theme->a_clear->surface.parentx = 0;
204
205         if (ob_rr_theme->grip_width > 0)
206             RrPaint(ob_rr_theme->a_clear, self->tltresize,
207                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
208         if (ob_rr_theme->title_height > 0)
209             RrPaint(ob_rr_theme->a_clear, self->tllresize,
210                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
211
212         ob_rr_theme->a_clear->surface.parentx =
213             self->width - ob_rr_theme->grip_width;
214
215         if (ob_rr_theme->grip_width > 0)
216             RrPaint(ob_rr_theme->a_clear, self->trtresize,
217                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
218
219         ob_rr_theme->a_clear->surface.parentx =
220             self->width - (ob_rr_theme->paddingx + 1);
221
222         if (ob_rr_theme->title_height > 0)
223             RrPaint(ob_rr_theme->a_clear, self->trrresize,
224                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
225
226         /* set parents for any parent relative guys */
227         l->surface.parent = t;
228         l->surface.parentx = self->label_x;
229         l->surface.parenty = ob_rr_theme->paddingy;
230
231         m->surface.parent = t;
232         m->surface.parentx = self->max_x;
233         m->surface.parenty = ob_rr_theme->paddingy + 1;
234
235         n->surface.parent = t;
236         n->surface.parentx = self->icon_x;
237         n->surface.parenty = ob_rr_theme->paddingy;
238
239         i->surface.parent = t;
240         i->surface.parentx = self->iconify_x;
241         i->surface.parenty = ob_rr_theme->paddingy + 1;
242
243         d->surface.parent = t;
244         d->surface.parentx = self->desk_x;
245         d->surface.parenty = ob_rr_theme->paddingy + 1;
246
247         s->surface.parent = t;
248         s->surface.parentx = self->shade_x;
249         s->surface.parenty = ob_rr_theme->paddingy + 1;
250
251         c->surface.parent = t;
252         c->surface.parentx = self->close_x;
253         c->surface.parenty = ob_rr_theme->paddingy + 1;
254
255         framerender_label(self, l);
256         framerender_max(self, m);
257         framerender_icon(self, n);
258         framerender_iconify(self, i);
259         framerender_desk(self, d);
260         framerender_shade(self, s);
261         framerender_close(self, c);
262     }
263
264     if (self->decorations & OB_FRAME_DECOR_HANDLE &&
265         ob_rr_theme->handle_height > 0)
266     {
267         RrAppearance *h, *g;
268
269         h = (self->focused ?
270              self->a_focused_handle : self->a_unfocused_handle);
271
272         RrPaint(h, self->handle, self->width, ob_rr_theme->handle_height);
273
274         if (self->decorations & OB_FRAME_DECOR_GRIPS) {
275             g = (self->focused ?
276                  ob_rr_theme->a_focused_grip : ob_rr_theme->a_unfocused_grip);
277
278             if (g->surface.grad == RR_SURFACE_PARENTREL)
279                 g->surface.parent = h;
280
281             g->surface.parentx = 0;
282             g->surface.parenty = 0;
283
284             RrPaint(g, self->lgrip,
285                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
286
287             g->surface.parentx = self->width - ob_rr_theme->grip_width;
288             g->surface.parenty = 0;
289
290             RrPaint(g, self->rgrip,
291                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
292         }
293     }
294
295     XFlush(ob_display);
296 }
297
298 static void framerender_label(ObFrame *self, RrAppearance *a)
299 {
300     if (!self->label_on) return;
301     /* set the texture's text! */
302     a->texture[0].data.text.string = self->client->title;
303     RrPaint(a, self->label, self->label_width, ob_rr_theme->label_height);
304 }
305
306 static void framerender_icon(ObFrame *self, RrAppearance *a)
307 {
308     const ObClientIcon *icon;
309
310     if (!self->icon_on) return;
311
312     icon = client_icon(self->client,
313                        ob_rr_theme->button_size + 2,
314                        ob_rr_theme->button_size + 2);
315     if (icon) {
316         a->texture[0].type = RR_TEXTURE_RGBA;
317         a->texture[0].data.rgba.width = icon->width;
318         a->texture[0].data.rgba.height = icon->height;
319         a->texture[0].data.rgba.data = icon->data;
320     } else
321         a->texture[0].type = RR_TEXTURE_NONE;
322
323     RrPaint(a, self->icon,
324             ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
325 }
326
327 static void framerender_max(ObFrame *self, RrAppearance *a)
328 {
329     if (!self->max_on) return;
330     RrPaint(a, self->max, ob_rr_theme->button_size, ob_rr_theme->button_size);
331 }
332
333 static void framerender_iconify(ObFrame *self, RrAppearance *a)
334 {
335     if (!self->iconify_on) return;
336     RrPaint(a, self->iconify,
337             ob_rr_theme->button_size, ob_rr_theme->button_size);
338 }
339
340 static void framerender_desk(ObFrame *self, RrAppearance *a)
341 {
342     if (!self->desk_on) return;
343     RrPaint(a, self->desk, ob_rr_theme->button_size, ob_rr_theme->button_size);
344 }
345
346 static void framerender_shade(ObFrame *self, RrAppearance *a)
347 {
348     if (!self->shade_on) return;
349     RrPaint(a, self->shade,
350             ob_rr_theme->button_size, ob_rr_theme->button_size);
351 }
352
353 static void framerender_close(ObFrame *self, RrAppearance *a)
354 {
355     if (!self->close_on) return;
356     RrPaint(a, self->close,
357             ob_rr_theme->button_size, ob_rr_theme->button_size);
358 }