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