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 "obrender/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(obt_display
, self
->backback
, px
);
53 XClearWindow(obt_display
, self
->backback
);
54 XSetWindowBackground(obt_display
, self
->innerleft
, px
);
55 XClearWindow(obt_display
, self
->innerleft
);
56 XSetWindowBackground(obt_display
, self
->innertop
, px
);
57 XClearWindow(obt_display
, self
->innertop
);
58 XSetWindowBackground(obt_display
, self
->innerright
, px
);
59 XClearWindow(obt_display
, self
->innerright
);
60 XSetWindowBackground(obt_display
, self
->innerbottom
, px
);
61 XClearWindow(obt_display
, self
->innerbottom
);
62 XSetWindowBackground(obt_display
, self
->innerbll
, px
);
63 XClearWindow(obt_display
, self
->innerbll
);
64 XSetWindowBackground(obt_display
, self
->innerbrr
, px
);
65 XClearWindow(obt_display
, self
->innerbrr
);
66 XSetWindowBackground(obt_display
, self
->innerblb
, px
);
67 XClearWindow(obt_display
, self
->innerblb
);
68 XSetWindowBackground(obt_display
, self
->innerbrb
, px
);
69 XClearWindow(obt_display
, self
->innerbrb
);
71 px
= RrColorPixel(self
->focused
?
72 (self
->client
->undecorated
?
73 ob_rr_theme
->frame_undecorated_focused_border_color
:
74 ob_rr_theme
->frame_focused_border_color
) :
75 (self
->client
->undecorated
?
76 ob_rr_theme
->frame_undecorated_unfocused_border_color
:
77 ob_rr_theme
->frame_unfocused_border_color
));
79 XSetWindowBackground(obt_display
, self
->left
, px
);
80 XClearWindow(obt_display
, self
->left
);
81 XSetWindowBackground(obt_display
, self
->right
, px
);
82 XClearWindow(obt_display
, self
->right
);
84 XSetWindowBackground(obt_display
, self
->titleleft
, px
);
85 XClearWindow(obt_display
, self
->titleleft
);
86 XSetWindowBackground(obt_display
, self
->titletop
, px
);
87 XClearWindow(obt_display
, self
->titletop
);
88 XSetWindowBackground(obt_display
, self
->titletopleft
, px
);
89 XClearWindow(obt_display
, self
->titletopleft
);
90 XSetWindowBackground(obt_display
, self
->titletopright
, px
);
91 XClearWindow(obt_display
, self
->titletopright
);
92 XSetWindowBackground(obt_display
, self
->titleright
, px
);
93 XClearWindow(obt_display
, self
->titleright
);
95 XSetWindowBackground(obt_display
, self
->handleleft
, px
);
96 XClearWindow(obt_display
, self
->handleleft
);
97 XSetWindowBackground(obt_display
, self
->handletop
, px
);
98 XClearWindow(obt_display
, self
->handletop
);
99 XSetWindowBackground(obt_display
, self
->handleright
, px
);
100 XClearWindow(obt_display
, self
->handleright
);
101 XSetWindowBackground(obt_display
, self
->handlebottom
, px
);
102 XClearWindow(obt_display
, self
->handlebottom
);
104 XSetWindowBackground(obt_display
, self
->lgripleft
, px
);
105 XClearWindow(obt_display
, self
->lgripleft
);
106 XSetWindowBackground(obt_display
, self
->lgriptop
, px
);
107 XClearWindow(obt_display
, self
->lgriptop
);
108 XSetWindowBackground(obt_display
, self
->lgripbottom
, px
);
109 XClearWindow(obt_display
, self
->lgripbottom
);
111 XSetWindowBackground(obt_display
, self
->rgripright
, px
);
112 XClearWindow(obt_display
, self
->rgripright
);
113 XSetWindowBackground(obt_display
, self
->rgriptop
, px
);
114 XClearWindow(obt_display
, self
->rgriptop
);
115 XSetWindowBackground(obt_display
, self
->rgripbottom
, px
);
116 XClearWindow(obt_display
, self
->rgripbottom
);
118 /* don't use the separator color for shaded windows */
119 if (!self
->client
->shaded
)
120 px
= (self
->focused
?
121 RrColorPixel(ob_rr_theme
->title_separator_focused_color
) :
122 RrColorPixel(ob_rr_theme
->title_separator_unfocused_color
));
124 XSetWindowBackground(obt_display
, self
->titlebottom
, px
);
125 XClearWindow(obt_display
, self
->titlebottom
);
128 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
129 RrAppearance
*t
, *l
, *m
, *n
, *i
, *d
, *s
, *c
, *clear
;
131 t
= ob_rr_theme
->a_focused_title
;
132 l
= ob_rr_theme
->a_focused_label
;
133 m
= (!(self
->decorations
& OB_FRAME_DECOR_MAXIMIZE
) ?
134 ob_rr_theme
->btn_max
->a_focused_disabled
:
135 (self
->client
->max_vert
|| self
->client
->max_horz
?
137 ob_rr_theme
->btn_max
->a_focused_pressed_toggled
:
139 ob_rr_theme
->btn_max
->a_focused_hover_toggled
:
140 ob_rr_theme
->btn_max
->a_focused_unpressed_toggled
)) :
142 ob_rr_theme
->btn_max
->a_focused_pressed
:
144 ob_rr_theme
->btn_max
->a_focused_hover
:
145 ob_rr_theme
->btn_max
->a_focused_unpressed
))));
146 n
= ob_rr_theme
->a_icon
;
147 i
= (!(self
->decorations
& OB_FRAME_DECOR_ICONIFY
) ?
148 ob_rr_theme
->btn_iconify
->a_focused_disabled
:
149 (self
->iconify_press
?
150 ob_rr_theme
->btn_iconify
->a_focused_pressed
:
151 (self
->iconify_hover
?
152 ob_rr_theme
->btn_iconify
->a_focused_hover
:
153 ob_rr_theme
->btn_iconify
->a_focused_unpressed
)));
154 d
= (!(self
->decorations
& OB_FRAME_DECOR_ALLDESKTOPS
) ?
155 ob_rr_theme
->btn_desk
->a_focused_disabled
:
156 (self
->client
->desktop
== DESKTOP_ALL
?
158 ob_rr_theme
->btn_desk
->a_focused_pressed_toggled
:
160 ob_rr_theme
->btn_desk
->a_focused_hover_toggled
:
161 ob_rr_theme
->btn_desk
->a_focused_unpressed_toggled
)) :
163 ob_rr_theme
->btn_desk
->a_focused_pressed
:
165 ob_rr_theme
->btn_desk
->a_focused_hover
:
166 ob_rr_theme
->btn_desk
->a_focused_unpressed
))));
167 s
= (!(self
->decorations
& OB_FRAME_DECOR_SHADE
) ?
168 ob_rr_theme
->btn_shade
->a_focused_disabled
:
169 (self
->client
->shaded
?
171 ob_rr_theme
->btn_shade
->a_focused_pressed_toggled
:
173 ob_rr_theme
->btn_shade
->a_focused_hover_toggled
:
174 ob_rr_theme
->btn_shade
->a_focused_unpressed_toggled
)) :
176 ob_rr_theme
->btn_shade
->a_focused_pressed
:
178 ob_rr_theme
->btn_shade
->a_focused_hover
:
179 ob_rr_theme
->btn_shade
->a_focused_unpressed
))));
180 c
= (!(self
->decorations
& OB_FRAME_DECOR_CLOSE
) ?
181 ob_rr_theme
->btn_close
->a_focused_disabled
:
183 ob_rr_theme
->btn_close
->a_focused_pressed
:
185 ob_rr_theme
->btn_close
->a_focused_hover
:
186 ob_rr_theme
->btn_close
->a_focused_unpressed
)));
188 t
= ob_rr_theme
->a_unfocused_title
;
189 l
= ob_rr_theme
->a_unfocused_label
;
190 m
= (!(self
->decorations
& OB_FRAME_DECOR_MAXIMIZE
) ?
191 ob_rr_theme
->btn_max
->a_unfocused_disabled
:
192 (self
->client
->max_vert
|| self
->client
->max_horz
?
194 ob_rr_theme
->btn_max
->a_unfocused_pressed_toggled
:
196 ob_rr_theme
->btn_max
->a_unfocused_hover_toggled
:
197 ob_rr_theme
->btn_max
->a_unfocused_unpressed_toggled
)) :
199 ob_rr_theme
->btn_max
->a_unfocused_pressed
:
201 ob_rr_theme
->btn_max
->a_unfocused_hover
:
202 ob_rr_theme
->btn_max
->a_unfocused_unpressed
))));
203 n
= ob_rr_theme
->a_icon
;
204 i
= (!(self
->decorations
& OB_FRAME_DECOR_ICONIFY
) ?
205 ob_rr_theme
->btn_iconify
->a_unfocused_disabled
:
206 (self
->iconify_press
?
207 ob_rr_theme
->btn_iconify
->a_unfocused_pressed
:
208 (self
->iconify_hover
?
209 ob_rr_theme
->btn_iconify
->a_unfocused_hover
:
210 ob_rr_theme
->btn_iconify
->a_unfocused_unpressed
)));
211 d
= (!(self
->decorations
& OB_FRAME_DECOR_ALLDESKTOPS
) ?
212 ob_rr_theme
->btn_desk
->a_unfocused_disabled
:
213 (self
->client
->desktop
== DESKTOP_ALL
?
215 ob_rr_theme
->btn_desk
->a_unfocused_pressed_toggled
:
217 ob_rr_theme
->btn_desk
->a_unfocused_hover_toggled
:
218 ob_rr_theme
->btn_desk
->a_unfocused_unpressed_toggled
)) :
220 ob_rr_theme
->btn_desk
->a_unfocused_pressed
:
222 ob_rr_theme
->btn_desk
->a_unfocused_hover
:
223 ob_rr_theme
->btn_desk
->a_unfocused_unpressed
))));
224 s
= (!(self
->decorations
& OB_FRAME_DECOR_SHADE
) ?
225 ob_rr_theme
->btn_shade
->a_unfocused_disabled
:
226 (self
->client
->shaded
?
228 ob_rr_theme
->btn_shade
->a_unfocused_pressed_toggled
:
230 ob_rr_theme
->btn_shade
->a_unfocused_hover_toggled
:
231 ob_rr_theme
->btn_shade
->a_unfocused_unpressed_toggled
)) :
233 ob_rr_theme
->btn_shade
->a_unfocused_pressed
:
235 ob_rr_theme
->btn_shade
->a_unfocused_hover
:
236 ob_rr_theme
->btn_shade
->a_unfocused_unpressed
))));
237 c
= (!(self
->decorations
& OB_FRAME_DECOR_CLOSE
) ?
238 ob_rr_theme
->btn_close
->a_unfocused_disabled
:
240 ob_rr_theme
->btn_close
->a_unfocused_pressed
:
242 ob_rr_theme
->btn_close
->a_unfocused_hover
:
243 ob_rr_theme
->btn_close
->a_unfocused_unpressed
)));
245 clear
= ob_rr_theme
->a_clear
;
247 RrPaint(t
, self
->title
, self
->width
, ob_rr_theme
->title_height
);
249 clear
->surface
.parent
= t
;
250 clear
->surface
.parenty
= 0;
252 clear
->surface
.parentx
= ob_rr_theme
->grip_width
;
254 RrPaint(clear
, self
->topresize
,
255 self
->width
- ob_rr_theme
->grip_width
* 2,
256 ob_rr_theme
->paddingy
+ 1);
258 clear
->surface
.parentx
= 0;
260 if (ob_rr_theme
->grip_width
> 0)
261 RrPaint(clear
, self
->tltresize
,
262 ob_rr_theme
->grip_width
, ob_rr_theme
->paddingy
+ 1);
263 if (ob_rr_theme
->title_height
> 0)
264 RrPaint(clear
, self
->tllresize
,
265 ob_rr_theme
->paddingx
+ 1, ob_rr_theme
->title_height
);
267 clear
->surface
.parentx
= self
->width
- ob_rr_theme
->grip_width
;
269 if (ob_rr_theme
->grip_width
> 0)
270 RrPaint(clear
, self
->trtresize
,
271 ob_rr_theme
->grip_width
, ob_rr_theme
->paddingy
+ 1);
273 clear
->surface
.parentx
= self
->width
- (ob_rr_theme
->paddingx
+ 1);
275 if (ob_rr_theme
->title_height
> 0)
276 RrPaint(clear
, self
->trrresize
,
277 ob_rr_theme
->paddingx
+ 1, ob_rr_theme
->title_height
);
279 /* set parents for any parent relative guys */
280 l
->surface
.parent
= t
;
281 l
->surface
.parentx
= self
->label_x
;
282 l
->surface
.parenty
= ob_rr_theme
->paddingy
;
284 m
->surface
.parent
= t
;
285 m
->surface
.parentx
= self
->max_x
;
286 m
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
288 n
->surface
.parent
= t
;
289 n
->surface
.parentx
= self
->icon_x
;
290 n
->surface
.parenty
= ob_rr_theme
->paddingy
;
292 i
->surface
.parent
= t
;
293 i
->surface
.parentx
= self
->iconify_x
;
294 i
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
296 d
->surface
.parent
= t
;
297 d
->surface
.parentx
= self
->desk_x
;
298 d
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
300 s
->surface
.parent
= t
;
301 s
->surface
.parentx
= self
->shade_x
;
302 s
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
304 c
->surface
.parent
= t
;
305 c
->surface
.parentx
= self
->close_x
;
306 c
->surface
.parenty
= ob_rr_theme
->paddingy
+ 1;
308 framerender_label(self
, l
);
309 framerender_max(self
, m
);
310 framerender_icon(self
, n
);
311 framerender_iconify(self
, i
);
312 framerender_desk(self
, d
);
313 framerender_shade(self
, s
);
314 framerender_close(self
, c
);
317 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
&&
318 ob_rr_theme
->handle_height
> 0)
323 ob_rr_theme
->a_focused_handle
: ob_rr_theme
->a_unfocused_handle
);
325 RrPaint(h
, self
->handle
, self
->width
, ob_rr_theme
->handle_height
);
327 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
329 ob_rr_theme
->a_focused_grip
: ob_rr_theme
->a_unfocused_grip
);
331 if (g
->surface
.grad
== RR_SURFACE_PARENTREL
)
332 g
->surface
.parent
= h
;
334 g
->surface
.parentx
= 0;
335 g
->surface
.parenty
= 0;
337 RrPaint(g
, self
->lgrip
,
338 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
340 g
->surface
.parentx
= self
->width
- ob_rr_theme
->grip_width
;
341 g
->surface
.parenty
= 0;
343 RrPaint(g
, self
->rgrip
,
344 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
351 static void framerender_label(ObFrame
*self
, RrAppearance
*a
)
353 if (!self
->label_on
) return;
354 /* set the texture's text! */
355 a
->texture
[0].data
.text
.string
= self
->client
->title
;
356 RrPaint(a
, self
->label
, self
->label_width
, ob_rr_theme
->label_height
);
359 static void framerender_icon(ObFrame
*self
, RrAppearance
*a
)
363 if (!self
->icon_on
) return;
365 icon
= client_icon(self
->client
);
368 RrAppearanceClearTextures(a
);
369 a
->texture
[0].type
= RR_TEXTURE_IMAGE
;
370 a
->texture
[0].data
.image
.alpha
= 0xff;
371 a
->texture
[0].data
.image
.image
= icon
;
373 RrAppearanceClearTextures(a
);
374 a
->texture
[0].type
= RR_TEXTURE_NONE
;
377 RrPaint(a
, self
->icon
,
378 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
381 static void framerender_max(ObFrame
*self
, RrAppearance
*a
)
383 if (!self
->max_on
) return;
384 RrPaint(a
, self
->max
, ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
387 static void framerender_iconify(ObFrame
*self
, RrAppearance
*a
)
389 if (!self
->iconify_on
) return;
390 RrPaint(a
, self
->iconify
,
391 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
394 static void framerender_desk(ObFrame
*self
, RrAppearance
*a
)
396 if (!self
->desk_on
) return;
397 RrPaint(a
, self
->desk
, ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
400 static void framerender_shade(ObFrame
*self
, RrAppearance
*a
)
402 if (!self
->shade_on
) return;
403 RrPaint(a
, self
->shade
,
404 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
407 static void framerender_close(ObFrame
*self
, RrAppearance
*a
)
409 if (!self
->close_on
) return;
410 RrPaint(a
, self
->close
,
411 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);