1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 framerender.c for the Openbox window manager
4 Copyright (c) 2006 Mikael Magnusson
5 Copyright (c) 2003-2007 Dana Jansens
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.
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.
17 See the COPYING file for a copy of the GNU General Public License.
24 #include "framerender.h"
25 #include "render/theme.h"
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
);
35 void framerender_frame(ObFrame
*self
)
37 if (frame_iconify_animating(self
))
38 return; /* delay redrawing until the animation is done */
39 if (!self
->need_render
)
43 self
->need_render
= FALSE
;
49 RrColorPixel(ob_rr_theme
->cb_focused_color
) :
50 RrColorPixel(ob_rr_theme
->cb_unfocused_color
));
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
);
64 RrColorPixel(ob_rr_theme
->frame_focused_border_color
) :
65 RrColorPixel(ob_rr_theme
->frame_unfocused_border_color
));
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
);
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
);
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
);
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
);
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
);
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
));
112 XSetWindowBackground(ob_display
, self
->titlebottom
, px
);
113 XClearWindow(ob_display
, self
->titlebottom
);
116 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
117 RrAppearance
*t
, *l
, *m
, *n
, *i
, *d
, *s
, *c
, *clear
;
120 t
= self
->a_focused_title
;
121 l
= self
->a_focused_label
;
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
?
127 ob_rr_theme
->a_toggled_focused_pressed_max
:
129 ob_rr_theme
->a_toggled_hover_focused_max
:
130 ob_rr_theme
->a_toggled_focused_unpressed_max
)) :
132 ob_rr_theme
->a_focused_pressed_max
:
134 ob_rr_theme
->a_hover_focused_max
:
135 ob_rr_theme
->a_focused_unpressed_max
))));
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
?
148 ob_rr_theme
->a_toggled_focused_pressed_desk
:
150 ob_rr_theme
->a_toggled_hover_focused_desk
:
151 ob_rr_theme
->a_toggled_focused_unpressed_desk
)) :
153 ob_rr_theme
->a_focused_pressed_desk
:
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
?
161 ob_rr_theme
->a_toggled_focused_pressed_shade
:
163 ob_rr_theme
->a_toggled_hover_focused_shade
:
164 ob_rr_theme
->a_toggled_focused_unpressed_shade
)) :
166 ob_rr_theme
->a_focused_pressed_shade
:
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
:
173 ob_rr_theme
->a_focused_pressed_close
:
175 ob_rr_theme
->a_hover_focused_close
:
176 ob_rr_theme
->a_focused_unpressed_close
)));
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
?
184 ob_rr_theme
->a_toggled_unfocused_pressed_max
:
186 ob_rr_theme
->a_toggled_hover_unfocused_max
:
187 ob_rr_theme
->a_toggled_unfocused_unpressed_max
)) :
189 ob_rr_theme
->a_unfocused_pressed_max
:
191 ob_rr_theme
->a_hover_unfocused_max
:
192 ob_rr_theme
->a_unfocused_unpressed_max
))));
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
?
205 ob_rr_theme
->a_toggled_unfocused_pressed_desk
:
207 ob_rr_theme
->a_toggled_hover_unfocused_desk
:
208 ob_rr_theme
->a_toggled_unfocused_unpressed_desk
)) :
210 ob_rr_theme
->a_unfocused_pressed_desk
:
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
?
218 ob_rr_theme
->a_toggled_unfocused_pressed_shade
:
220 ob_rr_theme
->a_toggled_hover_unfocused_shade
:
221 ob_rr_theme
->a_toggled_unfocused_unpressed_shade
)) :
223 ob_rr_theme
->a_unfocused_pressed_shade
:
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
:
230 ob_rr_theme
->a_unfocused_pressed_close
:
232 ob_rr_theme
->a_hover_unfocused_close
:
233 ob_rr_theme
->a_unfocused_unpressed_close
)));
235 clear
= ob_rr_theme
->a_clear
;
237 RrPaint(t
, self
->title
, self
->width
, ob_rr_theme
->title_height
);
239 clear
->surface
.parent
= t
;
240 clear
->surface
.parenty
= 0;
242 clear
->surface
.parentx
= ob_rr_theme
->grip_width
;
244 RrPaint(clear
, self
->topresize
,
245 self
->width
- ob_rr_theme
->grip_width
* 2,
246 ob_rr_theme
->paddingy
+ 1);
248 clear
->surface
.parentx
= 0;
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
);
257 clear
->surface
.parentx
= self
->width
- ob_rr_theme
->grip_width
;
259 if (ob_rr_theme
->grip_width
> 0)
260 RrPaint(clear
, self
->trtresize
,
261 ob_rr_theme
->grip_width
, ob_rr_theme
->paddingy
+ 1);
263 clear
->surface
.parentx
= self
->width
- (ob_rr_theme
->paddingx
+ 1);
265 if (ob_rr_theme
->title_height
> 0)
266 RrPaint(clear
, self
->trrresize
,
267 ob_rr_theme
->paddingx
+ 1, ob_rr_theme
->title_height
);
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
;
274 m
->surface
.parent
= t
;
275 m
->surface
.parentx
= self
->max_x
;
276 m
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
278 n
->surface
.parent
= t
;
279 n
->surface
.parentx
= self
->icon_x
;
280 n
->surface
.parenty
= ob_rr_theme
->paddingy
;
282 i
->surface
.parent
= t
;
283 i
->surface
.parentx
= self
->iconify_x
;
284 i
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
286 d
->surface
.parent
= t
;
287 d
->surface
.parentx
= self
->desk_x
;
288 d
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
290 s
->surface
.parent
= t
;
291 s
->surface
.parentx
= self
->shade_x
;
292 s
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
294 c
->surface
.parent
= t
;
295 c
->surface
.parentx
= self
->close_x
;
296 c
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
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
);
307 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
&&
308 ob_rr_theme
->handle_height
> 0)
313 self
->a_focused_handle
: self
->a_unfocused_handle
);
315 RrPaint(h
, self
->handle
, self
->width
, ob_rr_theme
->handle_height
);
317 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
319 ob_rr_theme
->a_focused_grip
: ob_rr_theme
->a_unfocused_grip
);
321 if (g
->surface
.grad
== RR_SURFACE_PARENTREL
)
322 g
->surface
.parent
= h
;
324 g
->surface
.parentx
= 0;
325 g
->surface
.parenty
= 0;
327 RrPaint(g
, self
->lgrip
,
328 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
330 g
->surface
.parentx
= self
->width
- ob_rr_theme
->grip_width
;
331 g
->surface
.parenty
= 0;
333 RrPaint(g
, self
->rgrip
,
334 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
341 static void framerender_label(ObFrame
*self
, RrAppearance
*a
)
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
);
349 static void framerender_icon(ObFrame
*self
, RrAppearance
*a
)
351 const ObClientIcon
*icon
;
353 if (!self
->icon_on
) return;
355 icon
= client_icon(self
->client
,
356 ob_rr_theme
->button_size
+ 2,
357 ob_rr_theme
->button_size
+ 2);
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
;
365 a
->texture
[0].type
= RR_TEXTURE_NONE
;
367 RrPaint(a
, self
->icon
,
368 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
371 static void framerender_max(ObFrame
*self
, RrAppearance
*a
)
373 if (!self
->max_on
) return;
374 RrPaint(a
, self
->max
, ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
377 static void framerender_iconify(ObFrame
*self
, RrAppearance
*a
)
379 if (!self
->iconify_on
) return;
380 RrPaint(a
, self
->iconify
,
381 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
384 static void framerender_desk(ObFrame
*self
, RrAppearance
*a
)
386 if (!self
->desk_on
) return;
387 RrPaint(a
, self
->desk
, ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
390 static void framerender_shade(ObFrame
*self
, RrAppearance
*a
)
392 if (!self
->shade_on
) return;
393 RrPaint(a
, self
->shade
,
394 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
397 static void framerender_close(ObFrame
*self
, RrAppearance
*a
)
399 if (!self
->close_on
) return;
400 RrPaint(a
, self
->close
,
401 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);