Add "active" and "primary" options to the <monitor> placement option for per-app...
[openbox.git] / openbox / framerender.c
blob041e6d1775c2dbd3e329732ae5256e59f38581a5
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.
20 #include "frame.h"
21 #include "openbox.h"
22 #include "screen.h"
23 #include "client.h"
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)
40 return;
41 if (!self->visible)
42 return;
43 self->need_render = FALSE;
46 gulong px;
48 px = (self->focused ?
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;
130 if (self->focused) {
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_disabled_focused :
135 (self->client->max_vert || self->client->max_horz ?
136 (self->max_press ?
137 ob_rr_theme->btn_max->a_toggled_focused_pressed :
138 (self->max_hover ?
139 ob_rr_theme->btn_max->a_toggled_hover_focused :
140 ob_rr_theme->btn_max->a_toggled_focused_unpressed)) :
141 (self->max_press ?
142 ob_rr_theme->btn_max->a_focused_pressed :
143 (self->max_hover ?
144 ob_rr_theme->btn_max->a_hover_focused :
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_disabled_focused :
149 (self->iconify_press ?
150 ob_rr_theme->btn_iconify->a_focused_pressed :
151 (self->iconify_hover ?
152 ob_rr_theme->btn_iconify->a_hover_focused :
153 ob_rr_theme->btn_iconify->a_focused_unpressed)));
154 d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
155 ob_rr_theme->btn_desk->a_disabled_focused :
156 (self->client->desktop == DESKTOP_ALL ?
157 (self->desk_press ?
158 ob_rr_theme->btn_desk->a_toggled_focused_pressed :
159 (self->desk_hover ?
160 ob_rr_theme->btn_desk->a_toggled_hover_focused :
161 ob_rr_theme->btn_desk->a_toggled_focused_unpressed)) :
162 (self->desk_press ?
163 ob_rr_theme->btn_desk->a_focused_pressed :
164 (self->desk_hover ?
165 ob_rr_theme->btn_desk->a_hover_focused :
166 ob_rr_theme->btn_desk->a_focused_unpressed))));
167 s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
168 ob_rr_theme->btn_shade->a_disabled_focused :
169 (self->client->shaded ?
170 (self->shade_press ?
171 ob_rr_theme->btn_shade->a_toggled_focused_pressed :
172 (self->shade_hover ?
173 ob_rr_theme->btn_shade->a_toggled_hover_focused :
174 ob_rr_theme->btn_shade->a_toggled_focused_unpressed)) :
175 (self->shade_press ?
176 ob_rr_theme->btn_shade->a_focused_pressed :
177 (self->shade_hover ?
178 ob_rr_theme->btn_shade->a_hover_focused :
179 ob_rr_theme->btn_shade->a_focused_unpressed))));
180 c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
181 ob_rr_theme->btn_close->a_disabled_focused :
182 (self->close_press ?
183 ob_rr_theme->btn_close->a_focused_pressed :
184 (self->close_hover ?
185 ob_rr_theme->btn_close->a_hover_focused :
186 ob_rr_theme->btn_close->a_focused_unpressed)));
187 } else {
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_disabled_unfocused :
192 (self->client->max_vert || self->client->max_horz ?
193 (self->max_press ?
194 ob_rr_theme->btn_max->a_toggled_unfocused_pressed :
195 (self->max_hover ?
196 ob_rr_theme->btn_max->a_toggled_hover_unfocused :
197 ob_rr_theme->btn_max->a_toggled_unfocused_unpressed)) :
198 (self->max_press ?
199 ob_rr_theme->btn_max->a_unfocused_pressed :
200 (self->max_hover ?
201 ob_rr_theme->btn_max->a_hover_unfocused :
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_disabled_unfocused :
206 (self->iconify_press ?
207 ob_rr_theme->btn_iconify->a_unfocused_pressed :
208 (self->iconify_hover ?
209 ob_rr_theme->btn_iconify->a_hover_unfocused :
210 ob_rr_theme->btn_iconify->a_unfocused_unpressed)));
211 d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
212 ob_rr_theme->btn_desk->a_disabled_unfocused :
213 (self->client->desktop == DESKTOP_ALL ?
214 (self->desk_press ?
215 ob_rr_theme->btn_desk->a_toggled_unfocused_pressed :
216 (self->desk_hover ?
217 ob_rr_theme->btn_desk->a_toggled_hover_unfocused :
218 ob_rr_theme->btn_desk->a_toggled_unfocused_unpressed)) :
219 (self->desk_press ?
220 ob_rr_theme->btn_desk->a_unfocused_pressed :
221 (self->desk_hover ?
222 ob_rr_theme->btn_desk->a_hover_unfocused :
223 ob_rr_theme->btn_desk->a_unfocused_unpressed))));
224 s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
225 ob_rr_theme->btn_shade->a_disabled_unfocused :
226 (self->client->shaded ?
227 (self->shade_press ?
228 ob_rr_theme->btn_shade->a_toggled_unfocused_pressed :
229 (self->shade_hover ?
230 ob_rr_theme->btn_shade->a_toggled_hover_unfocused :
231 ob_rr_theme->btn_shade->a_toggled_unfocused_unpressed)) :
232 (self->shade_press ?
233 ob_rr_theme->btn_shade->a_unfocused_pressed :
234 (self->shade_hover ?
235 ob_rr_theme->btn_shade->a_hover_unfocused :
236 ob_rr_theme->btn_shade->a_unfocused_unpressed))));
237 c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
238 ob_rr_theme->btn_close->a_disabled_unfocused :
239 (self->close_press ?
240 ob_rr_theme->btn_close->a_unfocused_pressed :
241 (self->close_hover ?
242 ob_rr_theme->btn_close->a_hover_unfocused :
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)
320 RrAppearance *h, *g;
322 h = (self->focused ?
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) {
328 g = (self->focused ?
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);
348 XFlush(obt_display);
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)
361 RrImage *icon;
363 if (!self->icon_on) return;
365 icon = client_icon(self->client);
367 if (icon) {
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;
372 } else {
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);