4 #include "extensions.h"
6 #include "framerender.h"
7 #include "render/theme.h"
9 #define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
10 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
11 ButtonPressMask | ButtonReleaseMask)
12 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
13 ButtonMotionMask | ExposureMask | \
14 EnterWindowMask | LeaveWindowMask)
16 #define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
19 static void layout_title(ObFrame
*self
);
21 static Window
createWindow(Window parent
, unsigned long mask
,
22 XSetWindowAttributes
*attrib
)
24 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
25 RrDepth(ob_rr_inst
), InputOutput
,
26 RrVisual(ob_rr_inst
), mask
, attrib
);
32 XSetWindowAttributes attrib
;
36 self
= g_new(ObFrame
, 1);
38 self
->visible
= FALSE
;
39 self
->decorations
= 0;
41 /* create all of the decor windows */
42 mask
= CWOverrideRedirect
| CWEventMask
;
43 attrib
.event_mask
= FRAME_EVENTMASK
;
44 attrib
.override_redirect
= TRUE
;
45 self
->window
= createWindow(RootWindow(ob_display
, ob_screen
),
49 self
->plate
= createWindow(self
->window
, mask
, &attrib
);
52 attrib
.event_mask
= ELEMENT_EVENTMASK
;
53 self
->title
= createWindow(self
->window
, mask
, &attrib
);
56 attrib
.cursor
= ob_cursor(OB_CURSOR_NORTHWEST
);
57 self
->tlresize
= createWindow(self
->title
, mask
, &attrib
);
58 attrib
.cursor
= ob_cursor(OB_CURSOR_NORTHEAST
);
59 self
->trresize
= createWindow(self
->title
, mask
, &attrib
);
62 self
->label
= createWindow(self
->title
, mask
, &attrib
);
63 self
->max
= createWindow(self
->title
, mask
, &attrib
);
64 self
->close
= createWindow(self
->title
, mask
, &attrib
);
65 self
->desk
= createWindow(self
->title
, mask
, &attrib
);
66 self
->shade
= createWindow(self
->title
, mask
, &attrib
);
67 self
->icon
= createWindow(self
->title
, mask
, &attrib
);
68 self
->iconify
= createWindow(self
->title
, mask
, &attrib
);
69 self
->handle
= createWindow(self
->window
, mask
, &attrib
);
72 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHWEST
);
73 self
->lgrip
= createWindow(self
->handle
, mask
, &attrib
);
74 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHEAST
);
75 self
->rgrip
= createWindow(self
->handle
, mask
, &attrib
);
77 self
->focused
= FALSE
;
79 /* the other stuff is shown based on decor settings */
80 XMapWindow(ob_display
, self
->plate
);
81 XMapWindow(ob_display
, self
->lgrip
);
82 XMapWindow(ob_display
, self
->rgrip
);
83 XMapWindow(ob_display
, self
->label
);
84 XMapWindow(ob_display
, self
->tlresize
);
85 XMapWindow(ob_display
, self
->trresize
);
87 /* set colors/appearance/sizes for stuff that doesn't change */
88 XSetWindowBorder(ob_display
, self
->window
, ob_rr_theme
->b_color
->pixel
);
89 XSetWindowBorder(ob_display
, self
->title
, ob_rr_theme
->b_color
->pixel
);
90 XSetWindowBorder(ob_display
, self
->handle
, ob_rr_theme
->b_color
->pixel
);
91 XSetWindowBorder(ob_display
, self
->rgrip
, ob_rr_theme
->b_color
->pixel
);
92 XSetWindowBorder(ob_display
, self
->lgrip
, ob_rr_theme
->b_color
->pixel
);
94 XResizeWindow(ob_display
, self
->max
,
95 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
96 XResizeWindow(ob_display
, self
->iconify
,
97 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
98 XResizeWindow(ob_display
, self
->icon
,
99 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
100 XResizeWindow(ob_display
, self
->close
,
101 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
102 XResizeWindow(ob_display
, self
->desk
,
103 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
104 XResizeWindow(ob_display
, self
->shade
,
105 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
106 XResizeWindow(ob_display
, self
->lgrip
,
107 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
108 XResizeWindow(ob_display
, self
->rgrip
,
109 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
110 XResizeWindow(ob_display
, self
->tlresize
,
111 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
112 XResizeWindow(ob_display
, self
->trresize
,
113 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
115 /* set up the dynamic appearances */
116 self
->a_unfocused_title
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_title
);
117 self
->a_focused_title
= RrAppearanceCopy(ob_rr_theme
->a_focused_title
);
118 self
->a_unfocused_label
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_label
);
119 self
->a_focused_label
= RrAppearanceCopy(ob_rr_theme
->a_focused_label
);
120 self
->a_unfocused_handle
=
121 RrAppearanceCopy(ob_rr_theme
->a_unfocused_handle
);
122 self
->a_focused_handle
= RrAppearanceCopy(ob_rr_theme
->a_focused_handle
);
123 self
->a_icon
= RrAppearanceCopy(ob_rr_theme
->a_icon
);
125 self
->max_press
= self
->close_press
= self
->desk_press
=
126 self
->iconify_press
= self
->shade_press
= FALSE
;
127 self
->max_hover
= self
->close_hover
= self
->desk_hover
=
128 self
->iconify_hover
= self
->shade_hover
= FALSE
;
130 return (ObFrame
*)self
;
133 static void frame_free(ObFrame
*self
)
135 RrAppearanceFree(self
->a_unfocused_title
);
136 RrAppearanceFree(self
->a_focused_title
);
137 RrAppearanceFree(self
->a_unfocused_label
);
138 RrAppearanceFree(self
->a_focused_label
);
139 RrAppearanceFree(self
->a_unfocused_handle
);
140 RrAppearanceFree(self
->a_focused_handle
);
141 RrAppearanceFree(self
->a_icon
);
143 XDestroyWindow(ob_display
, self
->window
);
148 void frame_show(ObFrame
*self
)
150 if (!self
->visible
) {
151 self
->visible
= TRUE
;
152 XMapWindow(ob_display
, self
->window
);
156 void frame_hide(ObFrame
*self
)
159 self
->visible
= FALSE
;
160 self
->client
->ignore_unmaps
++;
161 XUnmapWindow(ob_display
, self
->window
);
165 void frame_adjust_shape(ObFrame
*self
)
171 if (!self
->client
->shaped
) {
172 /* clear the shape on the frame window */
173 XShapeCombineMask(ob_display
, self
->window
, ShapeBounding
,
174 self
->innersize
.left
,
178 /* make the frame's shape match the clients */
179 XShapeCombineShape(ob_display
, self
->window
, ShapeBounding
,
180 self
->innersize
.left
,
182 self
->client
->window
,
183 ShapeBounding
, ShapeSet
);
186 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
187 xrect
[0].x
= -ob_rr_theme
->bwidth
;
188 xrect
[0].y
= -ob_rr_theme
->bwidth
;
189 xrect
[0].width
= self
->width
+ self
->rbwidth
* 2;
190 xrect
[0].height
= ob_rr_theme
->title_height
+
195 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
196 xrect
[1].x
= -ob_rr_theme
->bwidth
;
197 xrect
[1].y
= FRAME_HANDLE_Y(self
);
198 xrect
[1].width
= self
->width
+ self
->rbwidth
* 2;
199 xrect
[1].height
= ob_rr_theme
->handle_height
+
204 XShapeCombineRectangles(ob_display
, self
->window
,
205 ShapeBounding
, 0, 0, xrect
, num
,
206 ShapeUnion
, Unsorted
);
211 void frame_adjust_area(ObFrame
*self
, gboolean moved
,
212 gboolean resized
, gboolean fake
)
215 self
->decorations
= self
->client
->decorations
;
217 if (self
->decorations
& OB_FRAME_DECOR_BORDER
) {
218 self
->bwidth
= ob_rr_theme
->bwidth
;
219 self
->cbwidth_x
= self
->cbwidth_y
= ob_rr_theme
->cbwidth
;
221 self
->bwidth
= self
->cbwidth_x
= self
->cbwidth_y
= 0;
223 self
->rbwidth
= self
->bwidth
;
225 if (self
->client
->max_vert
&& self
->client
->max_horz
)
226 self
->decorations
&= ~OB_FRAME_DECOR_HANDLE
;
228 if (self
->client
->max_horz
)
229 self
->bwidth
= self
->cbwidth_x
= 0;
231 STRUT_SET(self
->innersize
,
236 self
->width
= self
->client
->area
.width
+ self
->cbwidth_x
* 2 -
237 (self
->client
->max_horz
? self
->rbwidth
* 2 : 0);
238 self
->width
= MAX(self
->width
, 1); /* no lower than 1 */
240 /* set border widths */
242 XSetWindowBorderWidth(ob_display
, self
->window
, self
->bwidth
);
243 XSetWindowBorderWidth(ob_display
, self
->title
, self
->rbwidth
);
244 XSetWindowBorderWidth(ob_display
, self
->handle
, self
->rbwidth
);
245 XSetWindowBorderWidth(ob_display
, self
->lgrip
, self
->rbwidth
);
246 XSetWindowBorderWidth(ob_display
, self
->rgrip
, self
->rbwidth
);
249 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
)
250 self
->innersize
.top
+= ob_rr_theme
->title_height
+ self
->rbwidth
+
251 (self
->rbwidth
- self
->bwidth
);
252 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
)
253 self
->innersize
.bottom
+= ob_rr_theme
->handle_height
+
254 self
->rbwidth
+ (self
->rbwidth
- self
->bwidth
);
256 /* they all default off, they're turned on in layout_title */
260 self
->iconify_x
= -1;
265 /* position/size and map/unmap all the windows */
268 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
269 XMoveResizeWindow(ob_display
, self
->title
,
270 -self
->bwidth
, -self
->bwidth
,
271 self
->width
, ob_rr_theme
->title_height
);
272 XMapWindow(ob_display
, self
->title
);
274 XMoveWindow(ob_display
, self
->tlresize
, 0, 0);
275 XMoveWindow(ob_display
, self
->trresize
,
276 self
->width
- ob_rr_theme
->grip_width
, 0);
279 XUnmapWindow(ob_display
, self
->title
);
282 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
)
283 /* layout the title bar elements */
287 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
288 XMoveResizeWindow(ob_display
, self
->handle
,
289 -self
->bwidth
, FRAME_HANDLE_Y(self
),
290 self
->width
, ob_rr_theme
->handle_height
);
291 XMapWindow(ob_display
, self
->handle
);
293 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
294 XMoveWindow(ob_display
, self
->lgrip
,
295 -self
->rbwidth
, -self
->rbwidth
);
296 XMoveWindow(ob_display
, self
->rgrip
,
297 -self
->rbwidth
+ self
->width
-
298 ob_rr_theme
->grip_width
, -self
->rbwidth
);
299 XMapWindow(ob_display
, self
->lgrip
);
300 XMapWindow(ob_display
, self
->rgrip
);
302 XUnmapWindow(ob_display
, self
->lgrip
);
303 XUnmapWindow(ob_display
, self
->rgrip
);
306 /* XXX make a subwindow with these dimentions?
307 ob_rr_theme->grip_width + self->bwidth, 0,
308 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
309 ob_rr_theme->handle_height);
312 XUnmapWindow(ob_display
, self
->handle
);
314 /* move and resize the plate */
315 XMoveResizeWindow(ob_display
, self
->plate
,
316 self
->innersize
.left
- self
->cbwidth_x
,
317 self
->innersize
.top
- self
->cbwidth_y
,
318 self
->client
->area
.width
+ self
->cbwidth_x
* 2,
319 self
->client
->area
.height
+ self
->cbwidth_y
* 2);
320 /* when the client has StaticGravity, it likes to move around. */
321 XMoveWindow(ob_display
, self
->client
->window
,
322 self
->cbwidth_x
, self
->cbwidth_y
);
325 STRUT_SET(self
->size
,
326 self
->innersize
.left
+ self
->bwidth
,
327 self
->innersize
.top
+ self
->bwidth
,
328 self
->innersize
.right
+ self
->bwidth
,
329 self
->innersize
.bottom
+ self
->bwidth
);
332 /* shading can change without being moved or resized */
333 RECT_SET_SIZE(self
->area
,
334 self
->client
->area
.width
+
335 self
->size
.left
+ self
->size
.right
,
336 (self
->client
->shaded
?
337 ob_rr_theme
->title_height
+ self
->bwidth
*2:
338 self
->client
->area
.height
+
339 self
->size
.top
+ self
->size
.bottom
));
342 /* find the new coordinates, done after setting the frame.size, for
343 frame_client_gravity. */
344 self
->area
.x
= self
->client
->area
.x
;
345 self
->area
.y
= self
->client
->area
.y
;
346 frame_client_gravity(self
, &self
->area
.x
, &self
->area
.y
);
350 /* move and resize the top level frame.
351 shading can change without being moved or resized */
352 XMoveResizeWindow(ob_display
, self
->window
,
353 self
->area
.x
, self
->area
.y
,
354 self
->area
.width
- self
->bwidth
* 2,
355 self
->area
.height
- self
->bwidth
* 2);
358 framerender_frame(self
);
360 frame_adjust_shape(self
);
365 void frame_adjust_state(ObFrame
*self
)
367 framerender_frame(self
);
370 void frame_adjust_focus(ObFrame
*self
, gboolean hilite
)
372 self
->focused
= hilite
;
373 framerender_frame(self
);
376 void frame_adjust_title(ObFrame
*self
)
378 framerender_frame(self
);
381 void frame_adjust_icon(ObFrame
*self
)
383 framerender_frame(self
);
386 void frame_grab_client(ObFrame
*self
, ObClient
*client
)
388 self
->client
= client
;
390 /* reparent the client to the frame */
391 XReparentWindow(ob_display
, client
->window
, self
->plate
, 0, 0);
393 When reparenting the client window, it is usually not mapped yet, since
394 this occurs from a MapRequest. However, in the case where Openbox is
395 starting up, the window is already mapped, so we'll see unmap events for
396 it. There are 2 unmap events generated that we see, one with the 'event'
397 member set the root window, and one set to the client, but both get
398 handled and need to be ignored.
400 if (ob_state() == OB_STATE_STARTING
)
401 client
->ignore_unmaps
+= 2;
403 /* select the event mask on the client's parent (to receive config/map
404 req's) the ButtonPress is to catch clicks on the client border */
405 XSelectInput(ob_display
, self
->plate
, PLATE_EVENTMASK
);
407 /* map the client so it maps when the frame does */
408 XMapWindow(ob_display
, client
->window
);
410 frame_adjust_area(self
, TRUE
, TRUE
, FALSE
);
412 /* set all the windows for the frame in the window_map */
413 g_hash_table_insert(window_map
, &self
->window
, client
);
414 g_hash_table_insert(window_map
, &self
->plate
, client
);
415 g_hash_table_insert(window_map
, &self
->title
, client
);
416 g_hash_table_insert(window_map
, &self
->label
, client
);
417 g_hash_table_insert(window_map
, &self
->max
, client
);
418 g_hash_table_insert(window_map
, &self
->close
, client
);
419 g_hash_table_insert(window_map
, &self
->desk
, client
);
420 g_hash_table_insert(window_map
, &self
->shade
, client
);
421 g_hash_table_insert(window_map
, &self
->icon
, client
);
422 g_hash_table_insert(window_map
, &self
->iconify
, client
);
423 g_hash_table_insert(window_map
, &self
->handle
, client
);
424 g_hash_table_insert(window_map
, &self
->lgrip
, client
);
425 g_hash_table_insert(window_map
, &self
->rgrip
, client
);
426 g_hash_table_insert(window_map
, &self
->tlresize
, client
);
427 g_hash_table_insert(window_map
, &self
->trresize
, client
);
430 void frame_release_client(ObFrame
*self
, ObClient
*client
)
434 g_assert(self
->client
== client
);
436 /* check if the app has already reparented its window away */
437 if (XCheckTypedWindowEvent(ob_display
, client
->window
,
438 ReparentNotify
, &ev
)) {
439 XPutBackEvent(ob_display
, &ev
);
441 /* re-map the window since the unmanaging process unmaps it */
443 /* XXX ... um no it doesnt it unmaps its parent, the window itself
444 retains its mapped state, no?! XXX
445 XMapWindow(ob_display, client->window); */
447 /* according to the ICCCM - if the client doesn't reparent itself,
448 then we will reparent the window to root for them */
449 XReparentWindow(ob_display
, client
->window
,
450 RootWindow(ob_display
, ob_screen
),
455 /* remove all the windows for the frame from the window_map */
456 g_hash_table_remove(window_map
, &self
->window
);
457 g_hash_table_remove(window_map
, &self
->plate
);
458 g_hash_table_remove(window_map
, &self
->title
);
459 g_hash_table_remove(window_map
, &self
->label
);
460 g_hash_table_remove(window_map
, &self
->max
);
461 g_hash_table_remove(window_map
, &self
->close
);
462 g_hash_table_remove(window_map
, &self
->desk
);
463 g_hash_table_remove(window_map
, &self
->shade
);
464 g_hash_table_remove(window_map
, &self
->icon
);
465 g_hash_table_remove(window_map
, &self
->iconify
);
466 g_hash_table_remove(window_map
, &self
->handle
);
467 g_hash_table_remove(window_map
, &self
->lgrip
);
468 g_hash_table_remove(window_map
, &self
->rgrip
);
469 g_hash_table_remove(window_map
, &self
->tlresize
);
470 g_hash_table_remove(window_map
, &self
->trresize
);
475 static void layout_title(ObFrame
*self
)
479 gboolean n
, d
, i
, l
, m
, c
, s
;
481 n
= d
= i
= l
= m
= c
= s
= FALSE
;
483 /* figure out whats being shown, and the width of the label */
484 self
->label_width
= self
->width
- (ob_rr_theme
->bevel
+ 1) * 2;
485 for (lc
= config_title_layout
; *lc
!= '\0'; ++lc
) {
488 if (n
) { *lc
= ' '; break; } /* rm duplicates */
490 self
->label_width
-= (ob_rr_theme
->button_size
+ 2 +
491 ob_rr_theme
->bevel
+ 1);
494 if (d
) { *lc
= ' '; break; } /* rm duplicates */
496 self
->label_width
-= (ob_rr_theme
->button_size
+
497 ob_rr_theme
->bevel
+ 1);
500 if (s
) { *lc
= ' '; break; } /* rm duplicates */
502 self
->label_width
-= (ob_rr_theme
->button_size
+
503 ob_rr_theme
->bevel
+ 1);
506 if (i
) { *lc
= ' '; break; } /* rm duplicates */
508 self
->label_width
-= (ob_rr_theme
->button_size
+
509 ob_rr_theme
->bevel
+ 1);
512 if (l
) { *lc
= ' '; break; } /* rm duplicates */
516 if (m
) { *lc
= ' '; break; } /* rm duplicates */
518 self
->label_width
-= (ob_rr_theme
->button_size
+
519 ob_rr_theme
->bevel
+ 1);
522 if (c
) { *lc
= ' '; break; } /* rm duplicates */
524 self
->label_width
-= (ob_rr_theme
->button_size
+
525 ob_rr_theme
->bevel
+ 1);
529 if (self
->label_width
< 1) self
->label_width
= 1;
531 XResizeWindow(ob_display
, self
->label
, self
->label_width
,
532 ob_rr_theme
->label_height
);
534 if (!n
) XUnmapWindow(ob_display
, self
->icon
);
535 if (!d
) XUnmapWindow(ob_display
, self
->desk
);
536 if (!s
) XUnmapWindow(ob_display
, self
->shade
);
537 if (!i
) XUnmapWindow(ob_display
, self
->iconify
);
538 if (!l
) XUnmapWindow(ob_display
, self
->label
);
539 if (!m
) XUnmapWindow(ob_display
, self
->max
);
540 if (!c
) XUnmapWindow(ob_display
, self
->close
);
542 x
= ob_rr_theme
->bevel
+ 1;
543 for (lc
= config_title_layout
; *lc
!= '\0'; ++lc
) {
548 XMapWindow(ob_display
, self
->icon
);
549 XMoveWindow(ob_display
, self
->icon
, x
, ob_rr_theme
->bevel
);
550 x
+= ob_rr_theme
->button_size
+ 2 + ob_rr_theme
->bevel
+ 1;
555 XMapWindow(ob_display
, self
->desk
);
556 XMoveWindow(ob_display
, self
->desk
, x
, ob_rr_theme
->bevel
+ 1);
557 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
562 XMapWindow(ob_display
, self
->shade
);
563 XMoveWindow(ob_display
, self
->shade
, x
, ob_rr_theme
->bevel
+ 1);
564 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
569 XMapWindow(ob_display
, self
->iconify
);
570 XMoveWindow(ob_display
, self
->iconify
, x
, ob_rr_theme
->bevel
+ 1);
571 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
576 XMapWindow(ob_display
, self
->label
);
577 XMoveWindow(ob_display
, self
->label
, x
, ob_rr_theme
->bevel
);
578 x
+= self
->label_width
+ ob_rr_theme
->bevel
+ 1;
583 XMapWindow(ob_display
, self
->max
);
584 XMoveWindow(ob_display
, self
->max
, x
, ob_rr_theme
->bevel
+ 1);
585 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
590 XMapWindow(ob_display
, self
->close
);
591 XMoveWindow(ob_display
, self
->close
, x
, ob_rr_theme
->bevel
+ 1);
592 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
598 ObFrameContext
frame_context_from_string(char *name
)
600 if (!g_ascii_strcasecmp("root", name
))
601 return OB_FRAME_CONTEXT_ROOT
;
602 else if (!g_ascii_strcasecmp("client", name
))
603 return OB_FRAME_CONTEXT_CLIENT
;
604 else if (!g_ascii_strcasecmp("titlebar", name
))
605 return OB_FRAME_CONTEXT_TITLEBAR
;
606 else if (!g_ascii_strcasecmp("handle", name
))
607 return OB_FRAME_CONTEXT_HANDLE
;
608 else if (!g_ascii_strcasecmp("frame", name
))
609 return OB_FRAME_CONTEXT_FRAME
;
610 else if (!g_ascii_strcasecmp("tlcorner", name
))
611 return OB_FRAME_CONTEXT_TLCORNER
;
612 else if (!g_ascii_strcasecmp("trcorner", name
))
613 return OB_FRAME_CONTEXT_TRCORNER
;
614 else if (!g_ascii_strcasecmp("blcorner", name
))
615 return OB_FRAME_CONTEXT_BLCORNER
;
616 else if (!g_ascii_strcasecmp("brcorner", name
))
617 return OB_FRAME_CONTEXT_BRCORNER
;
618 else if (!g_ascii_strcasecmp("maximize", name
))
619 return OB_FRAME_CONTEXT_MAXIMIZE
;
620 else if (!g_ascii_strcasecmp("alldesktops", name
))
621 return OB_FRAME_CONTEXT_ALLDESKTOPS
;
622 else if (!g_ascii_strcasecmp("shade", name
))
623 return OB_FRAME_CONTEXT_SHADE
;
624 else if (!g_ascii_strcasecmp("iconify", name
))
625 return OB_FRAME_CONTEXT_ICONIFY
;
626 else if (!g_ascii_strcasecmp("icon", name
))
627 return OB_FRAME_CONTEXT_ICON
;
628 else if (!g_ascii_strcasecmp("close", name
))
629 return OB_FRAME_CONTEXT_CLOSE
;
630 return OB_FRAME_CONTEXT_NONE
;
633 ObFrameContext
frame_context(ObClient
*client
, Window win
)
637 if (win
== RootWindow(ob_display
, ob_screen
)) return OB_FRAME_CONTEXT_ROOT
;
638 if (client
== NULL
) return OB_FRAME_CONTEXT_NONE
;
639 if (win
== client
->window
) return OB_FRAME_CONTEXT_CLIENT
;
641 self
= client
->frame
;
642 if (win
== self
->window
) return OB_FRAME_CONTEXT_FRAME
;
643 if (win
== self
->plate
) return OB_FRAME_CONTEXT_CLIENT
;
644 if (win
== self
->title
) return OB_FRAME_CONTEXT_TITLEBAR
;
645 if (win
== self
->label
) return OB_FRAME_CONTEXT_TITLEBAR
;
646 if (win
== self
->handle
) return OB_FRAME_CONTEXT_HANDLE
;
647 if (win
== self
->lgrip
) return OB_FRAME_CONTEXT_BLCORNER
;
648 if (win
== self
->rgrip
) return OB_FRAME_CONTEXT_BRCORNER
;
649 if (win
== self
->tlresize
) return OB_FRAME_CONTEXT_TLCORNER
;
650 if (win
== self
->trresize
) return OB_FRAME_CONTEXT_TRCORNER
;
651 if (win
== self
->max
) return OB_FRAME_CONTEXT_MAXIMIZE
;
652 if (win
== self
->iconify
) return OB_FRAME_CONTEXT_ICONIFY
;
653 if (win
== self
->close
) return OB_FRAME_CONTEXT_CLOSE
;
654 if (win
== self
->icon
) return OB_FRAME_CONTEXT_ICON
;
655 if (win
== self
->desk
) return OB_FRAME_CONTEXT_ALLDESKTOPS
;
656 if (win
== self
->shade
) return OB_FRAME_CONTEXT_SHADE
;
658 return OB_FRAME_CONTEXT_NONE
;
661 void frame_client_gravity(ObFrame
*self
, int *x
, int *y
)
664 switch (self
->client
->gravity
) {
666 case NorthWestGravity
:
667 case SouthWestGravity
:
674 *x
-= (self
->size
.left
+ self
->size
.right
) / 2;
677 case NorthEastGravity
:
678 case SouthEastGravity
:
680 *x
-= self
->size
.left
+ self
->size
.right
;
685 *x
-= self
->size
.left
;
690 switch (self
->client
->gravity
) {
692 case NorthWestGravity
:
693 case NorthEastGravity
:
700 *y
-= (self
->size
.top
+ self
->size
.bottom
) / 2;
703 case SouthWestGravity
:
704 case SouthEastGravity
:
706 *y
-= self
->size
.top
+ self
->size
.bottom
;
711 *y
-= self
->size
.top
;
716 void frame_frame_gravity(ObFrame
*self
, int *x
, int *y
)
719 switch (self
->client
->gravity
) {
721 case NorthWestGravity
:
723 case SouthWestGravity
:
728 *x
+= (self
->size
.left
+ self
->size
.right
) / 2;
730 case NorthEastGravity
:
732 case SouthEastGravity
:
733 *x
+= self
->size
.left
+ self
->size
.right
;
737 *x
+= self
->size
.left
;
742 switch (self
->client
->gravity
) {
744 case NorthWestGravity
:
746 case NorthEastGravity
:
751 *y
+= (self
->size
.top
+ self
->size
.bottom
) / 2;
753 case SouthWestGravity
:
755 case SouthEastGravity
:
756 *y
+= self
->size
.top
+ self
->size
.bottom
;
760 *y
+= self
->size
.top
;