4 #include "extensions.h"
5 #include "framerender.h"
6 #include "render/theme.h"
8 #define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
9 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
10 ButtonPressMask | ButtonReleaseMask)
11 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
12 ButtonMotionMask | ExposureMask)
14 #define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
17 static void layout_title(ObFrame
*self
);
19 static Window
createWindow(Window parent
, unsigned long mask
,
20 XSetWindowAttributes
*attrib
)
22 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
23 RrDepth(ob_rr_inst
), InputOutput
,
24 RrVisual(ob_rr_inst
), mask
, attrib
);
30 XSetWindowAttributes attrib
;
34 self
= g_new(ObFrame
, 1);
36 self
->visible
= FALSE
;
37 self
->decorations
= 0;
39 /* create all of the decor windows */
40 mask
= CWOverrideRedirect
| CWEventMask
;
41 attrib
.event_mask
= FRAME_EVENTMASK
;
42 attrib
.override_redirect
= TRUE
;
43 self
->window
= createWindow(RootWindow(ob_display
, ob_screen
),
47 self
->plate
= createWindow(self
->window
, mask
, &attrib
);
50 attrib
.event_mask
= ELEMENT_EVENTMASK
;
51 self
->title
= createWindow(self
->window
, mask
, &attrib
);
52 self
->label
= createWindow(self
->title
, mask
, &attrib
);
53 self
->max
= createWindow(self
->title
, mask
, &attrib
);
54 self
->close
= createWindow(self
->title
, mask
, &attrib
);
55 self
->desk
= createWindow(self
->title
, mask
, &attrib
);
56 self
->shade
= createWindow(self
->title
, mask
, &attrib
);
57 self
->icon
= createWindow(self
->title
, mask
, &attrib
);
58 self
->iconify
= createWindow(self
->title
, mask
, &attrib
);
59 self
->handle
= createWindow(self
->window
, mask
, &attrib
);
61 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHWEST
);
62 self
->lgrip
= createWindow(self
->handle
, mask
, &attrib
);
63 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHEAST
);
64 self
->rgrip
= createWindow(self
->handle
, mask
, &attrib
);
66 self
->focused
= FALSE
;
68 /* the other stuff is shown based on decor settings */
69 XMapWindow(ob_display
, self
->plate
);
70 XMapWindow(ob_display
, self
->lgrip
);
71 XMapWindow(ob_display
, self
->rgrip
);
72 XMapWindow(ob_display
, self
->label
);
74 /* set colors/appearance/sizes for stuff that doesn't change */
75 XSetWindowBorder(ob_display
, self
->window
, ob_rr_theme
->b_color
->pixel
);
76 XSetWindowBorder(ob_display
, self
->label
, ob_rr_theme
->b_color
->pixel
);
77 XSetWindowBorder(ob_display
, self
->rgrip
, ob_rr_theme
->b_color
->pixel
);
78 XSetWindowBorder(ob_display
, self
->lgrip
, ob_rr_theme
->b_color
->pixel
);
80 XResizeWindow(ob_display
, self
->max
,
81 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
82 XResizeWindow(ob_display
, self
->iconify
,
83 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
84 XResizeWindow(ob_display
, self
->icon
,
85 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
86 XResizeWindow(ob_display
, self
->close
,
87 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
88 XResizeWindow(ob_display
, self
->desk
,
89 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
90 XResizeWindow(ob_display
, self
->shade
,
91 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
92 XResizeWindow(ob_display
, self
->lgrip
,
93 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
94 XResizeWindow(ob_display
, self
->rgrip
,
95 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
97 /* set up the dynamic appearances */
98 self
->a_unfocused_title
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_title
);
99 self
->a_focused_title
= RrAppearanceCopy(ob_rr_theme
->a_focused_title
);
100 self
->a_unfocused_label
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_label
);
101 self
->a_focused_label
= RrAppearanceCopy(ob_rr_theme
->a_focused_label
);
102 self
->a_unfocused_handle
=
103 RrAppearanceCopy(ob_rr_theme
->a_unfocused_handle
);
104 self
->a_focused_handle
= RrAppearanceCopy(ob_rr_theme
->a_focused_handle
);
105 self
->a_icon
= RrAppearanceCopy(ob_rr_theme
->a_icon
);
107 self
->max_press
= self
->close_press
= self
->desk_press
=
108 self
->iconify_press
= self
->shade_press
= FALSE
;
110 return (ObFrame
*)self
;
113 static void frame_free(ObFrame
*self
)
115 RrAppearanceFree(self
->a_unfocused_title
);
116 RrAppearanceFree(self
->a_focused_title
);
117 RrAppearanceFree(self
->a_unfocused_label
);
118 RrAppearanceFree(self
->a_focused_label
);
119 RrAppearanceFree(self
->a_unfocused_handle
);
120 RrAppearanceFree(self
->a_focused_handle
);
121 RrAppearanceFree(self
->a_icon
);
123 XDestroyWindow(ob_display
, self
->window
);
128 void frame_show(ObFrame
*self
)
130 if (!self
->visible
) {
131 self
->visible
= TRUE
;
132 XMapWindow(ob_display
, self
->window
);
136 void frame_hide(ObFrame
*self
)
139 self
->visible
= FALSE
;
140 self
->client
->ignore_unmaps
++;
141 XUnmapWindow(ob_display
, self
->window
);
145 void frame_adjust_shape(ObFrame
*self
)
151 if (!self
->client
->shaped
) {
152 /* clear the shape on the frame window */
153 XShapeCombineMask(ob_display
, self
->window
, ShapeBounding
,
154 self
->innersize
.left
,
158 /* make the frame's shape match the clients */
159 XShapeCombineShape(ob_display
, self
->window
, ShapeBounding
,
160 self
->innersize
.left
,
162 self
->client
->window
,
163 ShapeBounding
, ShapeSet
);
166 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
167 xrect
[0].x
= -ob_rr_theme
->bevel
;
168 xrect
[0].y
= -ob_rr_theme
->bevel
;
169 xrect
[0].width
= self
->width
+ self
->bwidth
* 2;
170 xrect
[0].height
= ob_rr_theme
->title_height
+
175 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
176 xrect
[1].x
= -ob_rr_theme
->bevel
;
177 xrect
[1].y
= FRAME_HANDLE_Y(self
);
178 xrect
[1].width
= self
->width
+ self
->bwidth
* 2;
179 xrect
[1].height
= ob_rr_theme
->handle_height
+
184 XShapeCombineRectangles(ob_display
, self
->window
,
185 ShapeBounding
, 0, 0, xrect
, num
,
186 ShapeUnion
, Unsorted
);
191 void frame_adjust_area(ObFrame
*self
, gboolean moved
, gboolean resized
)
194 self
->decorations
= self
->client
->decorations
;
195 if (self
->decorations
& OB_FRAME_DECOR_BORDER
) {
196 self
->bwidth
= ob_rr_theme
->bwidth
;
197 self
->cbwidth
= ob_rr_theme
->cbwidth
;
199 self
->bwidth
= self
->cbwidth
= 0;
201 STRUT_SET(self
->innersize
, self
->cbwidth
, self
->cbwidth
,
202 self
->cbwidth
, self
->cbwidth
);
203 self
->width
= self
->client
->area
.width
+ self
->cbwidth
* 2;
204 g_assert(self
->width
> 0);
206 /* set border widths */
207 XSetWindowBorderWidth(ob_display
, self
->plate
, self
->cbwidth
);
208 XSetWindowBorderWidth(ob_display
, self
->window
, self
->bwidth
);
209 XSetWindowBorderWidth(ob_display
, self
->title
, self
->bwidth
);
210 XSetWindowBorderWidth(ob_display
, self
->handle
, self
->bwidth
);
211 XSetWindowBorderWidth(ob_display
, self
->lgrip
, self
->bwidth
);
212 XSetWindowBorderWidth(ob_display
, self
->rgrip
, self
->bwidth
);
214 /* position/size and map/unmap all the windows */
216 /* they all default off, they're turned on in layout_title */
220 self
->iconify_x
= -1;
225 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
226 XMoveResizeWindow(ob_display
, self
->title
,
227 -self
->bwidth
, -self
->bwidth
,
228 self
->width
, ob_rr_theme
->title_height
);
229 self
->innersize
.top
+= ob_rr_theme
->title_height
+ self
->bwidth
;
230 XMapWindow(ob_display
, self
->title
);
232 /* layout the title bar elements */
235 XUnmapWindow(ob_display
, self
->title
);
237 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
238 XMoveResizeWindow(ob_display
, self
->handle
,
239 -self
->bwidth
, FRAME_HANDLE_Y(self
),
240 self
->width
, ob_rr_theme
->handle_height
);
241 self
->innersize
.bottom
+= ob_rr_theme
->handle_height
+
243 XMapWindow(ob_display
, self
->handle
);
245 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
246 XMoveWindow(ob_display
, self
->lgrip
,
247 -self
->bwidth
, -self
->bwidth
);
248 XMoveWindow(ob_display
, self
->rgrip
,
249 -self
->bwidth
+ self
->width
-
250 ob_rr_theme
->grip_width
, -self
->bwidth
);
251 XMapWindow(ob_display
, self
->lgrip
);
252 XMapWindow(ob_display
, self
->rgrip
);
254 XUnmapWindow(ob_display
, self
->lgrip
);
255 XUnmapWindow(ob_display
, self
->rgrip
);
258 /* XXX make a subwindow with these dimentions?
259 ob_rr_theme->grip_width + self->bwidth, 0,
260 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
261 ob_rr_theme->handle_height);
264 XUnmapWindow(ob_display
, self
->handle
);
268 /* move and resize the plate */
269 XMoveResizeWindow(ob_display
, self
->plate
,
270 self
->innersize
.left
- self
->cbwidth
,
271 self
->innersize
.top
- self
->cbwidth
,
272 self
->client
->area
.width
,
273 self
->client
->area
.height
);
274 /* when the client has StaticGravity, it likes to move around. */
275 XMoveWindow(ob_display
, self
->client
->window
, 0, 0);
279 STRUT_SET(self
->size
,
280 self
->innersize
.left
+ self
->bwidth
,
281 self
->innersize
.top
+ self
->bwidth
,
282 self
->innersize
.right
+ self
->bwidth
,
283 self
->innersize
.bottom
+ self
->bwidth
);
286 /* shading can change without being moved or resized */
287 RECT_SET_SIZE(self
->area
,
288 self
->client
->area
.width
+
289 self
->size
.left
+ self
->size
.right
,
290 (self
->client
->shaded
? ob_rr_theme
->title_height
+ self
->bwidth
*2:
291 self
->client
->area
.height
+
292 self
->size
.top
+ self
->size
.bottom
));
295 /* find the new coordinates, done after setting the frame.size, for
296 frame_client_gravity. */
297 self
->area
.x
= self
->client
->area
.x
;
298 self
->area
.y
= self
->client
->area
.y
;
299 frame_client_gravity((ObFrame
*)self
,
300 &self
->area
.x
, &self
->area
.y
);
303 /* move and resize the top level frame.
304 shading can change without being moved or resized */
305 XMoveResizeWindow(ob_display
, self
->window
,
306 self
->area
.x
, self
->area
.y
,
308 self
->area
.height
- self
->bwidth
* 2);
311 framerender_frame(self
);
313 frame_adjust_shape(self
);
317 void frame_adjust_state(ObFrame
*self
)
319 framerender_frame(self
);
322 void frame_adjust_focus(ObFrame
*self
, gboolean hilite
)
324 self
->focused
= hilite
;
325 framerender_frame(self
);
328 void frame_adjust_title(ObFrame
*self
)
330 framerender_frame(self
);
333 void frame_adjust_icon(ObFrame
*self
)
335 framerender_frame(self
);
338 void frame_grab_client(ObFrame
*self
, ObClient
*client
)
340 self
->client
= client
;
342 /* reparent the client to the frame */
343 XReparentWindow(ob_display
, client
->window
, self
->plate
, 0, 0);
345 When reparenting the client window, it is usually not mapped yet, since
346 this occurs from a MapRequest. However, in the case where Openbox is
347 starting up, the window is already mapped, so we'll see unmap events for
348 it. There are 2 unmap events generated that we see, one with the 'event'
349 member set the root window, and one set to the client, but both get
350 handled and need to be ignored.
352 if (ob_state() == OB_STATE_STARTING
)
353 client
->ignore_unmaps
+= 2;
355 /* select the event mask on the client's parent (to receive config/map
356 req's) the ButtonPress is to catch clicks on the client border */
357 XSelectInput(ob_display
, self
->plate
, PLATE_EVENTMASK
);
359 /* map the client so it maps when the frame does */
360 XMapWindow(ob_display
, client
->window
);
362 frame_adjust_area(self
, TRUE
, TRUE
);
364 /* set all the windows for the frame in the window_map */
365 g_hash_table_insert(window_map
, &self
->window
, client
);
366 g_hash_table_insert(window_map
, &self
->plate
, client
);
367 g_hash_table_insert(window_map
, &self
->title
, client
);
368 g_hash_table_insert(window_map
, &self
->label
, client
);
369 g_hash_table_insert(window_map
, &self
->max
, client
);
370 g_hash_table_insert(window_map
, &self
->close
, client
);
371 g_hash_table_insert(window_map
, &self
->desk
, client
);
372 g_hash_table_insert(window_map
, &self
->shade
, client
);
373 g_hash_table_insert(window_map
, &self
->icon
, client
);
374 g_hash_table_insert(window_map
, &self
->iconify
, client
);
375 g_hash_table_insert(window_map
, &self
->handle
, client
);
376 g_hash_table_insert(window_map
, &self
->lgrip
, client
);
377 g_hash_table_insert(window_map
, &self
->rgrip
, client
);
380 void frame_release_client(ObFrame
*self
, ObClient
*client
)
384 g_assert(self
->client
== client
);
386 /* check if the app has already reparented its window away */
387 if (XCheckTypedWindowEvent(ob_display
, client
->window
,
388 ReparentNotify
, &ev
)) {
389 XPutBackEvent(ob_display
, &ev
);
391 /* re-map the window since the unmanaging process unmaps it */
393 /* XXX ... um no it doesnt it unmaps its parent, the window itself
394 retains its mapped state, no?! XXX
395 XMapWindow(ob_display, client->window); */
397 /* according to the ICCCM - if the client doesn't reparent itself,
398 then we will reparent the window to root for them */
399 XReparentWindow(ob_display
, client
->window
,
400 RootWindow(ob_display
, ob_screen
),
405 /* remove all the windows for the frame from the window_map */
406 g_hash_table_remove(window_map
, &self
->window
);
407 g_hash_table_remove(window_map
, &self
->plate
);
408 g_hash_table_remove(window_map
, &self
->title
);
409 g_hash_table_remove(window_map
, &self
->label
);
410 g_hash_table_remove(window_map
, &self
->max
);
411 g_hash_table_remove(window_map
, &self
->close
);
412 g_hash_table_remove(window_map
, &self
->desk
);
413 g_hash_table_remove(window_map
, &self
->shade
);
414 g_hash_table_remove(window_map
, &self
->icon
);
415 g_hash_table_remove(window_map
, &self
->iconify
);
416 g_hash_table_remove(window_map
, &self
->handle
);
417 g_hash_table_remove(window_map
, &self
->lgrip
);
418 g_hash_table_remove(window_map
, &self
->rgrip
);
423 static void layout_title(ObFrame
*self
)
427 gboolean n
, d
, i
, l
, m
, c
, s
;
429 n
= d
= i
= l
= m
= c
= s
= FALSE
;
431 /* figure out whats being shown, and the width of the label */
432 self
->label_width
= self
->width
- (ob_rr_theme
->bevel
+ 1) * 2;
433 for (lc
= ob_rr_theme
->title_layout
; *lc
!= '\0'; ++lc
) {
436 if (n
) { *lc
= ' '; break; } /* rm duplicates */
438 self
->label_width
-= (ob_rr_theme
->button_size
+ 2 +
439 ob_rr_theme
->bevel
+ 1);
442 if (d
) { *lc
= ' '; break; } /* rm duplicates */
444 self
->label_width
-= (ob_rr_theme
->button_size
+
445 ob_rr_theme
->bevel
+ 1);
448 if (s
) { *lc
= ' '; break; } /* rm duplicates */
450 self
->label_width
-= (ob_rr_theme
->button_size
+
451 ob_rr_theme
->bevel
+ 1);
454 if (i
) { *lc
= ' '; break; } /* rm duplicates */
456 self
->label_width
-= (ob_rr_theme
->button_size
+
457 ob_rr_theme
->bevel
+ 1);
460 if (l
) { *lc
= ' '; break; } /* rm duplicates */
464 if (m
) { *lc
= ' '; break; } /* rm duplicates */
466 self
->label_width
-= (ob_rr_theme
->button_size
+
467 ob_rr_theme
->bevel
+ 1);
470 if (c
) { *lc
= ' '; break; } /* rm duplicates */
472 self
->label_width
-= (ob_rr_theme
->button_size
+
473 ob_rr_theme
->bevel
+ 1);
477 if (self
->label_width
< 1) self
->label_width
= 1;
479 XResizeWindow(ob_display
, self
->label
, self
->label_width
,
480 ob_rr_theme
->label_height
);
482 if (!n
) XUnmapWindow(ob_display
, self
->icon
);
483 if (!d
) XUnmapWindow(ob_display
, self
->desk
);
484 if (!s
) XUnmapWindow(ob_display
, self
->shade
);
485 if (!i
) XUnmapWindow(ob_display
, self
->iconify
);
486 if (!l
) XUnmapWindow(ob_display
, self
->label
);
487 if (!m
) XUnmapWindow(ob_display
, self
->max
);
488 if (!c
) XUnmapWindow(ob_display
, self
->close
);
490 x
= ob_rr_theme
->bevel
+ 1;
491 for (lc
= ob_rr_theme
->title_layout
; *lc
!= '\0'; ++lc
) {
496 XMapWindow(ob_display
, self
->icon
);
497 XMoveWindow(ob_display
, self
->icon
, x
, ob_rr_theme
->bevel
);
498 x
+= ob_rr_theme
->button_size
+ 2 + ob_rr_theme
->bevel
+ 1;
503 XMapWindow(ob_display
, self
->desk
);
504 XMoveWindow(ob_display
, self
->desk
, x
, ob_rr_theme
->bevel
+ 1);
505 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
510 XMapWindow(ob_display
, self
->shade
);
511 XMoveWindow(ob_display
, self
->shade
, x
, ob_rr_theme
->bevel
+ 1);
512 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
517 XMapWindow(ob_display
, self
->iconify
);
518 XMoveWindow(ob_display
, self
->iconify
, x
, ob_rr_theme
->bevel
+ 1);
519 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
524 XMapWindow(ob_display
, self
->label
);
525 XMoveWindow(ob_display
, self
->label
, x
, ob_rr_theme
->bevel
);
526 x
+= self
->label_width
+ ob_rr_theme
->bevel
+ 1;
531 XMapWindow(ob_display
, self
->max
);
532 XMoveWindow(ob_display
, self
->max
, x
, ob_rr_theme
->bevel
+ 1);
533 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
538 XMapWindow(ob_display
, self
->close
);
539 XMoveWindow(ob_display
, self
->close
, x
, ob_rr_theme
->bevel
+ 1);
540 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
546 ObFrameContext
frame_context_from_string(char *name
)
548 if (!g_ascii_strcasecmp("root", name
))
549 return OB_FRAME_CONTEXT_ROOT
;
550 else if (!g_ascii_strcasecmp("client", name
))
551 return OB_FRAME_CONTEXT_CLIENT
;
552 else if (!g_ascii_strcasecmp("titlebar", name
))
553 return OB_FRAME_CONTEXT_TITLEBAR
;
554 else if (!g_ascii_strcasecmp("handle", name
))
555 return OB_FRAME_CONTEXT_HANDLE
;
556 else if (!g_ascii_strcasecmp("frame", name
))
557 return OB_FRAME_CONTEXT_FRAME
;
558 else if (!g_ascii_strcasecmp("blcorner", name
))
559 return OB_FRAME_CONTEXT_BLCORNER
;
560 else if (!g_ascii_strcasecmp("brcorner", name
))
561 return OB_FRAME_CONTEXT_BRCORNER
;
562 else if (!g_ascii_strcasecmp("maximize", name
))
563 return OB_FRAME_CONTEXT_MAXIMIZE
;
564 else if (!g_ascii_strcasecmp("alldesktops", name
))
565 return OB_FRAME_CONTEXT_ALLDESKTOPS
;
566 else if (!g_ascii_strcasecmp("shade", name
))
567 return OB_FRAME_CONTEXT_SHADE
;
568 else if (!g_ascii_strcasecmp("iconify", name
))
569 return OB_FRAME_CONTEXT_ICONIFY
;
570 else if (!g_ascii_strcasecmp("icon", name
))
571 return OB_FRAME_CONTEXT_ICON
;
572 else if (!g_ascii_strcasecmp("close", name
))
573 return OB_FRAME_CONTEXT_CLOSE
;
574 return OB_FRAME_CONTEXT_NONE
;
577 ObFrameContext
frame_context(ObClient
*client
, Window win
)
581 if (win
== RootWindow(ob_display
, ob_screen
)) return OB_FRAME_CONTEXT_ROOT
;
582 if (client
== NULL
) return OB_FRAME_CONTEXT_NONE
;
583 if (win
== client
->window
) return OB_FRAME_CONTEXT_CLIENT
;
585 self
= client
->frame
;
586 if (win
== self
->window
) return OB_FRAME_CONTEXT_FRAME
;
587 if (win
== self
->plate
) return OB_FRAME_CONTEXT_CLIENT
;
588 if (win
== self
->title
) return OB_FRAME_CONTEXT_TITLEBAR
;
589 if (win
== self
->label
) return OB_FRAME_CONTEXT_TITLEBAR
;
590 if (win
== self
->handle
) return OB_FRAME_CONTEXT_HANDLE
;
591 if (win
== self
->lgrip
) return OB_FRAME_CONTEXT_BLCORNER
;
592 if (win
== self
->rgrip
) return OB_FRAME_CONTEXT_BRCORNER
;
593 if (win
== self
->max
) return OB_FRAME_CONTEXT_MAXIMIZE
;
594 if (win
== self
->iconify
)return OB_FRAME_CONTEXT_ICONIFY
;
595 if (win
== self
->close
) return OB_FRAME_CONTEXT_CLOSE
;
596 if (win
== self
->icon
) return OB_FRAME_CONTEXT_ICON
;
597 if (win
== self
->desk
) return OB_FRAME_CONTEXT_ALLDESKTOPS
;
598 if (win
== self
->shade
) return OB_FRAME_CONTEXT_SHADE
;
600 return OB_FRAME_CONTEXT_NONE
;
603 void frame_client_gravity(ObFrame
*self
, int *x
, int *y
)
606 switch (self
->client
->gravity
) {
608 case NorthWestGravity
:
609 case SouthWestGravity
:
616 *x
-= (self
->size
.left
+ self
->size
.right
) / 2;
619 case NorthEastGravity
:
620 case SouthEastGravity
:
622 *x
-= self
->size
.left
+ self
->size
.right
;
627 *x
-= self
->size
.left
;
632 switch (self
->client
->gravity
) {
634 case NorthWestGravity
:
635 case NorthEastGravity
:
642 *y
-= (self
->size
.top
+ self
->size
.bottom
) / 2;
645 case SouthWestGravity
:
646 case SouthEastGravity
:
648 *y
-= self
->size
.top
+ self
->size
.bottom
;
653 *y
-= self
->size
.top
;
658 void frame_frame_gravity(ObFrame
*self
, int *x
, int *y
)
661 switch (self
->client
->gravity
) {
663 case NorthWestGravity
:
665 case SouthWestGravity
:
670 *x
+= (self
->size
.left
+ self
->size
.right
) / 2;
672 case NorthEastGravity
:
674 case SouthEastGravity
:
675 *x
+= self
->size
.left
+ self
->size
.right
;
679 *x
+= self
->size
.left
;
684 switch (self
->client
->gravity
) {
686 case NorthWestGravity
:
688 case SouthWestGravity
:
693 *y
+= (self
->size
.top
+ self
->size
.bottom
) / 2;
695 case NorthEastGravity
:
697 case SouthEastGravity
:
698 *y
+= self
->size
.top
+ self
->size
.bottom
;
702 *y
+= self
->size
.top
;