]> icculus.org git repositories - mikachu/openbox.git/blob - openbox/framerender.c
let you send windows with the desktop and directionaldesktop actions
[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     if (frame_iconify_animating(self))
38         return; /* delay redrawing until the animation is done */
39     if (!self->need_render)
40         return;
41     if (!self->visible)
42         return;
43     self->need_render = FALSE;
44
45     {
46         gulong px;
47
48         px = (self->focused ?
49               RrColorPixel(ob_rr_theme->cb_focused_color) :
50               RrColorPixel(ob_rr_theme->cb_unfocused_color));
51
52         XSetWindowBackground(ob_display, self->backback, px);
53         XClearWindow(ob_display, self->backback);
54         XSetWindowBackground(ob_display, self->innerleft, px);
55         XClearWindow(ob_display, self->innerleft);
56         XSetWindowBackground(ob_display, self->innertop, px);
57         XClearWindow(ob_display, self->innertop);
58         XSetWindowBackground(ob_display, self->innerright, px);
59         XClearWindow(ob_display, self->innerright);
60         XSetWindowBackground(ob_display, self->innerbottom, px);
61         XClearWindow(ob_display, self->innerbottom);
62
63         px = (self->focused ?
64               RrColorPixel(ob_rr_theme->frame_focused_border_color) :
65               RrColorPixel(ob_rr_theme->frame_unfocused_border_color));
66
67         XSetWindowBackground(ob_display, self->left, px);
68         XClearWindow(ob_display, self->left);
69         XSetWindowBackground(ob_display, self->right, px);
70         XClearWindow(ob_display, self->right);
71
72         XSetWindowBackground(ob_display, self->titleleft, px);
73         XClearWindow(ob_display, self->titleleft);
74         XSetWindowBackground(ob_display, self->titletop, px);
75         XClearWindow(ob_display, self->titletop);
76         XSetWindowBackground(ob_display, self->titletopleft, px);
77         XClearWindow(ob_display, self->titletopleft);
78         XSetWindowBackground(ob_display, self->titletopright, px);
79         XClearWindow(ob_display, self->titletopright);
80         XSetWindowBackground(ob_display, self->titleright, px);
81         XClearWindow(ob_display, self->titleright);
82
83         XSetWindowBackground(ob_display, self->handleleft, px);
84         XClearWindow(ob_display, self->handleleft);
85         XSetWindowBackground(ob_display, self->handletop, px);
86         XClearWindow(ob_display, self->handletop);
87         XSetWindowBackground(ob_display, self->handleright, px);
88         XClearWindow(ob_display, self->handleright);
89         XSetWindowBackground(ob_display, self->handlebottom, px);
90         XClearWindow(ob_display, self->handlebottom);
91
92         XSetWindowBackground(ob_display, self->lgripleft, px);
93         XClearWindow(ob_display, self->lgripleft);
94         XSetWindowBackground(ob_display, self->lgriptop, px);
95         XClearWindow(ob_display, self->lgriptop);
96         XSetWindowBackground(ob_display, self->lgripbottom, px);
97         XClearWindow(ob_display, self->lgripbottom);
98
99         XSetWindowBackground(ob_display, self->rgripright, px);
100         XClearWindow(ob_display, self->rgripright);
101         XSetWindowBackground(ob_display, self->rgriptop, px);
102         XClearWindow(ob_display, self->rgriptop);
103         XSetWindowBackground(ob_display, self->rgripbottom, px);
104         XClearWindow(ob_display, self->rgripbottom);
105
106         /* don't use the separator color for shaded windows */
107         if (!self->client->shaded)
108             px = (self->focused ?
109                   RrColorPixel(ob_rr_theme->title_separator_focused_color) :
110                   RrColorPixel(ob_rr_theme->title_separator_unfocused_color));
111
112         XSetWindowBackground(ob_display, self->titlebottom, px);
113         XClearWindow(ob_display, self->titlebottom);
114     }
115
116     if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
117         RrAppearance *t, *l, *m, *n, *i, *d, *s, *c, *clear;
118         if (self->focused) {
119
120             t = self->a_focused_title;
121             l = self->a_focused_label;
122
123             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
124                  ob_rr_theme->a_disabled_focused_max :
125                  (self->client->max_vert || self->client->max_horz ?
126                   (self->max_press ?
127                    ob_rr_theme->a_toggled_focused_pressed_max :
128                    (self->max_hover ?
129                     ob_rr_theme->a_toggled_hover_focused_max : 
130                     ob_rr_theme->a_toggled_focused_unpressed_max)) :
131                   (self->max_press ?
132                    ob_rr_theme->a_focused_pressed_max :
133                    (self->max_hover ?
134                     ob_rr_theme->a_hover_focused_max : 
135                     ob_rr_theme->a_focused_unpressed_max))));
136             n = self->a_icon;
137             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
138                  ob_rr_theme->a_disabled_focused_iconify :
139                  (self->iconify_press ?
140                   ob_rr_theme->a_focused_pressed_iconify :
141                   (self->iconify_hover ?
142                    ob_rr_theme->a_hover_focused_iconify : 
143                    ob_rr_theme->a_focused_unpressed_iconify)));
144             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
145                  ob_rr_theme->a_disabled_focused_desk :
146                  (self->client->desktop == DESKTOP_ALL ?
147                   (self->desk_press ?
148                    ob_rr_theme->a_toggled_focused_pressed_desk :
149                    (self->desk_hover ?
150                     ob_rr_theme->a_toggled_hover_focused_desk : 
151                     ob_rr_theme->a_toggled_focused_unpressed_desk)) :
152                   (self->desk_press ?
153                    ob_rr_theme->a_focused_pressed_desk :
154                    (self->desk_hover ?
155                     ob_rr_theme->a_hover_focused_desk : 
156                     ob_rr_theme->a_focused_unpressed_desk))));
157             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
158                  ob_rr_theme->a_disabled_focused_shade :
159                  (self->client->shaded ?
160                   (self->shade_press ?
161                    ob_rr_theme->a_toggled_focused_pressed_shade :
162                    (self->shade_hover ?
163                     ob_rr_theme->a_toggled_hover_focused_shade : 
164                     ob_rr_theme->a_toggled_focused_unpressed_shade)) :
165                   (self->shade_press ?
166                    ob_rr_theme->a_focused_pressed_shade :
167                    (self->shade_hover ?
168                     ob_rr_theme->a_hover_focused_shade : 
169                     ob_rr_theme->a_focused_unpressed_shade))));
170             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
171                  ob_rr_theme->a_disabled_focused_close :
172                  (self->close_press ?
173                   ob_rr_theme->a_focused_pressed_close :
174                   (self->close_hover ?
175                    ob_rr_theme->a_hover_focused_close : 
176                    ob_rr_theme->a_focused_unpressed_close)));
177         } else {
178             t = self->a_unfocused_title;
179             l = self->a_unfocused_label;
180             m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
181                  ob_rr_theme->a_disabled_unfocused_max :
182                  (self->client->max_vert || self->client->max_horz ?
183                   (self->max_press ?
184                    ob_rr_theme->a_toggled_unfocused_pressed_max :
185                    (self->max_hover ?
186                     ob_rr_theme->a_toggled_hover_unfocused_max : 
187                     ob_rr_theme->a_toggled_unfocused_unpressed_max)) :
188                   (self->max_press ?
189                    ob_rr_theme->a_unfocused_pressed_max :
190                    (self->max_hover ?
191                     ob_rr_theme->a_hover_unfocused_max : 
192                     ob_rr_theme->a_unfocused_unpressed_max))));
193             n = self->a_icon;
194             i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
195                  ob_rr_theme->a_disabled_unfocused_iconify :
196                  (self->iconify_press ?
197                   ob_rr_theme->a_unfocused_pressed_iconify :
198                   (self->iconify_hover ?
199                    ob_rr_theme->a_hover_unfocused_iconify : 
200                    ob_rr_theme->a_unfocused_unpressed_iconify)));
201             d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
202                  ob_rr_theme->a_disabled_unfocused_desk :
203                  (self->client->desktop == DESKTOP_ALL ?
204                   (self->desk_press ?
205                    ob_rr_theme->a_toggled_unfocused_pressed_desk :
206                    (self->desk_hover ?
207                     ob_rr_theme->a_toggled_hover_unfocused_desk : 
208                     ob_rr_theme->a_toggled_unfocused_unpressed_desk)) :
209                   (self->desk_press ?
210                    ob_rr_theme->a_unfocused_pressed_desk :
211                    (self->desk_hover ?
212                     ob_rr_theme->a_hover_unfocused_desk : 
213                     ob_rr_theme->a_unfocused_unpressed_desk))));
214             s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
215                  ob_rr_theme->a_disabled_unfocused_shade :
216                  (self->client->shaded ?
217                   (self->shade_press ?
218                    ob_rr_theme->a_toggled_unfocused_pressed_shade :
219                    (self->shade_hover ?
220                     ob_rr_theme->a_toggled_hover_unfocused_shade : 
221                     ob_rr_theme->a_toggled_unfocused_unpressed_shade)) :
222                   (self->shade_press ?
223                    ob_rr_theme->a_unfocused_pressed_shade :
224                    (self->shade_hover ?
225                     ob_rr_theme->a_hover_unfocused_shade : 
226                     ob_rr_theme->a_unfocused_unpressed_shade))));
227             c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
228                  ob_rr_theme->a_disabled_unfocused_close :
229                  (self->close_press ?
230                   ob_rr_theme->a_unfocused_pressed_close :
231                   (self->close_hover ?
232                    ob_rr_theme->a_hover_unfocused_close : 
233                    ob_rr_theme->a_unfocused_unpressed_close)));
234         }
235         clear = ob_rr_theme->a_clear;
236
237         RrPaint(t, self->title, self->width, ob_rr_theme->title_height);
238
239         clear->surface.parent = t;
240         clear->surface.parenty = 0;
241
242         clear->surface.parentx = ob_rr_theme->grip_width;
243
244         RrPaint(clear, self->topresize,
245                 self->width - ob_rr_theme->grip_width * 2,
246                 ob_rr_theme->paddingy + 1);
247
248         clear->surface.parentx = 0;
249
250         if (ob_rr_theme->grip_width > 0)
251             RrPaint(clear, self->tltresize,
252                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
253         if (ob_rr_theme->title_height > 0)
254             RrPaint(clear, self->tllresize,
255                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
256
257         clear->surface.parentx = self->width - ob_rr_theme->grip_width;
258
259         if (ob_rr_theme->grip_width > 0)
260             RrPaint(clear, self->trtresize,
261                     ob_rr_theme->grip_width, ob_rr_theme->paddingy + 1);
262
263         clear->surface.parentx = self->width - (ob_rr_theme->paddingx + 1);
264
265         if (ob_rr_theme->title_height > 0)
266             RrPaint(clear, self->trrresize,
267                     ob_rr_theme->paddingx + 1, ob_rr_theme->title_height);
268
269         /* set parents for any parent relative guys */
270         l->surface.parent = t;
271         l->surface.parentx = self->label_x;
272         l->surface.parenty = ob_rr_theme->paddingy;
273
274         m->surface.parent = t;
275         m->surface.parentx = self->max_x;
276         m->surface.parenty = ob_rr_theme->paddingy + 1;
277
278         n->surface.parent = t;
279         n->surface.parentx = self->icon_x;
280         n->surface.parenty = ob_rr_theme->paddingy;
281
282         i->surface.parent = t;
283         i->surface.parentx = self->iconify_x;
284         i->surface.parenty = ob_rr_theme->paddingy + 1;
285
286         d->surface.parent = t;
287         d->surface.parentx = self->desk_x;
288         d->surface.parenty = ob_rr_theme->paddingy + 1;
289
290         s->surface.parent = t;
291         s->surface.parentx = self->shade_x;
292         s->surface.parenty = ob_rr_theme->paddingy + 1;
293
294         c->surface.parent = t;
295         c->surface.parentx = self->close_x;
296         c->surface.parenty = ob_rr_theme->paddingy + 1;
297
298         framerender_label(self, l);
299         framerender_max(self, m);
300         framerender_icon(self, n);
301         framerender_iconify(self, i);
302         framerender_desk(self, d);
303         framerender_shade(self, s);
304         framerender_close(self, c);
305     }
306
307     if (self->decorations & OB_FRAME_DECOR_HANDLE &&
308         ob_rr_theme->handle_height > 0)
309     {
310         RrAppearance *h, *g;
311
312         h = (self->focused ?
313              self->a_focused_handle : self->a_unfocused_handle);
314
315         RrPaint(h, self->handle, self->width, ob_rr_theme->handle_height);
316
317         if (self->decorations & OB_FRAME_DECOR_GRIPS) {
318             g = (self->focused ?
319                  ob_rr_theme->a_focused_grip : ob_rr_theme->a_unfocused_grip);
320
321             if (g->surface.grad == RR_SURFACE_PARENTREL)
322                 g->surface.parent = h;
323
324             g->surface.parentx = 0;
325             g->surface.parenty = 0;
326
327             RrPaint(g, self->lgrip,
328                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
329
330             g->surface.parentx = self->width - ob_rr_theme->grip_width;
331             g->surface.parenty = 0;
332
333             RrPaint(g, self->rgrip,
334                     ob_rr_theme->grip_width, ob_rr_theme->handle_height);
335         }
336     }
337
338     XFlush(ob_display);
339 }
340
341 static void framerender_label(ObFrame *self, RrAppearance *a)
342 {
343     if (!self->label_on) return;
344     /* set the texture's text! */
345     a->texture[0].data.text.string = self->client->title;
346     RrPaint(a, self->label, self->label_width, ob_rr_theme->label_height);
347 }
348
349 static void framerender_icon(ObFrame *self, RrAppearance *a)
350 {
351     const ObClientIcon *icon;
352
353     if (!self->icon_on) return;
354
355     icon = client_icon(self->client,
356                        ob_rr_theme->button_size + 2,
357                        ob_rr_theme->button_size + 2);
358     if (icon) {
359         a->texture[0].type = RR_TEXTURE_RGBA;
360         a->texture[0].data.rgba.width = icon->width;
361         a->texture[0].data.rgba.height = icon->height;
362         a->texture[0].data.rgba.alpha = 0xff;
363         a->texture[0].data.rgba.data = icon->data;
364     } else
365         a->texture[0].type = RR_TEXTURE_NONE;
366
367     RrPaint(a, self->icon,
368             ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
369 }
370
371 static void framerender_max(ObFrame *self, RrAppearance *a)
372 {
373     if (!self->max_on) return;
374     RrPaint(a, self->max, ob_rr_theme->button_size, ob_rr_theme->button_size);
375 }
376
377 static void framerender_iconify(ObFrame *self, RrAppearance *a)
378 {
379     if (!self->iconify_on) return;
380     RrPaint(a, self->iconify,
381             ob_rr_theme->button_size, ob_rr_theme->button_size);
382 }
383
384 static void framerender_desk(ObFrame *self, RrAppearance *a)
385 {
386     if (!self->desk_on) return;
387     RrPaint(a, self->desk, ob_rr_theme->button_size, ob_rr_theme->button_size);
388 }
389
390 static void framerender_shade(ObFrame *self, RrAppearance *a)
391 {
392     if (!self->shade_on) return;
393     RrPaint(a, self->shade,
394             ob_rr_theme->button_size, ob_rr_theme->button_size);
395 }
396
397 static void framerender_close(ObFrame *self, RrAppearance *a)
398 {
399     if (!self->close_on) return;
400     RrPaint(a, self->close,
401             ob_rr_theme->button_size, ob_rr_theme->button_size);
402 }