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
);
27 static Window
createWindow(Window parent
, unsigned long mask
,
28 XSetWindowAttributes
*attrib
)
30 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
31 RrDepth(ob_rr_inst
), InputOutput
,
32 RrVisual(ob_rr_inst
), mask
, attrib
);
38 XSetWindowAttributes attrib
;
42 self
= g_new(ObFrame
, 1);
44 self
->visible
= FALSE
;
45 self
->decorations
= 0;
47 /* create all of the decor windows */
48 mask
= CWOverrideRedirect
| CWEventMask
;
49 attrib
.event_mask
= FRAME_EVENTMASK
;
50 attrib
.override_redirect
= TRUE
;
51 self
->window
= createWindow(ob_root
, mask
, &attrib
);
54 self
->plate
= createWindow(self
->window
, mask
, &attrib
);
57 attrib
.event_mask
= ELEMENT_EVENTMASK
;
58 self
->title
= createWindow(self
->window
, mask
, &attrib
);
59 self
->label
= createWindow(self
->title
, mask
, &attrib
);
60 self
->max
= createWindow(self
->title
, mask
, &attrib
);
61 self
->close
= createWindow(self
->title
, mask
, &attrib
);
62 self
->desk
= createWindow(self
->title
, mask
, &attrib
);
63 self
->shade
= createWindow(self
->title
, mask
, &attrib
);
64 self
->icon
= createWindow(self
->title
, mask
, &attrib
);
65 self
->iconify
= createWindow(self
->title
, mask
, &attrib
);
66 self
->handle
= createWindow(self
->window
, mask
, &attrib
);
68 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHWEST
);
69 self
->lgrip
= createWindow(self
->handle
, mask
, &attrib
);
70 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHEAST
);
71 self
->rgrip
= createWindow(self
->handle
, mask
, &attrib
);
73 self
->focused
= FALSE
;
75 /* the other stuff is shown based on decor settings */
76 XMapWindow(ob_display
, self
->plate
);
77 XMapWindow(ob_display
, self
->lgrip
);
78 XMapWindow(ob_display
, self
->rgrip
);
79 XMapWindow(ob_display
, self
->label
);
81 /* set colors/appearance/sizes for stuff that doesn't change */
82 XSetWindowBorder(ob_display
, self
->window
, ob_rr_theme
->b_color
->pixel
);
83 XSetWindowBorder(ob_display
, self
->label
, ob_rr_theme
->b_color
->pixel
);
84 XSetWindowBorder(ob_display
, self
->rgrip
, ob_rr_theme
->b_color
->pixel
);
85 XSetWindowBorder(ob_display
, self
->lgrip
, ob_rr_theme
->b_color
->pixel
);
87 XResizeWindow(ob_display
, self
->max
,
88 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
89 XResizeWindow(ob_display
, self
->iconify
,
90 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
91 XResizeWindow(ob_display
, self
->icon
,
92 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
93 XResizeWindow(ob_display
, self
->close
,
94 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
95 XResizeWindow(ob_display
, self
->desk
,
96 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
97 XResizeWindow(ob_display
, self
->shade
,
98 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
99 XResizeWindow(ob_display
, self
->lgrip
,
100 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
101 XResizeWindow(ob_display
, self
->rgrip
,
102 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
104 /* set up the dynamic appearances */
105 self
->a_unfocused_title
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_title
);
106 self
->a_focused_title
= RrAppearanceCopy(ob_rr_theme
->a_focused_title
);
107 self
->a_unfocused_label
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_label
);
108 self
->a_focused_label
= RrAppearanceCopy(ob_rr_theme
->a_focused_label
);
109 self
->a_unfocused_handle
=
110 RrAppearanceCopy(ob_rr_theme
->a_unfocused_handle
);
111 self
->a_focused_handle
= RrAppearanceCopy(ob_rr_theme
->a_focused_handle
);
112 self
->a_icon
= RrAppearanceCopy(ob_rr_theme
->a_icon
);
114 self
->max_press
= self
->close_press
= self
->desk_press
=
115 self
->iconify_press
= self
->shade_press
= FALSE
;
117 return (ObFrame
*)self
;
120 static void frame_free(ObFrame
*self
)
122 RrAppearanceFree(self
->a_unfocused_title
);
123 RrAppearanceFree(self
->a_focused_title
);
124 RrAppearanceFree(self
->a_unfocused_label
);
125 RrAppearanceFree(self
->a_focused_label
);
126 RrAppearanceFree(self
->a_unfocused_handle
);
127 RrAppearanceFree(self
->a_focused_handle
);
128 RrAppearanceFree(self
->a_icon
);
130 XDestroyWindow(ob_display
, self
->window
);
135 void frame_show(ObFrame
*self
)
137 if (!self
->visible
) {
138 self
->visible
= TRUE
;
139 XMapWindow(ob_display
, self
->window
);
143 void frame_hide(ObFrame
*self
)
146 self
->visible
= FALSE
;
147 self
->client
->ignore_unmaps
++;
148 XUnmapWindow(ob_display
, self
->window
);
152 void frame_adjust_shape(ObFrame
*self
)
158 if (!self
->client
->shaped
) {
159 /* clear the shape on the frame window */
160 XShapeCombineMask(ob_display
, self
->window
, ShapeBounding
,
161 self
->innersize
.left
,
165 /* make the frame's shape match the clients */
166 XShapeCombineShape(ob_display
, self
->window
, ShapeBounding
,
167 self
->innersize
.left
,
169 self
->client
->window
,
170 ShapeBounding
, ShapeSet
);
173 if (self
->decorations
& Decor_Titlebar
) {
174 xrect
[0].x
= -ob_rr_theme
->bevel
;
175 xrect
[0].y
= -ob_rr_theme
->bevel
;
176 xrect
[0].width
= self
->width
+ self
->bwidth
* 2;
177 xrect
[0].height
= ob_rr_theme
->title_height
+
182 if (self
->decorations
& Decor_Handle
) {
183 xrect
[1].x
= -ob_rr_theme
->bevel
;
184 xrect
[1].y
= FRAME_HANDLE_Y(self
);
185 xrect
[1].width
= self
->width
+ self
->bwidth
* 2;
186 xrect
[1].height
= ob_rr_theme
->handle_height
+
191 XShapeCombineRectangles(ob_display
, self
->window
,
192 ShapeBounding
, 0, 0, xrect
, num
,
193 ShapeUnion
, Unsorted
);
198 void frame_adjust_area(ObFrame
*self
, gboolean moved
, gboolean resized
)
201 self
->decorations
= self
->client
->decorations
;
202 if (self
->decorations
& Decor_Border
) {
203 self
->bwidth
= ob_rr_theme
->bwidth
;
204 self
->cbwidth
= ob_rr_theme
->cbwidth
;
206 self
->bwidth
= self
->cbwidth
= 0;
208 STRUT_SET(self
->innersize
, self
->cbwidth
, self
->cbwidth
,
209 self
->cbwidth
, self
->cbwidth
);
210 self
->width
= self
->client
->area
.width
+ self
->cbwidth
* 2;
211 g_assert(self
->width
> 0);
213 /* set border widths */
214 XSetWindowBorderWidth(ob_display
, self
->plate
, self
->cbwidth
);
215 XSetWindowBorderWidth(ob_display
, self
->window
, self
->bwidth
);
216 XSetWindowBorderWidth(ob_display
, self
->title
, self
->bwidth
);
217 XSetWindowBorderWidth(ob_display
, self
->handle
, self
->bwidth
);
218 XSetWindowBorderWidth(ob_display
, self
->lgrip
, self
->bwidth
);
219 XSetWindowBorderWidth(ob_display
, self
->rgrip
, self
->bwidth
);
221 /* position/size and map/unmap all the windows */
223 /* they all default off, they're turned on in layout_title */
227 self
->iconify_x
= -1;
232 if (self
->decorations
& Decor_Titlebar
) {
233 XMoveResizeWindow(ob_display
, self
->title
,
234 -self
->bwidth
, -self
->bwidth
,
235 self
->width
, ob_rr_theme
->title_height
);
236 self
->innersize
.top
+= ob_rr_theme
->title_height
+ self
->bwidth
;
237 XMapWindow(ob_display
, self
->title
);
239 /* layout the title bar elements */
242 XUnmapWindow(ob_display
, self
->title
);
244 if (self
->decorations
& Decor_Handle
) {
245 XMoveResizeWindow(ob_display
, self
->handle
,
246 -self
->bwidth
, FRAME_HANDLE_Y(self
),
247 self
->width
, ob_rr_theme
->handle_height
);
248 XMoveWindow(ob_display
, self
->lgrip
,
249 -self
->bwidth
, -self
->bwidth
);
250 XMoveWindow(ob_display
, self
->rgrip
,
251 -self
->bwidth
+ self
->width
-
252 ob_rr_theme
->grip_width
, -self
->bwidth
);
253 self
->innersize
.bottom
+= ob_rr_theme
->handle_height
+
255 XMapWindow(ob_display
, self
->handle
);
257 /* XXX make a subwindow with these dimentions?
258 ob_rr_theme->grip_width + self->bwidth, 0,
259 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
260 ob_rr_theme->handle_height);
263 XUnmapWindow(ob_display
, self
->handle
);
267 /* move and resize the plate */
268 XMoveResizeWindow(ob_display
, self
->plate
,
269 self
->innersize
.left
- self
->cbwidth
,
270 self
->innersize
.top
- self
->cbwidth
,
271 self
->client
->area
.width
,
272 self
->client
->area
.height
);
273 /* when the client has StaticGravity, it likes to move around. */
274 XMoveWindow(ob_display
, self
->client
->window
, 0, 0);
278 STRUT_SET(self
->size
,
279 self
->innersize
.left
+ self
->bwidth
,
280 self
->innersize
.top
+ self
->bwidth
,
281 self
->innersize
.right
+ self
->bwidth
,
282 self
->innersize
.bottom
+ self
->bwidth
);
285 /* shading can change without being moved or resized */
286 RECT_SET_SIZE(self
->area
,
287 self
->client
->area
.width
+
288 self
->size
.left
+ self
->size
.right
,
289 (self
->client
->shaded
? ob_rr_theme
->title_height
+ self
->bwidth
*2:
290 self
->client
->area
.height
+
291 self
->size
.top
+ self
->size
.bottom
));
294 /* find the new coordinates, done after setting the frame.size, for
295 frame_client_gravity. */
296 self
->area
.x
= self
->client
->area
.x
;
297 self
->area
.y
= self
->client
->area
.y
;
298 frame_client_gravity((ObFrame
*)self
,
299 &self
->area
.x
, &self
->area
.y
);
302 /* move and resize the top level frame.
303 shading can change without being moved or resized */
304 XMoveResizeWindow(ob_display
, self
->window
,
305 self
->area
.x
, self
->area
.y
,
307 self
->area
.height
- self
->bwidth
* 2);
310 framerender_frame(self
);
312 frame_adjust_shape(self
);
316 void frame_adjust_state(ObFrame
*self
)
318 framerender_frame(self
);
321 void frame_adjust_focus(ObFrame
*self
, gboolean hilite
)
323 self
->focused
= hilite
;
324 framerender_frame(self
);
327 void frame_adjust_title(ObFrame
*self
)
329 framerender_frame(self
);
332 void frame_adjust_icon(ObFrame
*self
)
334 framerender_frame(self
);
337 void frame_grab_client(ObFrame
*self
, ObClient
*client
)
339 self
->client
= client
;
341 /* reparent the client to the frame */
342 XReparentWindow(ob_display
, client
->window
, self
->plate
, 0, 0);
344 When reparenting the client window, it is usually not mapped yet, since
345 this occurs from a MapRequest. However, in the case where Openbox is
346 starting up, the window is already mapped, so we'll see unmap events for
347 it. There are 2 unmap events generated that we see, one with the 'event'
348 member set the root window, and one set to the client, but both get
349 handled and need to be ignored.
351 if (ob_state
== OB_STATE_STARTING
)
352 client
->ignore_unmaps
+= 2;
354 /* select the event mask on the client's parent (to receive config/map
355 req's) the ButtonPress is to catch clicks on the client border */
356 XSelectInput(ob_display
, self
->plate
, PLATE_EVENTMASK
);
358 /* map the client so it maps when the frame does */
359 XMapWindow(ob_display
, client
->window
);
361 frame_adjust_area(self
, TRUE
, TRUE
);
363 /* set all the windows for the frame in the window_map */
364 g_hash_table_insert(window_map
, &self
->window
, client
);
365 g_hash_table_insert(window_map
, &self
->plate
, client
);
366 g_hash_table_insert(window_map
, &self
->title
, client
);
367 g_hash_table_insert(window_map
, &self
->label
, client
);
368 g_hash_table_insert(window_map
, &self
->max
, client
);
369 g_hash_table_insert(window_map
, &self
->close
, client
);
370 g_hash_table_insert(window_map
, &self
->desk
, client
);
371 g_hash_table_insert(window_map
, &self
->shade
, client
);
372 g_hash_table_insert(window_map
, &self
->icon
, client
);
373 g_hash_table_insert(window_map
, &self
->iconify
, client
);
374 g_hash_table_insert(window_map
, &self
->handle
, client
);
375 g_hash_table_insert(window_map
, &self
->lgrip
, client
);
376 g_hash_table_insert(window_map
, &self
->rgrip
, client
);
379 void frame_release_client(ObFrame
*self
, ObClient
*client
)
383 g_assert(self
->client
== client
);
385 /* check if the app has already reparented its window away */
386 if (XCheckTypedWindowEvent(ob_display
, client
->window
,
387 ReparentNotify
, &ev
)) {
388 XPutBackEvent(ob_display
, &ev
);
390 /* re-map the window since the unmanaging process unmaps it */
392 /* XXX ... um no it doesnt it unmaps its parent, the window itself
393 retains its mapped state, no?! XXX
394 XMapWindow(ob_display, client->window); */
396 /* according to the ICCCM - if the client doesn't reparent itself,
397 then we will reparent the window to root for them */
398 XReparentWindow(ob_display
, client
->window
, ob_root
,
403 /* remove all the windows for the frame from the window_map */
404 g_hash_table_remove(window_map
, &self
->window
);
405 g_hash_table_remove(window_map
, &self
->plate
);
406 g_hash_table_remove(window_map
, &self
->title
);
407 g_hash_table_remove(window_map
, &self
->label
);
408 g_hash_table_remove(window_map
, &self
->max
);
409 g_hash_table_remove(window_map
, &self
->close
);
410 g_hash_table_remove(window_map
, &self
->desk
);
411 g_hash_table_remove(window_map
, &self
->shade
);
412 g_hash_table_remove(window_map
, &self
->icon
);
413 g_hash_table_remove(window_map
, &self
->iconify
);
414 g_hash_table_remove(window_map
, &self
->handle
);
415 g_hash_table_remove(window_map
, &self
->lgrip
);
416 g_hash_table_remove(window_map
, &self
->rgrip
);
421 static void layout_title(ObFrame
*self
)
425 gboolean n
, d
, i
, l
, m
, c
, s
;
427 n
= d
= i
= l
= m
= c
= s
= FALSE
;
429 /* figure out whats being shown, and the width of the label */
430 self
->label_width
= self
->width
- (ob_rr_theme
->bevel
+ 1) * 2;
431 for (lc
= ob_rr_theme
->title_layout
; *lc
!= '\0'; ++lc
) {
434 if (!(self
->decorations
& Decor_Icon
)) break;
435 if (n
) { *lc
= ' '; break; } /* rm duplicates */
437 self
->label_width
-= (ob_rr_theme
->button_size
+ 2 +
438 ob_rr_theme
->bevel
+ 1);
441 if (!(self
->decorations
& Decor_AllDesktops
)) break;
442 if (d
) { *lc
= ' '; break; } /* rm duplicates */
444 self
->label_width
-= (ob_rr_theme
->button_size
+
445 ob_rr_theme
->bevel
+ 1);
448 if (!(self
->decorations
& Decor_Shade
)) break;
449 if (s
) { *lc
= ' '; break; } /* rm duplicates */
451 self
->label_width
-= (ob_rr_theme
->button_size
+
452 ob_rr_theme
->bevel
+ 1);
455 if (!(self
->decorations
& Decor_Iconify
)) break;
456 if (i
) { *lc
= ' '; break; } /* rm duplicates */
458 self
->label_width
-= (ob_rr_theme
->button_size
+
459 ob_rr_theme
->bevel
+ 1);
462 if (l
) { *lc
= ' '; break; } /* rm duplicates */
466 if (!(self
->decorations
& Decor_Maximize
)) break;
467 if (m
) { *lc
= ' '; break; } /* rm duplicates */
469 self
->label_width
-= (ob_rr_theme
->button_size
+
470 ob_rr_theme
->bevel
+ 1);
473 if (!(self
->decorations
& Decor_Close
)) break;
474 if (c
) { *lc
= ' '; break; } /* rm duplicates */
476 self
->label_width
-= (ob_rr_theme
->button_size
+
477 ob_rr_theme
->bevel
+ 1);
481 if (self
->label_width
< 1) self
->label_width
= 1;
483 XResizeWindow(ob_display
, self
->label
, self
->label_width
,
484 ob_rr_theme
->label_height
);
486 if (!n
) XUnmapWindow(ob_display
, self
->icon
);
487 if (!d
) XUnmapWindow(ob_display
, self
->desk
);
488 if (!s
) XUnmapWindow(ob_display
, self
->shade
);
489 if (!i
) XUnmapWindow(ob_display
, self
->iconify
);
490 if (!l
) XUnmapWindow(ob_display
, self
->label
);
491 if (!m
) XUnmapWindow(ob_display
, self
->max
);
492 if (!c
) XUnmapWindow(ob_display
, self
->close
);
494 x
= ob_rr_theme
->bevel
+ 1;
495 for (lc
= ob_rr_theme
->title_layout
; *lc
!= '\0'; ++lc
) {
500 XMapWindow(ob_display
, self
->icon
);
501 XMoveWindow(ob_display
, self
->icon
, x
, ob_rr_theme
->bevel
);
502 x
+= ob_rr_theme
->button_size
+ 2 + ob_rr_theme
->bevel
+ 1;
507 XMapWindow(ob_display
, self
->desk
);
508 XMoveWindow(ob_display
, self
->desk
, x
, ob_rr_theme
->bevel
+ 1);
509 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
514 XMapWindow(ob_display
, self
->shade
);
515 XMoveWindow(ob_display
, self
->shade
, x
, ob_rr_theme
->bevel
+ 1);
516 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
521 XMapWindow(ob_display
, self
->iconify
);
522 XMoveWindow(ob_display
, self
->iconify
, x
, ob_rr_theme
->bevel
+ 1);
523 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
528 XMapWindow(ob_display
, self
->label
);
529 XMoveWindow(ob_display
, self
->label
, x
, ob_rr_theme
->bevel
);
530 x
+= self
->label_width
+ ob_rr_theme
->bevel
+ 1;
535 XMapWindow(ob_display
, self
->max
);
536 XMoveWindow(ob_display
, self
->max
, x
, ob_rr_theme
->bevel
+ 1);
537 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
542 XMapWindow(ob_display
, self
->close
);
543 XMoveWindow(ob_display
, self
->close
, x
, ob_rr_theme
->bevel
+ 1);
544 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
550 ObFrameContext
frame_context_from_string(char *name
)
552 if (!g_ascii_strcasecmp("root", name
))
553 return OB_FRAME_CONTEXT_ROOT
;
554 else if (!g_ascii_strcasecmp("client", name
))
555 return OB_FRAME_CONTEXT_CLIENT
;
556 else if (!g_ascii_strcasecmp("titlebar", name
))
557 return OB_FRAME_CONTEXT_TITLEBAR
;
558 else if (!g_ascii_strcasecmp("handle", name
))
559 return OB_FRAME_CONTEXT_HANDLE
;
560 else if (!g_ascii_strcasecmp("frame", name
))
561 return OB_FRAME_CONTEXT_FRAME
;
562 else if (!g_ascii_strcasecmp("blcorner", name
))
563 return OB_FRAME_CONTEXT_BLCORNER
;
564 else if (!g_ascii_strcasecmp("brcorner", name
))
565 return OB_FRAME_CONTEXT_BRCORNER
;
566 else if (!g_ascii_strcasecmp("maximize", name
))
567 return OB_FRAME_CONTEXT_MAXIMIZE
;
568 else if (!g_ascii_strcasecmp("alldesktops", name
))
569 return OB_FRAME_CONTEXT_ALLDESKTOPS
;
570 else if (!g_ascii_strcasecmp("shade", name
))
571 return OB_FRAME_CONTEXT_SHADE
;
572 else if (!g_ascii_strcasecmp("iconify", name
))
573 return OB_FRAME_CONTEXT_ICONIFY
;
574 else if (!g_ascii_strcasecmp("icon", name
))
575 return OB_FRAME_CONTEXT_ICON
;
576 else if (!g_ascii_strcasecmp("close", name
))
577 return OB_FRAME_CONTEXT_CLOSE
;
578 return OB_FRAME_CONTEXT_NONE
;
581 ObFrameContext
frame_context(ObClient
*client
, Window win
)
585 if (win
== ob_root
) return OB_FRAME_CONTEXT_ROOT
;
586 if (client
== NULL
) return OB_FRAME_CONTEXT_NONE
;
587 if (win
== client
->window
) return OB_FRAME_CONTEXT_CLIENT
;
589 self
= client
->frame
;
590 if (win
== self
->window
) return OB_FRAME_CONTEXT_FRAME
;
591 if (win
== self
->plate
) return OB_FRAME_CONTEXT_CLIENT
;
592 if (win
== self
->title
) return OB_FRAME_CONTEXT_TITLEBAR
;
593 if (win
== self
->label
) return OB_FRAME_CONTEXT_TITLEBAR
;
594 if (win
== self
->handle
) return OB_FRAME_CONTEXT_HANDLE
;
595 if (win
== self
->lgrip
) return OB_FRAME_CONTEXT_BLCORNER
;
596 if (win
== self
->rgrip
) return OB_FRAME_CONTEXT_BRCORNER
;
597 if (win
== self
->max
) return OB_FRAME_CONTEXT_MAXIMIZE
;
598 if (win
== self
->iconify
)return OB_FRAME_CONTEXT_ICONIFY
;
599 if (win
== self
->close
) return OB_FRAME_CONTEXT_CLOSE
;
600 if (win
== self
->icon
) return OB_FRAME_CONTEXT_ICON
;
601 if (win
== self
->desk
) return OB_FRAME_CONTEXT_ALLDESKTOPS
;
602 if (win
== self
->shade
) return OB_FRAME_CONTEXT_SHADE
;
604 return OB_FRAME_CONTEXT_NONE
;
607 void frame_client_gravity(ObFrame
*self
, int *x
, int *y
)
610 switch (self
->client
->gravity
) {
612 case NorthWestGravity
:
613 case SouthWestGravity
:
620 *x
-= (self
->size
.left
+ self
->size
.right
) / 2;
623 case NorthEastGravity
:
624 case SouthEastGravity
:
626 *x
-= self
->size
.left
+ self
->size
.right
;
631 *x
-= self
->size
.left
;
636 switch (self
->client
->gravity
) {
638 case NorthWestGravity
:
639 case NorthEastGravity
:
646 *y
-= (self
->size
.top
+ self
->size
.bottom
) / 2;
649 case SouthWestGravity
:
650 case SouthEastGravity
:
652 *y
-= self
->size
.top
+ self
->size
.bottom
;
657 *y
-= self
->size
.top
;
662 void frame_frame_gravity(ObFrame
*self
, int *x
, int *y
)
665 switch (self
->client
->gravity
) {
667 case NorthWestGravity
:
669 case SouthWestGravity
:
674 *x
+= (self
->size
.left
+ self
->size
.right
) / 2;
676 case NorthEastGravity
:
678 case SouthEastGravity
:
679 *x
+= self
->size
.left
+ self
->size
.right
;
683 *x
+= self
->size
.left
;
688 switch (self
->client
->gravity
) {
690 case NorthWestGravity
:
692 case SouthWestGravity
:
697 *y
+= (self
->size
.top
+ self
->size
.bottom
) / 2;
699 case NorthEastGravity
:
701 case SouthEastGravity
:
702 *y
+= self
->size
.top
+ self
->size
.bottom
;
706 *y
+= self
->size
.top
;