1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
3 frame_default_plugin.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.
23 #include "openbox/config.h"
24 #include "openbox/openbox.h"
26 /* Needed for the _() function */
30 #include "openbox/screen.h"
32 /* Needed for the grab_server */
33 #include "openbox/grab.h"
35 #include <X11/extensions/shape.h>
40 OB_FLAG_CLOSE = 1 << 1,
41 OB_FLAG_DESK = 1 << 2,
42 OB_FLAG_SHADE = 1 << 3,
43 OB_FLAG_ICONIFY = 1 << 4
46 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
47 ButtonPressMask | ButtonReleaseMask | \
48 SubstructureRedirectMask | FocusChangeMask)
49 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
50 ButtonMotionMask | PointerMotionMask | \
51 EnterWindowMask | LeaveWindowMask)
53 #define FRAME_HANDLE_Y(f) (f->size.top + f->client_area.height + f->cbwidth_b)
55 Display * obp_display;
57 RrInstance *ob_rr_inst;
59 Window createWindow(Window parent, Visual *visual, gulong mask,
60 XSetWindowAttributes *attrib)
62 return XCreateWindow(obp_display, parent, 0, 0, 1, 1, 0, (visual ? 32
63 : RrDepth(ob_rr_inst)), InputOutput, (visual ? visual
64 : RrVisual(ob_rr_inst)), mask, attrib);
68 Visual *check_32bit_client(ObClient *c)
70 XWindowAttributes wattrib;
73 /* we're already running at 32 bit depth, yay. we don't need to use their
75 if (RrDepth(ob_rr_inst) == 32)
78 ret = XGetWindowAttributes(obp_display, c->w_client, &wattrib);
79 g_assert(ret != BadDrawable);
80 g_assert(ret != BadWindow);
82 if (wattrib.depth == 32)
83 return wattrib.visual;
88 gint init(Display * display, gint screen)
90 ob_rr_inst = RrInstanceNew(display, screen);
91 if (ob_rr_inst == NULL)
92 ob_exit_with_error(_("Failed to initialize the obrender library."));
93 obp_display = display;
97 gpointer frame_new(struct _ObClient * client, Window w_client, Window w_frame)
99 XSetWindowAttributes attrib;
101 ObDefaultFrame *self;
104 self = g_new0(ObDefaultFrame, 1);
105 self->client = client;
107 visual = check_32bit_client(client);
109 /* create the non-visible decor windows */
113 /* client has a 32-bit visual */
114 mask |= CWColormap | CWBackPixel | CWBorderPixel;
115 /* create a colormap with the visual */
116 OBDEFAULTFRAME(self)->colormap = attrib.colormap = XCreateColormap(
117 obp_display, RootWindow(obp_display, obp_screen), visual,
119 attrib.background_pixel = BlackPixel(obp_display, obp_screen);
120 attrib.border_pixel = BlackPixel(obp_display, obp_screen);
122 self->window = w_frame;
124 /* create the visible decor windows */
128 /* client has a 32-bit visual */
129 mask |= CWColormap | CWBackPixel | CWBorderPixel;
130 attrib.colormap = RrColormap(ob_rr_inst);
133 self->backback = createWindow(self->window, NULL, mask, &attrib);
134 self->backfront = createWindow(self->backback, NULL, mask, &attrib);
137 attrib.event_mask = ELEMENT_EVENTMASK;
138 self->innerleft = createWindow(self->window, NULL, mask, &attrib);
139 self->innertop = createWindow(self->window, NULL, mask, &attrib);
140 self->innerright = createWindow(self->window, NULL, mask, &attrib);
141 self->innerbottom = createWindow(self->window, NULL, mask, &attrib);
143 self->innerblb = createWindow(self->innerbottom, NULL, mask, &attrib);
144 self->innerbrb = createWindow(self->innerbottom, NULL, mask, &attrib);
145 self->innerbll = createWindow(self->innerleft, NULL, mask, &attrib);
146 self->innerbrr = createWindow(self->innerright, NULL, mask, &attrib);
148 self->title = createWindow(self->window, NULL, mask, &attrib);
149 self->titleleft = createWindow(self->window, NULL, mask, &attrib);
150 self->titletop = createWindow(self->window, NULL, mask, &attrib);
151 self->titletopleft = createWindow(self->window, NULL, mask, &attrib);
152 self->titletopright = createWindow(self->window, NULL, mask, &attrib);
153 self->titleright = createWindow(self->window, NULL, mask, &attrib);
154 self->titlebottom = createWindow(self->window, NULL, mask, &attrib);
156 self->topresize = createWindow(self->title, NULL, mask, &attrib);
157 self->tltresize = createWindow(self->title, NULL, mask, &attrib);
158 self->tllresize = createWindow(self->title, NULL, mask, &attrib);
159 self->trtresize = createWindow(self->title, NULL, mask, &attrib);
160 self->trrresize = createWindow(self->title, NULL, mask, &attrib);
162 self->left = createWindow(self->window, NULL, mask, &attrib);
163 self->right = createWindow(self->window, NULL, mask, &attrib);
165 self->label = createWindow(self->title, NULL, mask, &attrib);
166 self->max = createWindow(self->title, NULL, mask, &attrib);
167 self->close = createWindow(self->title, NULL, mask, &attrib);
168 self->desk = createWindow(self->title, NULL, mask, &attrib);
169 self->shade = createWindow(self->title, NULL, mask, &attrib);
170 self->icon = createWindow(self->title, NULL, mask, &attrib);
171 self->iconify = createWindow(self->title, NULL, mask, &attrib);
173 self->handle = createWindow(self->window, NULL, mask, &attrib);
174 self->lgrip = createWindow(self->handle, NULL, mask, &attrib);
175 self->rgrip = createWindow(self->handle, NULL, mask, &attrib);
177 self->handleleft = createWindow(self->handle, NULL, mask, &attrib);
178 self->handleright = createWindow(self->handle, NULL, mask, &attrib);
180 self->handletop = createWindow(self->window, NULL, mask, &attrib);
181 self->handlebottom = createWindow(self->window, NULL, mask, &attrib);
182 self->lgripleft = createWindow(self->window, NULL, mask, &attrib);
183 self->lgriptop = createWindow(self->window, NULL, mask, &attrib);
184 self->lgripbottom = createWindow(self->window, NULL, mask, &attrib);
185 self->rgripright = createWindow(self->window, NULL, mask, &attrib);
186 self->rgriptop = createWindow(self->window, NULL, mask, &attrib);
187 self->rgripbottom = createWindow(self->window, NULL, mask, &attrib);
189 self->stitle = g_strdup("");
190 self->focused = FALSE;
192 /* the other stuff is shown based on decor settings */
193 XMapWindow(obp_display, self->label);
194 XMapWindow(obp_display, self->backback);
195 XMapWindow(obp_display, self->backfront);
197 self->hover_flag = OB_BUTTON_NONE;
198 self->press_flag = OB_BUTTON_NONE;
200 set_theme_statics(self);
205 void set_theme_statics(gpointer _self)
207 ObDefaultFrame * self = (ObDefaultFrame *) _self;
208 /* set colors/appearance/sizes for stuff that doesn't change */
209 XResizeWindow(obp_display, self->max, theme_config.button_size,
210 theme_config.button_size);
211 XResizeWindow(obp_display, self->iconify, theme_config.button_size,
212 theme_config.button_size);
213 XResizeWindow(obp_display, self->icon, theme_config.button_size + 2,
214 theme_config.button_size + 2);
215 XResizeWindow(obp_display, self->close, theme_config.button_size,
216 theme_config.button_size);
217 XResizeWindow(obp_display, self->desk, theme_config.button_size,
218 theme_config.button_size);
219 XResizeWindow(obp_display, self->shade, theme_config.button_size,
220 theme_config.button_size);
221 XResizeWindow(obp_display, self->tltresize, theme_config.grip_width,
222 theme_config.paddingy + 1);
223 XResizeWindow(obp_display, self->trtresize, theme_config.grip_width,
224 theme_config.paddingy + 1);
225 XResizeWindow(obp_display, self->tllresize, theme_config.paddingx + 1,
226 theme_config.title_height);
227 XResizeWindow(obp_display, self->trrresize, theme_config.paddingx + 1,
228 theme_config.title_height);
230 /* set up the dynamic appearances */
231 self->a_unfocused_title = RrAppearanceCopy(theme_config.a_unfocused_title);
232 self->a_focused_title = RrAppearanceCopy(theme_config.a_focused_title);
233 self->a_unfocused_label = RrAppearanceCopy(theme_config.a_unfocused_label);
234 self->a_focused_label = RrAppearanceCopy(theme_config.a_focused_label);
235 self->a_unfocused_handle
236 = RrAppearanceCopy(theme_config.a_unfocused_handle);
237 self->a_focused_handle = RrAppearanceCopy(theme_config.a_focused_handle);
238 self->a_icon = RrAppearanceCopy(theme_config.a_icon);
241 void free_theme_statics(gpointer _self)
243 ObDefaultFrame * self = (ObDefaultFrame *) _self;
244 RrAppearanceFree(self->a_unfocused_title);
245 RrAppearanceFree(self->a_focused_title);
246 RrAppearanceFree(self->a_unfocused_label);
247 RrAppearanceFree(self->a_focused_label);
248 RrAppearanceFree(self->a_unfocused_handle);
249 RrAppearanceFree(self->a_focused_handle);
250 RrAppearanceFree(self->a_icon);
253 void frame_free(gpointer self)
255 free_theme_statics(OBDEFAULTFRAME(self));
256 XDestroyWindow(obp_display, OBDEFAULTFRAME(self)->window);
257 if (OBDEFAULTFRAME(self)->colormap)
258 XFreeColormap(obp_display, OBDEFAULTFRAME(self)->colormap);
260 g_free(OBDEFAULTFRAME(self)->stitle);
264 void frame_adjust_theme(gpointer self)
266 free_theme_statics(self);
267 set_theme_statics(self);
270 void frame_adjust_shape(gpointer _self)
273 ObDefaultFrame * self = (ObDefaultFrame *) _self;
277 if (!self->client->shaped)
279 /* clear the shape on the frame window */
280 XShapeCombineMask(obp_display, self->window, ShapeBounding,
287 /* make the frame's shape match the clients */
288 XShapeCombineShape(obp_display, self->window, ShapeBounding,
291 self->client->w_client,
292 ShapeBounding, ShapeSet);
295 if (self->decorations & OB_FRAME_DECOR_TITLEBAR)
299 xrect[0].width = self->area.width;
300 xrect[0].height = self->size.top;
304 if (self->decorations & OB_FRAME_DECOR_HANDLE &&
305 theme_config.handle_height> 0)
308 xrect[1].y = FRAME_HANDLE_Y(self);
309 xrect[1].width = self->area.width;
310 xrect[1].height = theme_config.handle_height +
315 XShapeCombineRectangles(obp_display, self->window,
316 ShapeBounding, 0, 0, xrect, num,
317 ShapeUnion, Unsorted);
322 void frame_grab(gpointer _self, GHashTable * window_map)
324 ObDefaultFrame * self = (ObDefaultFrame *) _self;
325 /* DO NOT map the client window here. we used to do that, but it is bogus.
326 we need to set up the client's dimensions and everything before we
327 send a mapnotify or we create race conditions.
330 /* set all the windows for the frame in the window_map */
331 g_hash_table_insert(window_map, &self->window, self->client);
332 g_hash_table_insert(window_map, &self->backback, self->client);
333 g_hash_table_insert(window_map, &self->backfront, self->client);
334 g_hash_table_insert(window_map, &self->innerleft, self->client);
335 g_hash_table_insert(window_map, &self->innertop, self->client);
336 g_hash_table_insert(window_map, &self->innerright, self->client);
337 g_hash_table_insert(window_map, &self->innerbottom, self->client);
338 g_hash_table_insert(window_map, &self->title, self->client);
339 g_hash_table_insert(window_map, &self->label, self->client);
340 g_hash_table_insert(window_map, &self->max, self->client);
341 g_hash_table_insert(window_map, &self->close, self->client);
342 g_hash_table_insert(window_map, &self->desk, self->client);
343 g_hash_table_insert(window_map, &self->shade, self->client);
344 g_hash_table_insert(window_map, &self->icon, self->client);
345 g_hash_table_insert(window_map, &self->iconify, self->client);
346 g_hash_table_insert(window_map, &self->handle, self->client);
347 g_hash_table_insert(window_map, &self->lgrip, self->client);
348 g_hash_table_insert(window_map, &self->rgrip, self->client);
349 g_hash_table_insert(window_map, &self->topresize, self->client);
350 g_hash_table_insert(window_map, &self->tltresize, self->client);
351 g_hash_table_insert(window_map, &self->tllresize, self->client);
352 g_hash_table_insert(window_map, &self->trtresize, self->client);
353 g_hash_table_insert(window_map, &self->trrresize, self->client);
354 g_hash_table_insert(window_map, &self->left, self->client);
355 g_hash_table_insert(window_map, &self->right, self->client);
356 g_hash_table_insert(window_map, &self->titleleft, self->client);
357 g_hash_table_insert(window_map, &self->titletop, self->client);
358 g_hash_table_insert(window_map, &self->titletopleft, self->client);
359 g_hash_table_insert(window_map, &self->titletopright, self->client);
360 g_hash_table_insert(window_map, &self->titleright, self->client);
361 g_hash_table_insert(window_map, &self->titlebottom, self->client);
362 g_hash_table_insert(window_map, &self->handleleft, self->client);
363 g_hash_table_insert(window_map, &self->handletop, self->client);
364 g_hash_table_insert(window_map, &self->handleright, self->client);
365 g_hash_table_insert(window_map, &self->handlebottom, self->client);
366 g_hash_table_insert(window_map, &self->lgripleft, self->client);
367 g_hash_table_insert(window_map, &self->lgriptop, self->client);
368 g_hash_table_insert(window_map, &self->lgripbottom, self->client);
369 g_hash_table_insert(window_map, &self->rgripright, self->client);
370 g_hash_table_insert(window_map, &self->rgriptop, self->client);
371 g_hash_table_insert(window_map, &self->rgripbottom, self->client);
374 void frame_ungrab(gpointer _self, GHashTable * window_map)
376 ObDefaultFrame * self = (ObDefaultFrame *) _self;
377 /* remove all the windows for the frame from the window_map */
378 g_hash_table_remove(window_map, &self->window);
379 g_hash_table_remove(window_map, &self->backback);
380 g_hash_table_remove(window_map, &self->backfront);
381 g_hash_table_remove(window_map, &self->innerleft);
382 g_hash_table_remove(window_map, &self->innertop);
383 g_hash_table_remove(window_map, &self->innerright);
384 g_hash_table_remove(window_map, &self->innerbottom);
385 g_hash_table_remove(window_map, &self->title);
386 g_hash_table_remove(window_map, &self->label);
387 g_hash_table_remove(window_map, &self->max);
388 g_hash_table_remove(window_map, &self->close);
389 g_hash_table_remove(window_map, &self->desk);
390 g_hash_table_remove(window_map, &self->shade);
391 g_hash_table_remove(window_map, &self->icon);
392 g_hash_table_remove(window_map, &self->iconify);
393 g_hash_table_remove(window_map, &self->handle);
394 g_hash_table_remove(window_map, &self->lgrip);
395 g_hash_table_remove(window_map, &self->rgrip);
396 g_hash_table_remove(window_map, &self->topresize);
397 g_hash_table_remove(window_map, &self->tltresize);
398 g_hash_table_remove(window_map, &self->tllresize);
399 g_hash_table_remove(window_map, &self->trtresize);
400 g_hash_table_remove(window_map, &self->trrresize);
401 g_hash_table_remove(window_map, &self->left);
402 g_hash_table_remove(window_map, &self->right);
403 g_hash_table_remove(window_map, &self->titleleft);
404 g_hash_table_remove(window_map, &self->titletop);
405 g_hash_table_remove(window_map, &self->titletopleft);
406 g_hash_table_remove(window_map, &self->titletopright);
407 g_hash_table_remove(window_map, &self->titleright);
408 g_hash_table_remove(window_map, &self->titlebottom);
409 g_hash_table_remove(window_map, &self->handleleft);
410 g_hash_table_remove(window_map, &self->handletop);
411 g_hash_table_remove(window_map, &self->handleright);
412 g_hash_table_remove(window_map, &self->handlebottom);
413 g_hash_table_remove(window_map, &self->lgripleft);
414 g_hash_table_remove(window_map, &self->lgriptop);
415 g_hash_table_remove(window_map, &self->lgripbottom);
416 g_hash_table_remove(window_map, &self->rgripright);
417 g_hash_table_remove(window_map, &self->rgriptop);
418 g_hash_table_remove(window_map, &self->rgripbottom);
423 ObFrameContext frame_context(gpointer _self, Window win, gint x, gint y)
425 ObDefaultFrame * self = OBDEFAULTFRAME(_self);
427 /* when the user clicks in the corners of the titlebar and the client
428 is fully maximized, then treat it like they clicked in the
429 button that is there */
430 if (self->max_horz && self->max_vert && (win == self->title || win
431 == self->titletop || win == self->titleleft || win
432 == self->titletopleft || win == self->titleright || win
433 == self->titletopright)) {
434 /* get the mouse coords in reference to the whole frame */
438 /* these windows are down a border width from the top of the frame */
439 if (win == self->title || win == self->titleleft || win
443 /* title is a border width in from the edge */
444 if (win == self->title)
446 /* titletop is a bit to the right */
447 else if (win == self->titletop)
448 fx += theme_config.grip_width + self->bwidth;
449 /* titletopright is way to the right edge */
450 else if (win == self->titletopright)
451 fx += self->area.width - (theme_config.grip_width + self->bwidth);
452 /* titleright is even more way to the right edge */
453 else if (win == self->titleright)
454 fx += self->area.width - self->bwidth;
456 /* figure out if we're over the area that should be considered a
458 if (fy < self->bwidth + theme_config.paddingy + 1
459 + theme_config.button_size) {
460 if (fx < (self->bwidth + theme_config.paddingx + 1
461 + theme_config.button_size)) {
462 if (self->leftmost != OB_FRAME_CONTEXT_NONE)
463 return self->leftmost;
465 else if (fx >= (self->area.width - (self->bwidth
466 + theme_config.paddingx + 1 + theme_config.button_size))) {
467 if (self->rightmost != OB_FRAME_CONTEXT_NONE)
468 return self->rightmost;
472 /* there is no resizing maximized windows so make them the titlebar
474 return OB_FRAME_CONTEXT_TITLEBAR;
476 else if (self->max_vert
477 && (win == self->titletop || win == self->topresize))
478 /* can't resize vertically when max vert */
479 return OB_FRAME_CONTEXT_TITLEBAR;
480 else if (self->shaded && (win == self->titletop || win == self->topresize))
481 /* can't resize vertically when shaded */
482 return OB_FRAME_CONTEXT_TITLEBAR;
484 if (win == self->window)
485 return OB_FRAME_CONTEXT_FRAME;
486 if (win == self->label)
487 return OB_FRAME_CONTEXT_TITLEBAR;
488 if (win == self->handle)
489 return OB_FRAME_CONTEXT_BOTTOM;
490 if (win == self->handletop)
491 return OB_FRAME_CONTEXT_BOTTOM;
492 if (win == self->handlebottom)
493 return OB_FRAME_CONTEXT_BOTTOM;
494 if (win == self->handleleft)
495 return OB_FRAME_CONTEXT_BLCORNER;
496 if (win == self->lgrip)
497 return OB_FRAME_CONTEXT_BLCORNER;
498 if (win == self->lgripleft)
499 return OB_FRAME_CONTEXT_BLCORNER;
500 if (win == self->lgriptop)
501 return OB_FRAME_CONTEXT_BLCORNER;
502 if (win == self->lgripbottom)
503 return OB_FRAME_CONTEXT_BLCORNER;
504 if (win == self->handleright)
505 return OB_FRAME_CONTEXT_BRCORNER;
506 if (win == self->rgrip)
507 return OB_FRAME_CONTEXT_BRCORNER;
508 if (win == self->rgripright)
509 return OB_FRAME_CONTEXT_BLCORNER;
510 if (win == self->rgriptop)
511 return OB_FRAME_CONTEXT_BLCORNER;
512 if (win == self->rgripbottom)
513 return OB_FRAME_CONTEXT_BLCORNER;
514 if (win == self->title)
515 return OB_FRAME_CONTEXT_TITLEBAR;
516 if (win == self->titlebottom)
517 return OB_FRAME_CONTEXT_TITLEBAR;
518 if (win == self->titleleft)
519 return OB_FRAME_CONTEXT_TLCORNER;
520 if (win == self->titletopleft)
521 return OB_FRAME_CONTEXT_TLCORNER;
522 if (win == self->titleright)
523 return OB_FRAME_CONTEXT_TRCORNER;
524 if (win == self->titletopright)
525 return OB_FRAME_CONTEXT_TRCORNER;
526 if (win == self->titletop)
527 return OB_FRAME_CONTEXT_TOP;
528 if (win == self->topresize)
529 return OB_FRAME_CONTEXT_TOP;
530 if (win == self->tltresize)
531 return OB_FRAME_CONTEXT_TLCORNER;
532 if (win == self->tllresize)
533 return OB_FRAME_CONTEXT_TLCORNER;
534 if (win == self->trtresize)
535 return OB_FRAME_CONTEXT_TRCORNER;
536 if (win == self->trrresize)
537 return OB_FRAME_CONTEXT_TRCORNER;
538 if (win == self->left)
539 return OB_FRAME_CONTEXT_LEFT;
540 if (win == self->right)
541 return OB_FRAME_CONTEXT_RIGHT;
542 if (win == self->innertop)
543 return OB_FRAME_CONTEXT_TITLEBAR;
544 if (win == self->innerleft)
545 return OB_FRAME_CONTEXT_LEFT;
546 if (win == self->innerbottom)
547 return OB_FRAME_CONTEXT_BOTTOM;
548 if (win == self->innerright)
549 return OB_FRAME_CONTEXT_RIGHT;
550 if (win == self->max)
551 return OB_FRAME_CONTEXT_MAXIMIZE;
552 if (win == self->iconify)
553 return OB_FRAME_CONTEXT_ICONIFY;
554 if (win == self->close)
555 return OB_FRAME_CONTEXT_CLOSE;
556 if (win == self->icon)
557 return OB_FRAME_CONTEXT_ICON;
558 if (win == self->desk)
559 return OB_FRAME_CONTEXT_ALLDESKTOPS;
560 if (win == self->shade)
561 return OB_FRAME_CONTEXT_SHADE;
563 return OB_FRAME_CONTEXT_NONE;
566 void frame_set_is_visible(gpointer self, gboolean b)
568 OBDEFAULTFRAME(self)->visible = b;
571 void frame_set_is_focus(gpointer self, gboolean b)
573 OBDEFAULTFRAME(self)->focused = b;
576 void frame_set_is_max_vert(gpointer self, gboolean b)
578 OBDEFAULTFRAME(self)->max_vert = b;
581 void frame_set_is_max_horz(gpointer self, gboolean b)
583 OBDEFAULTFRAME(self)->max_horz = b;
586 void frame_set_is_shaded(gpointer self, gboolean b)
588 OBDEFAULTFRAME(self)->shaded = b;
591 void frame_unfocus(gpointer self)
593 OBDEFAULTFRAME(self)->focused = FALSE;
596 void frame_set_decorations(gpointer self, ObFrameDecorations d)
598 OBDEFAULTFRAME(self)->decorations = d;
601 void frame_get_window_area(gpointer self, Rect * r)
603 /* *r = (OBDEFAULTFRAME(self)->area) ??? */
604 memcpy(r, &(OBDEFAULTFRAME(self)->area), sizeof(Rect));
606 void frame_set_client_area(gpointer self, Rect r)
608 OBDEFAULTFRAME(self)->client_area = r;
611 void frame_update_layout(gpointer _self, Rect area, gboolean is_resize, gboolean is_fake)
613 ObDefaultFrame * self = (ObDefaultFrame *) _self;
616 oldsize = self->size;
617 self->client_area = area;
618 self->area = self->client_area;
620 /* do this before changing the frame's status like max_horz max_vert */
621 frame_adjust_cursors(self);
623 if (self->decorations & OB_FRAME_DECOR_BORDER
624 || (config_theme_keepborder)) {
625 self->bwidth = theme_config.fbwidth;
631 if (self->decorations & OB_FRAME_DECOR_BORDER) {
632 self->cbwidth_l = theme_config.cbwidthx;
633 self->cbwidth_r = theme_config.cbwidthx;
634 self->cbwidth_t = theme_config.cbwidthy;
635 self->cbwidth_b = theme_config.cbwidthy;
644 if (self->max_horz) {
647 self->width = self->client_area.width;
652 self->width = self->client_area.width + self->cbwidth_l
656 /* some elements are sized based of the width, so don't let them have
658 self->width = MAX(self->width, (theme_config.grip_width + self->bwidth) * 2
661 STRUT_SET(self->size, self->cbwidth_l
662 + (!self->max_horz ? self->bwidth : 0), self->cbwidth_t
663 + self->bwidth, self->cbwidth_r + (!self->max_horz ? self->bwidth
664 : 0), self->cbwidth_b
665 + (!self->max_horz || !self->max_vert ? self->bwidth : 0));
667 if (self->decorations & OB_FRAME_DECOR_TITLEBAR)
668 self->size.top += theme_config.title_height + self->bwidth;
669 if (self->decorations & OB_FRAME_DECOR_HANDLE && theme_config.handle_height
671 self->size.bottom += theme_config.handle_height + self->bwidth;
674 /* position/size and map/unmap all the windows */
676 gint innercornerheight = theme_config.grip_width - self->size.bottom;
678 if (self->cbwidth_l) {
679 XMoveResizeWindow(obp_display, self->innerleft, self->size.left
680 - self->cbwidth_l, self->size.top, self->cbwidth_l,
681 self->client_area.height);
683 XMapWindow(obp_display, self->innerleft);
686 XUnmapWindow(obp_display, self->innerleft);
688 if (self->cbwidth_l && innercornerheight > 0) {
689 XMoveResizeWindow(obp_display, self->innerbll, 0,
690 self->client_area.height - (theme_config.grip_width
691 - self->size.bottom), self->cbwidth_l,
692 theme_config.grip_width - self->size.bottom);
694 XMapWindow(obp_display, self->innerbll);
697 XUnmapWindow(obp_display, self->innerbll);
699 if (self->cbwidth_r) {
700 XMoveResizeWindow(obp_display, self->innerright, self->size.left
701 + self->client_area.width, self->size.top, self->cbwidth_r,
702 self->client_area.height);
704 XMapWindow(obp_display, self->innerright);
707 XUnmapWindow(obp_display, self->innerright);
709 if (self->cbwidth_r && innercornerheight > 0) {
710 XMoveResizeWindow(obp_display, self->innerbrr, 0,
711 self->client_area.height - (theme_config.grip_width
712 - self->size.bottom), self->cbwidth_r,
713 theme_config.grip_width - self->size.bottom);
715 XMapWindow(obp_display, self->innerbrr);
718 XUnmapWindow(obp_display, self->innerbrr);
720 if (self->cbwidth_t) {
724 self->size.left - self->cbwidth_l,
725 self->size.top - self->cbwidth_t,
726 self->client_area.width + self->cbwidth_l + self->cbwidth_r,
729 XMapWindow(obp_display, self->innertop);
732 XUnmapWindow(obp_display, self->innertop);
734 if (self->cbwidth_b) {
735 XMoveResizeWindow(obp_display, self->innerbottom, self->size.left
736 - self->cbwidth_l, self->size.top
737 + self->client_area.height, self->client_area.width
738 + self->cbwidth_l + self->cbwidth_r, self->cbwidth_b);
740 XMoveResizeWindow(obp_display, self->innerblb, 0, 0,
741 theme_config.grip_width + self->bwidth, self->cbwidth_b);
742 XMoveResizeWindow(obp_display, self->innerbrb,
743 self->client_area.width + self->cbwidth_l + self->cbwidth_r
744 - (theme_config.grip_width + self->bwidth), 0,
745 theme_config.grip_width + self->bwidth, self->cbwidth_b);
747 XMapWindow(obp_display, self->innerbottom);
748 XMapWindow(obp_display, self->innerblb);
749 XMapWindow(obp_display, self->innerbrb);
752 XUnmapWindow(obp_display, self->innerbottom);
753 XUnmapWindow(obp_display, self->innerblb);
754 XUnmapWindow(obp_display, self->innerbrb);
760 /* height of titleleft and titleright */
761 titlesides = (!self->max_horz ? theme_config.grip_width : 0);
763 XMoveResizeWindow(obp_display, self->titletop,
764 theme_config.grip_width + self->bwidth, 0,
765 /* width + bwidth*2 - bwidth*2 - grips*2 */
766 self->width - theme_config.grip_width * 2, self->bwidth);
767 XMoveResizeWindow(obp_display, self->titletopleft, 0, 0,
768 theme_config.grip_width + self->bwidth, self->bwidth);
769 XMoveResizeWindow(obp_display, self->titletopright,
770 self->client_area.width + self->size.left
771 + self->size.right - theme_config.grip_width
772 - self->bwidth, 0, theme_config.grip_width
773 + self->bwidth, self->bwidth);
775 if (titlesides > 0) {
776 XMoveResizeWindow(obp_display, self->titleleft, 0,
777 self->bwidth, self->bwidth, titlesides);
778 XMoveResizeWindow(obp_display, self->titleright,
779 self->client_area.width + self->size.left
780 + self->size.right - self->bwidth,
781 self->bwidth, self->bwidth, titlesides);
783 XMapWindow(obp_display, self->titleleft);
784 XMapWindow(obp_display, self->titleright);
787 XUnmapWindow(obp_display, self->titleleft);
788 XUnmapWindow(obp_display, self->titleright);
791 XMapWindow(obp_display, self->titletop);
792 XMapWindow(obp_display, self->titletopleft);
793 XMapWindow(obp_display, self->titletopright);
795 if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
796 XMoveResizeWindow(obp_display, self->titlebottom,
797 (self->max_horz ? 0 : self->bwidth),
798 theme_config.title_height + self->bwidth, self->width,
801 XMapWindow(obp_display, self->titlebottom);
804 XUnmapWindow(obp_display, self->titlebottom);
807 XUnmapWindow(obp_display, self->titlebottom);
809 XUnmapWindow(obp_display, self->titletop);
810 XUnmapWindow(obp_display, self->titletopleft);
811 XUnmapWindow(obp_display, self->titletopright);
812 XUnmapWindow(obp_display, self->titleleft);
813 XUnmapWindow(obp_display, self->titleright);
816 if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
817 XMoveResizeWindow(obp_display, self->title, (self->max_horz ? 0
818 : self->bwidth), self->bwidth, self->width,
819 theme_config.title_height);
821 XMapWindow(obp_display, self->title);
823 if (self->decorations & OB_FRAME_DECOR_GRIPS) {
824 XMoveResizeWindow(obp_display, self->topresize,
825 theme_config.grip_width, 0, self->width
826 - theme_config.grip_width *2,
827 theme_config.paddingy + 1);
829 XMoveWindow(obp_display, self->tltresize, 0, 0);
830 XMoveWindow(obp_display, self->tllresize, 0, 0);
831 XMoveWindow(obp_display, self->trtresize, self->width
832 - theme_config.grip_width, 0);
833 XMoveWindow(obp_display, self->trrresize, self->width
834 - theme_config.paddingx - 1, 0);
836 XMapWindow(obp_display, self->topresize);
837 XMapWindow(obp_display, self->tltresize);
838 XMapWindow(obp_display, self->tllresize);
839 XMapWindow(obp_display, self->trtresize);
840 XMapWindow(obp_display, self->trrresize);
843 XUnmapWindow(obp_display, self->topresize);
844 XUnmapWindow(obp_display, self->tltresize);
845 XUnmapWindow(obp_display, self->tllresize);
846 XUnmapWindow(obp_display, self->trtresize);
847 XUnmapWindow(obp_display, self->trrresize);
851 XUnmapWindow(obp_display, self->title);
854 if ((self->decorations & OB_FRAME_DECOR_TITLEBAR))
855 /* layout the title bar elements */
859 gint sidebwidth = self->max_horz ? 0 : self->bwidth;
861 if (self->bwidth && self->size.bottom) {
862 XMoveResizeWindow(obp_display, self->handlebottom,
863 theme_config.grip_width + self->bwidth + sidebwidth,
864 self->size.top + self->client_area.height
865 + self->size.bottom - self->bwidth, self->width
866 - (theme_config.grip_width + sidebwidth) * 2,
870 XMoveResizeWindow(obp_display, self->lgripleft, 0,
871 self->size.top + self->client_area.height
873 - (!self->max_horz ? theme_config.grip_width
874 : self->size.bottom - self->cbwidth_b),
876 (!self->max_horz ? theme_config.grip_width
877 : self->size.bottom - self->cbwidth_b));
878 XMoveResizeWindow(obp_display, self->rgripright,
879 self->size.left + self->client_area.width
880 + self->size.right - self->bwidth,
881 self->size.top + self->client_area.height
883 - (!self->max_horz ? theme_config.grip_width
884 : self->size.bottom - self->cbwidth_b),
886 (!self->max_horz ? theme_config.grip_width
887 : self->size.bottom - self->cbwidth_b));
889 XMapWindow(obp_display, self->lgripleft);
890 XMapWindow(obp_display, self->rgripright);
893 XUnmapWindow(obp_display, self->lgripleft);
894 XUnmapWindow(obp_display, self->rgripright);
897 XMoveResizeWindow(obp_display, self->lgripbottom, sidebwidth,
898 self->size.top + self->client_area.height
899 + self->size.bottom - self->bwidth,
900 theme_config.grip_width + self->bwidth, self->bwidth);
901 XMoveResizeWindow(obp_display, self->rgripbottom, self->size.left
902 + self->client_area.width + self->size.right - self->bwidth
903 - sidebwidth - theme_config.grip_width, self->size.top
904 + self->client_area.height + self->size.bottom
905 - self->bwidth, theme_config.grip_width + self->bwidth,
908 XMapWindow(obp_display, self->handlebottom);
909 XMapWindow(obp_display, self->lgripbottom);
910 XMapWindow(obp_display, self->rgripbottom);
912 if (self->decorations & OB_FRAME_DECOR_HANDLE
913 && theme_config.handle_height > 0) {
914 XMoveResizeWindow(obp_display, self->handletop,
915 theme_config.grip_width + self->bwidth + sidebwidth,
916 FRAME_HANDLE_Y(self), self->width - (theme_config.grip_width
917 + sidebwidth) * 2, self->bwidth);
918 XMapWindow(obp_display, self->handletop);
920 if (self->decorations & OB_FRAME_DECOR_GRIPS) {
921 XMoveResizeWindow(obp_display, self->handleleft,
922 theme_config.grip_width, 0, self->bwidth,
923 theme_config.handle_height);
924 XMoveResizeWindow(obp_display, self->handleright,
925 self->width - theme_config.grip_width
926 - self->bwidth, 0, self->bwidth,
927 theme_config.handle_height);
929 XMoveResizeWindow(obp_display, self->lgriptop, sidebwidth,
930 FRAME_HANDLE_Y(self), theme_config.grip_width + self->bwidth,
932 XMoveResizeWindow(obp_display, self->rgriptop,
933 self->size.left + self->client_area.width
934 + self->size.right - self->bwidth
935 - sidebwidth - theme_config.grip_width,
936 FRAME_HANDLE_Y(self), theme_config.grip_width
937 + self->bwidth, self->bwidth);
939 XMapWindow(obp_display, self->handleleft);
940 XMapWindow(obp_display, self->handleright);
941 XMapWindow(obp_display, self->lgriptop);
942 XMapWindow(obp_display, self->rgriptop);
945 XUnmapWindow(obp_display, self->handleleft);
946 XUnmapWindow(obp_display, self->handleright);
947 XUnmapWindow(obp_display, self->lgriptop);
948 XUnmapWindow(obp_display, self->rgriptop);
952 XUnmapWindow(obp_display, self->handleleft);
953 XUnmapWindow(obp_display, self->handleright);
954 XUnmapWindow(obp_display, self->lgriptop);
955 XUnmapWindow(obp_display, self->rgriptop);
957 XUnmapWindow(obp_display, self->handletop);
961 XUnmapWindow(obp_display, self->handleleft);
962 XUnmapWindow(obp_display, self->handleright);
963 XUnmapWindow(obp_display, self->lgriptop);
964 XUnmapWindow(obp_display, self->rgriptop);
966 XUnmapWindow(obp_display, self->handletop);
968 XUnmapWindow(obp_display, self->handlebottom);
969 XUnmapWindow(obp_display, self->lgripleft);
970 XUnmapWindow(obp_display, self->rgripright);
971 XUnmapWindow(obp_display, self->lgripbottom);
972 XUnmapWindow(obp_display, self->rgripbottom);
975 if (self->decorations & OB_FRAME_DECOR_HANDLE
976 && theme_config.handle_height > 0) {
977 XMoveResizeWindow(obp_display, self->handle, sidebwidth,
978 FRAME_HANDLE_Y(self) + self->bwidth, self->width,
979 theme_config.handle_height);
980 XMapWindow(obp_display, self->handle);
982 if (self->decorations & OB_FRAME_DECOR_GRIPS) {
983 XMoveResizeWindow(obp_display, self->lgrip, 0, 0,
984 theme_config.grip_width, theme_config.handle_height);
985 XMoveResizeWindow(obp_display, self->rgrip, self->width
986 - theme_config.grip_width, 0, theme_config.grip_width,
987 theme_config.handle_height);
989 XMapWindow(obp_display, self->lgrip);
990 XMapWindow(obp_display, self->rgrip);
993 XUnmapWindow(obp_display, self->lgrip);
994 XUnmapWindow(obp_display, self->rgrip);
998 XUnmapWindow(obp_display, self->lgrip);
999 XUnmapWindow(obp_display, self->rgrip);
1001 XUnmapWindow(obp_display, self->handle);
1004 if (self->bwidth && !self->max_horz && (self->client_area.height
1005 + self->size.top + self->size.bottom) > theme_config.grip_width
1007 XMoveResizeWindow(obp_display, self->left, 0, self->bwidth
1008 + theme_config.grip_width, self->bwidth,
1009 self->client_area.height + self->size.top
1010 + self->size.bottom - theme_config.grip_width * 2);
1012 XMapWindow(obp_display, self->left);
1015 XUnmapWindow(obp_display, self->left);
1017 if (self->bwidth && !self->max_horz && (self->client_area.height
1018 + self->size.top + self->size.bottom) > theme_config.grip_width
1020 XMoveResizeWindow(obp_display, self->right, self->client_area.width
1021 + self->cbwidth_l + self->cbwidth_r + self->bwidth,
1022 self->bwidth + theme_config.grip_width, self->bwidth,
1023 self->client_area.height + self->size.top
1024 + self->size.bottom - theme_config.grip_width * 2);
1026 XMapWindow(obp_display, self->right);
1029 XUnmapWindow(obp_display, self->right);
1031 XMoveResizeWindow(obp_display, self->backback, self->size.left,
1032 self->size.top, self->client_area.width,
1033 self->client_area.height);
1036 /* shading can change without being moved or resized */
1037 RECT_SET_SIZE(self->area, self->client_area.width + self->size.left
1038 + self->size.right, (self->shaded ? theme_config.title_height
1039 + self->bwidth * 2 : self->client_area.height + self->size.top
1040 + self->size.bottom));
1042 if ((is_resize) && !is_fake) {
1043 /* find the new coordinates, done after setting the frame.size, for
1044 frame_client_gravity. */
1045 self->area.x = self->client_area.x;
1046 self->area.y = self->client_area.y;
1047 frame_client_gravity(OBDEFAULTFRAME(_self)->client, &self->area.x, &self->area.y);
1051 /* move and resize the top level frame.
1052 shading can change without being moved or resized.
1053 but don't do this during an iconify animation. it will be
1054 reflected afterwards.
1056 XMoveResizeWindow(obp_display, self->window, self->area.x,
1057 self->area.y, self->area.width, self->area.height);
1059 /* when the client has StaticGravity, it likes to move around.
1060 also this correctly positions the client when it maps.
1061 this also needs to be run when the frame's decorations sizes change!
1064 XMoveResizeWindow(obp_display, self->client->w_client,
1065 self->size.left, self->size.top, self->client_area.width,
1066 self->client_area.height);
1069 self->need_render = TRUE;
1070 frame_update_skin(self);
1071 frame_adjust_shape(self);
1074 if (!STRUT_EQUAL(self->size, oldsize)) {
1076 vals[0] = self->size.left;
1077 vals[1] = self->size.right;
1078 vals[2] = self->size.top;
1079 vals[3] = self->size.bottom;
1080 OBT_PROP_SETA32(self->client->w_client, NET_FRAME_EXTENTS,
1082 OBT_PROP_SETA32(self->client->w_client, KDE_NET_WM_FRAME_STRUT,
1086 /* if this occurs while we are focus cycling, the indicator needs to
1087 match the changes */
1088 if (plugin.focus_cycle_target == self->client)
1089 focus_cycle_draw_indicator(self->client);
1091 if (is_resize && (self->decorations & OB_FRAME_DECOR_TITLEBAR))
1092 XResizeWindow(obp_display, self->label, self->label_width,
1093 theme_config.label_height);
1096 void frame_set_hover_flag(gpointer self, ObFrameButton button)
1098 if (OBDEFAULTFRAME(self)->hover_flag != button) {
1099 OBDEFAULTFRAME(self)->hover_flag = button;
1100 frame_update_skin(self);
1104 void frame_set_press_flag(gpointer self, ObFrameButton button)
1106 if (OBDEFAULTFRAME(self)->press_flag != button) {
1107 OBDEFAULTFRAME(self)->press_flag = button;
1108 frame_update_skin(self);
1112 Window frame_get_window(gpointer self)
1114 return OBDEFAULTFRAME(self)->window;
1117 void frame_get_size(gpointer self, Strut * s)
1119 memcpy(s, &(OBDEFAULTFRAME(self)->size), sizeof(Strut));
1122 gint frame_get_decorations(gpointer self)
1124 return OBDEFAULTFRAME(self)->decorations;
1127 void frame_update_title(gpointer self, const gchar * src)
1129 g_free(OBDEFAULTFRAME(self)->stitle);
1130 OBDEFAULTFRAME(self)->stitle = g_strdup(src);
1133 gboolean frame_is_visible(gpointer self)
1135 return OBDEFAULTFRAME(self)->visible;
1138 gboolean frame_is_max_horz(gpointer self)
1140 return OBDEFAULTFRAME(self)->max_horz;
1143 gboolean frame_is_max_vert(gpointer self)
1145 return OBDEFAULTFRAME(self)->max_vert;
1148 void frame_adjust_cursors(gpointer _self)
1150 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1151 if ((self->functions & OB_CLIENT_FUNC_RESIZE) != (self->functions
1152 & OB_CLIENT_FUNC_RESIZE) || self->max_horz != self->max_horz
1153 || self->max_vert != self->max_vert || self->shaded != self->shaded) {
1154 gboolean r = (self->functions & OB_CLIENT_FUNC_RESIZE)
1155 && !(self->max_horz && self->max_vert);
1156 gboolean topbot = !self->max_vert;
1157 gboolean sh = self->shaded;
1158 XSetWindowAttributes a;
1160 /* these ones turn off when max vert, and some when shaded */
1161 a.cursor = ob_cursor(r && topbot && !sh ? OB_CURSOR_NORTH
1163 XChangeWindowAttributes(obp_display, self->topresize, CWCursor, &a);
1164 XChangeWindowAttributes(obp_display, self->titletop, CWCursor, &a);
1165 a.cursor = ob_cursor(r && topbot ? OB_CURSOR_SOUTH : OB_CURSOR_NONE);
1166 XChangeWindowAttributes(obp_display, self->handle, CWCursor, &a);
1167 XChangeWindowAttributes(obp_display, self->handletop, CWCursor, &a);
1168 XChangeWindowAttributes(obp_display, self->handlebottom, CWCursor, &a);
1169 XChangeWindowAttributes(obp_display, self->innerbottom, CWCursor, &a);
1171 /* these ones change when shaded */
1172 a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_WEST : OB_CURSOR_NORTHWEST)
1174 XChangeWindowAttributes(obp_display, self->titleleft, CWCursor, &a);
1175 XChangeWindowAttributes(obp_display, self->tltresize, CWCursor, &a);
1176 XChangeWindowAttributes(obp_display, self->tllresize, CWCursor, &a);
1177 XChangeWindowAttributes(obp_display, self->titletopleft, CWCursor, &a);
1178 a.cursor = ob_cursor(r ? (sh ? OB_CURSOR_EAST : OB_CURSOR_NORTHEAST)
1180 XChangeWindowAttributes(obp_display, self->titleright, CWCursor, &a);
1181 XChangeWindowAttributes(obp_display, self->trtresize, CWCursor, &a);
1182 XChangeWindowAttributes(obp_display, self->trrresize, CWCursor, &a);
1183 XChangeWindowAttributes(obp_display, self->titletopright, CWCursor, &a);
1185 /* these ones are pretty static */
1186 a.cursor = ob_cursor(r ? OB_CURSOR_WEST : OB_CURSOR_NONE);
1187 XChangeWindowAttributes(obp_display, self->left, CWCursor, &a);
1188 XChangeWindowAttributes(obp_display, self->innerleft, CWCursor, &a);
1189 a.cursor = ob_cursor(r ? OB_CURSOR_EAST : OB_CURSOR_NONE);
1190 XChangeWindowAttributes(obp_display, self->right, CWCursor, &a);
1191 XChangeWindowAttributes(obp_display, self->innerright, CWCursor, &a);
1192 a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHWEST : OB_CURSOR_NONE);
1193 XChangeWindowAttributes(obp_display, self->lgrip, CWCursor, &a);
1194 XChangeWindowAttributes(obp_display, self->handleleft, CWCursor, &a);
1195 XChangeWindowAttributes(obp_display, self->lgripleft, CWCursor, &a);
1196 XChangeWindowAttributes(obp_display, self->lgriptop, CWCursor, &a);
1197 XChangeWindowAttributes(obp_display, self->lgripbottom, CWCursor, &a);
1198 XChangeWindowAttributes(obp_display, self->innerbll, CWCursor, &a);
1199 XChangeWindowAttributes(obp_display, self->innerblb, CWCursor, &a);
1200 a.cursor = ob_cursor(r ? OB_CURSOR_SOUTHEAST : OB_CURSOR_NONE);
1201 XChangeWindowAttributes(obp_display, self->rgrip, CWCursor, &a);
1202 XChangeWindowAttributes(obp_display, self->handleright, CWCursor, &a);
1203 XChangeWindowAttributes(obp_display, self->rgripright, CWCursor, &a);
1204 XChangeWindowAttributes(obp_display, self->rgriptop, CWCursor, &a);
1205 XChangeWindowAttributes(obp_display, self->rgripbottom, CWCursor, &a);
1206 XChangeWindowAttributes(obp_display, self->innerbrr, CWCursor, &a);
1207 XChangeWindowAttributes(obp_display, self->innerbrb, CWCursor, &a);
1211 void frame_adjust_client_area(gpointer _self)
1213 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1214 /* adjust the window which is there to prevent flashing on unmap */
1215 XMoveResizeWindow(obp_display, self->backfront, 0, 0,
1216 self->client_area.width, self->client_area.height);
1219 void frame_adjust_state(gpointer _self)
1221 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1222 self->need_render = TRUE;
1223 frame_update_skin(self);
1226 void frame_adjust_focus(gpointer _self, gboolean hilite)
1228 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1229 self->focused = hilite;
1230 self->need_render = TRUE;
1231 frame_update_skin(self);
1232 XFlush(obp_display);
1235 void frame_adjust_title(gpointer _self)
1237 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1238 self->need_render = TRUE;
1239 frame_update_skin(self);
1242 void frame_adjust_icon(gpointer _self)
1244 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1245 self->need_render = TRUE;
1246 frame_update_skin(self);
1249 /* is there anything present between us and the label? */
1250 static gboolean is_button_present(ObDefaultFrame *_self, const gchar *lc,
1253 ObDefaultFrame * self = (ObDefaultFrame *) _self;
1254 for (; *lc != '\0' && lc >= config_title_layout; lc += dir) {
1256 continue; /* it was invalid */
1257 if (*lc == 'N' && self->decorations & OB_FRAME_DECOR_ICON)
1259 if (*lc == 'D' && self->decorations & OB_FRAME_DECOR_ALLDESKTOPS)
1261 if (*lc == 'S' && self->decorations & OB_FRAME_DECOR_SHADE)
1263 if (*lc == 'I' && self->decorations & OB_FRAME_DECOR_ICONIFY)
1265 if (*lc == 'M' && self->decorations & OB_FRAME_DECOR_MAXIMIZE)
1267 if (*lc == 'C' && self->decorations & OB_FRAME_DECOR_CLOSE)
1275 void layout_title(ObDefaultFrame * self)
1280 const gint bwidth = theme_config.button_size + theme_config.paddingx + 1;
1281 /* position of the left most button */
1282 const gint left = theme_config.paddingx + 1;
1283 /* position of the right most button */
1284 const gint right = self->width;
1286 /* turn them all off */
1287 self->icon_on = self->desk_on = self->shade_on = self->iconify_on
1288 = self->max_on = self->close_on = self->label_on = FALSE;
1289 self->label_width = self->width - (theme_config.paddingx + 1) * 2;
1290 self->leftmost = self->rightmost = OB_FRAME_CONTEXT_NONE;
1292 /* figure out what's being show, find each element's position, and the
1295 do the ones before the label, then after the label,
1296 i will be +1 the first time through when working to the left,
1297 and -1 the second time through when working to the right */
1298 for (i = 1; i >= -1; i-=2) {
1300 ObFrameContext *firstcon;
1304 lc = config_title_layout;
1305 firstcon = &self->leftmost;
1309 lc = config_title_layout
1310 + strlen(config_title_layout)-1;
1311 firstcon = &self->rightmost;
1314 /* stop at the end of the string (or the label, which calls break) */
1315 for (; *lc != '\0' && lc >= config_title_layout; lc+=i) {
1318 self->label_on = TRUE;
1321 break; /* break the for loop, do other side of label */
1323 else if (*lc == 'N') {
1325 *firstcon = OB_FRAME_CONTEXT_ICON;
1326 if ((self->icon_on = is_button_present(self, lc, i))) {
1327 /* icon is bigger than buttons */
1328 self->label_width -= bwidth + 2;
1331 x += i * (bwidth + 2);
1336 else if (*lc == 'D') {
1338 *firstcon = OB_FRAME_CONTEXT_ALLDESKTOPS;
1339 if ((self->desk_on = is_button_present(self, lc, i))) {
1340 self->label_width -= bwidth;
1348 else if (*lc == 'S') {
1350 *firstcon = OB_FRAME_CONTEXT_SHADE;
1351 if ((self->shade_on = is_button_present(self, lc, i))) {
1352 self->label_width -= bwidth;
1360 else if (*lc == 'I') {
1362 *firstcon = OB_FRAME_CONTEXT_ICONIFY;
1363 if ((self->iconify_on = is_button_present(self, lc, i))) {
1364 self->label_width -= bwidth;
1366 self->iconify_x = x;
1369 self->iconify_x = x;
1372 else if (*lc == 'M') {
1374 *firstcon = OB_FRAME_CONTEXT_MAXIMIZE;
1375 if ((self->max_on = is_button_present(self, lc, i))) {
1376 self->label_width -= bwidth;
1384 else if (*lc == 'C') {
1386 *firstcon = OB_FRAME_CONTEXT_CLOSE;
1387 if ((self->close_on = is_button_present(self, lc, i))) {
1388 self->label_width -= bwidth;
1397 continue; /* don't set firstcon */
1402 /* position and map the elements */
1403 if (self->icon_on) {
1404 XMapWindow(obp_display, self->icon);
1405 XMoveWindow(obp_display, self->icon, self->icon_x,
1406 theme_config.paddingy);
1409 XUnmapWindow(obp_display, self->icon);
1411 if (self->desk_on) {
1412 XMapWindow(obp_display, self->desk);
1413 XMoveWindow(obp_display, self->desk, self->desk_x,
1414 theme_config.paddingy + 1);
1417 XUnmapWindow(obp_display, self->desk);
1419 if (self->shade_on) {
1420 XMapWindow(obp_display, self->shade);
1421 XMoveWindow(obp_display, self->shade, self->shade_x,
1422 theme_config.paddingy + 1);
1425 XUnmapWindow(obp_display, self->shade);
1427 if (self->iconify_on) {
1428 XMapWindow(obp_display, self->iconify);
1429 XMoveWindow(obp_display, self->iconify, self->iconify_x,
1430 theme_config.paddingy + 1);
1433 XUnmapWindow(obp_display, self->iconify);
1436 XMapWindow(obp_display, self->max);
1437 XMoveWindow(obp_display, self->max, self->max_x, theme_config.paddingy
1441 XUnmapWindow(obp_display, self->max);
1443 if (self->close_on) {
1444 XMapWindow(obp_display, self->close);
1445 XMoveWindow(obp_display, self->close, self->close_x,
1446 theme_config.paddingy + 1);
1449 XUnmapWindow(obp_display, self->close);
1451 if (self->label_on) {
1452 self->label_width = MAX(1, self->label_width); /* no lower than 1 */
1453 XMapWindow(obp_display, self->label);
1454 XMoveWindow(obp_display, self->label, self->label_x,
1455 theme_config.paddingy);
1458 XUnmapWindow(obp_display, self->label);
1461 void trigger_none(gpointer self)
1464 void trigger_iconify(gpointer self)
1467 void trigger_uniconnity(gpointer self)
1470 void trigger_iconify_toggle(gpointer self)
1473 void trigger_shade(gpointer self)
1476 void trigger_unshade(gpointer self)
1479 void trigger_shade_toggle(gpointer self)
1482 void trigger_max(gpointer self)
1485 void trigger_unmax(gpointer self)
1488 void trigger_max_troggle(gpointer self)
1491 void trigger_max_vert(gpointer self)
1493 OBDEFAULTFRAME(self)->max_vert = TRUE;
1495 void trigger_unmax_vert(gpointer self)
1497 OBDEFAULTFRAME(self)->max_vert = FALSE;
1499 void trigger_max_toggle(gpointer self)
1502 void trigger_max_horz(gpointer self)
1504 OBDEFAULTFRAME(self)->max_horz = TRUE;
1506 void trigger_unmax_horz(gpointer self)
1508 OBDEFAULTFRAME(self)->max_horz = FALSE;
1510 void trigger_max_horz_toggle(gpointer self)
1513 void trigger_plugin1(gpointer self)
1516 void trigger_plugin2(gpointer self)
1519 void trigger_plugin3(gpointer self)
1522 void trigger_plugin4(gpointer self)
1525 void trigger_plugin5(gpointer self)
1528 void trigger_plugin6(gpointer self)
1531 void trigger_plugin7(gpointer self)
1534 void trigger_plugin8(gpointer self)
1537 void trigger_plugin9(gpointer self)
1541 void frame_trigger(gpointer self, ObFrameTrigger trigger_name)
1544 static void (*trigger_func[64])(gpointer) = { trigger_none,
1545 trigger_iconify, trigger_uniconnity, trigger_iconify_toggle,
1546 trigger_shade, trigger_unshade, trigger_shade_toggle,
1547 trigger_max, trigger_unmax, trigger_max_troggle,
1548 trigger_max_vert, trigger_unmax_vert, trigger_max_toggle,
1549 trigger_max_horz, trigger_unmax_horz,
1550 trigger_max_horz_toggle, trigger_plugin1, trigger_plugin2,
1551 trigger_plugin3, trigger_plugin4, trigger_plugin5,
1552 trigger_plugin6, trigger_plugin7, trigger_plugin8,
1553 trigger_plugin9, NULL,
1556 void (*call_trigger_func)(gpointer) = trigger_func[trigger_name];
1557 if(!call_trigger_func)
1559 call_trigger_func (self);
1563 ObFrameEngine plugin = {
1564 0, /* gpointer handler */
1565 "libdefault.la", /* gchar * filename */
1566 "Default", /* gchar * name */
1567 init, //gint (*init) (Display * display, gint screen);
1569 frame_new, //gpointer (*frame_new) (struct _ObClient *c);
1570 frame_free, //void (*frame_free) (gpointer self);
1571 frame_adjust_theme, //void (*frame_adjust_theme) (gpointer self);
1572 frame_adjust_shape, //void (*frame_adjust_shape) (gpointer self);
1573 frame_grab, //void (*frame_adjust_area) (gpointer self, gboolean moved, gboolean resized, gboolean fake);
1575 frame_context, //void (*frame_adjust_state) (gpointer self);
1576 frame_set_is_visible, /* */
1577 frame_set_is_focus, /* */
1578 frame_set_is_max_vert, /* */
1579 frame_set_is_max_horz, /* */
1580 frame_set_is_shaded, /* */
1581 0, //frame_flash_start, /* */
1582 0, //frame_flash_stop, /* */
1583 frame_set_decorations, /* */
1584 frame_update_title, /* */
1585 /* This give the window area */
1586 frame_get_window_area, /* */
1587 frame_set_client_area, /* */
1588 /* Draw the frame */
1589 frame_update_layout, /* */
1590 frame_update_skin, /* */
1591 frame_set_hover_flag, /* */
1592 frame_set_press_flag, /* */
1593 frame_get_size, /* */
1594 frame_get_decorations, /* */
1595 frame_is_visible, /* */
1596 frame_is_max_horz, /* */
1597 frame_is_max_vert, /* */
1598 frame_trigger, /* */
1599 load_theme_config, /* */
1600 /* This fields are fill by openbox. */
1601 0, /*struct _ObClient *focus_cycle_target; */
1602 FALSE, /*gboolean moveresize_in_progress;*/
1605 ObFrameEngine * get_info()
1610 gboolean flash_timeout(gpointer data)