]> Dogcows Code - chaz/openbox/blob - openbox/frame.c
put the render theme into a struct
[chaz/openbox] / openbox / frame.c
1 #include "frame.h"
2 #include "openbox.h"
3 #include "extensions.h"
4 #include "framerender.h"
5 #include "render/theme.h"
6
7 #define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
8 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
9 ButtonPressMask | ButtonReleaseMask)
10 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
11 ButtonMotionMask | ExposureMask)
12
13 static void layout_title(Frame *self);
14
15 void frame_startup()
16 {
17 }
18
19 void frame_shutdown()
20 {
21 }
22
23 static Window createWindow(Window parent, unsigned long mask,
24 XSetWindowAttributes *attrib)
25 {
26 return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
27 RrDepth(ob_rr_inst), InputOutput,
28 RrVisual(ob_rr_inst), mask, attrib);
29
30 }
31
32 Frame *frame_new()
33 {
34 XSetWindowAttributes attrib;
35 unsigned long mask;
36 Frame *self;
37
38 self = g_new(Frame, 1);
39
40 self->visible = FALSE;
41
42 /* create all of the decor windows */
43 mask = CWOverrideRedirect | CWEventMask;
44 attrib.event_mask = FRAME_EVENTMASK;
45 attrib.override_redirect = TRUE;
46 self->window = createWindow(ob_root, mask, &attrib);
47
48 mask = 0;
49 self->plate = createWindow(self->window, mask, &attrib);
50
51 mask = CWEventMask;
52 attrib.event_mask = ELEMENT_EVENTMASK;
53 self->title = createWindow(self->window, mask, &attrib);
54 self->label = createWindow(self->title, mask, &attrib);
55 self->max = createWindow(self->title, mask, &attrib);
56 self->close = createWindow(self->title, mask, &attrib);
57 self->desk = createWindow(self->title, mask, &attrib);
58 self->shade = createWindow(self->title, mask, &attrib);
59 self->icon = createWindow(self->title, mask, &attrib);
60 self->iconify = createWindow(self->title, mask, &attrib);
61 self->handle = createWindow(self->window, mask, &attrib);
62 mask |= CWCursor;
63 attrib.cursor = ob_cursors.bl;
64 self->lgrip = createWindow(self->handle, mask, &attrib);
65 attrib.cursor = ob_cursors.br;
66 self->rgrip = createWindow(self->handle, mask, &attrib);
67
68 self->focused = FALSE;
69
70 /* the other stuff is shown based on decor settings */
71 XMapWindow(ob_display, self->plate);
72 XMapWindow(ob_display, self->lgrip);
73 XMapWindow(ob_display, self->rgrip);
74 XMapWindow(ob_display, self->label);
75
76 /* set colors/appearance/sizes for stuff that doesn't change */
77 XSetWindowBorder(ob_display, self->window, ob_rr_theme->b_color->pixel);
78 XSetWindowBorder(ob_display, self->label, ob_rr_theme->b_color->pixel);
79 XSetWindowBorder(ob_display, self->rgrip, ob_rr_theme->b_color->pixel);
80 XSetWindowBorder(ob_display, self->lgrip, ob_rr_theme->b_color->pixel);
81
82 XResizeWindow(ob_display, self->max,
83 ob_rr_theme->button_size, ob_rr_theme->button_size);
84 XResizeWindow(ob_display, self->iconify,
85 ob_rr_theme->button_size, ob_rr_theme->button_size);
86 XResizeWindow(ob_display, self->icon,
87 ob_rr_theme->button_size + 2, ob_rr_theme->button_size + 2);
88 XResizeWindow(ob_display, self->close,
89 ob_rr_theme->button_size, ob_rr_theme->button_size);
90 XResizeWindow(ob_display, self->desk,
91 ob_rr_theme->button_size, ob_rr_theme->button_size);
92 XResizeWindow(ob_display, self->shade,
93 ob_rr_theme->button_size, ob_rr_theme->button_size);
94 XResizeWindow(ob_display, self->lgrip,
95 ob_rr_theme->grip_width, ob_rr_theme->handle_height);
96 XResizeWindow(ob_display, self->rgrip,
97 ob_rr_theme->grip_width, ob_rr_theme->handle_height);
98
99 /* set up the dynamic appearances */
100 self->a_unfocused_title = RrAppearanceCopy(ob_rr_theme->a_unfocused_title);
101 self->a_focused_title = RrAppearanceCopy(ob_rr_theme->a_focused_title);
102 self->a_unfocused_label = RrAppearanceCopy(ob_rr_theme->a_unfocused_label);
103 self->a_focused_label = RrAppearanceCopy(ob_rr_theme->a_focused_label);
104 self->a_unfocused_handle =
105 RrAppearanceCopy(ob_rr_theme->a_unfocused_handle);
106 self->a_focused_handle = RrAppearanceCopy(ob_rr_theme->a_focused_handle);
107 self->a_icon = RrAppearanceCopy(ob_rr_theme->a_icon);
108
109 self->max_press = self->close_press = self->desk_press =
110 self->iconify_press = self->shade_press = FALSE;
111
112 return (Frame*)self;
113 }
114
115 static void frame_free(Frame *self)
116 {
117 RrAppearanceFree(self->a_unfocused_title);
118 RrAppearanceFree(self->a_focused_title);
119 RrAppearanceFree(self->a_unfocused_label);
120 RrAppearanceFree(self->a_focused_label);
121 RrAppearanceFree(self->a_unfocused_handle);
122 RrAppearanceFree(self->a_focused_handle);
123 RrAppearanceFree(self->a_icon);
124
125 XDestroyWindow(ob_display, self->window);
126
127 g_free(self);
128 }
129
130 void frame_show(Frame *self)
131 {
132 if (!self->visible) {
133 self->visible = TRUE;
134 XMapWindow(ob_display, self->window);
135 }
136 }
137
138 void frame_hide(Frame *self)
139 {
140 if (self->visible) {
141 self->visible = FALSE;
142 self->client->ignore_unmaps++;
143 XUnmapWindow(ob_display, self->window);
144 }
145 }
146
147 void frame_adjust_shape(Frame *self)
148 {
149 #ifdef SHAPE
150 int num;
151 XRectangle xrect[2];
152
153 if (!self->client->shaped) {
154 /* clear the shape on the frame window */
155 XShapeCombineMask(ob_display, self->window, ShapeBounding,
156 self->innersize.left,
157 self->innersize.top,
158 None, ShapeSet);
159 } else {
160 /* make the frame's shape match the clients */
161 XShapeCombineShape(ob_display, self->window, ShapeBounding,
162 self->innersize.left,
163 self->innersize.top,
164 self->client->window,
165 ShapeBounding, ShapeSet);
166
167 num = 0;
168 if (self->client->decorations & Decor_Titlebar) {
169 xrect[0].x = -ob_rr_theme->bevel;
170 xrect[0].y = -ob_rr_theme->bevel;
171 xrect[0].width = self->width + self->bwidth * 2;
172 xrect[0].height = ob_rr_theme->title_height +
173 self->bwidth * 2;
174 ++num;
175 }
176
177 if (self->client->decorations & Decor_Handle) {
178 xrect[1].x = -ob_rr_theme->bevel;
179 xrect[1].y = FRAME_HANDLE_Y(self);
180 xrect[1].width = self->width + self->bwidth * 2;
181 xrect[1].height = ob_rr_theme->handle_height +
182 self->bwidth * 2;
183 ++num;
184 }
185
186 XShapeCombineRectangles(ob_display, self->window,
187 ShapeBounding, 0, 0, xrect, num,
188 ShapeUnion, Unsorted);
189 }
190 #endif
191 }
192
193 void frame_adjust_area(Frame *self, gboolean moved, gboolean resized)
194 {
195 if (resized) {
196 if (self->client->decorations & Decor_Border) {
197 self->bwidth = ob_rr_theme->bwidth;
198 self->cbwidth = ob_rr_theme->cbwidth;
199 } else {
200 self->bwidth = self->cbwidth = 0;
201 }
202 STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
203 self->cbwidth, self->cbwidth);
204 self->width = self->client->area.width + self->cbwidth * 2;
205 g_assert(self->width > 0);
206
207 /* set border widths */
208 XSetWindowBorderWidth(ob_display, self->plate, self->cbwidth);
209 XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
210 XSetWindowBorderWidth(ob_display, self->title, self->bwidth);
211 XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
212 XSetWindowBorderWidth(ob_display, self->lgrip, self->bwidth);
213 XSetWindowBorderWidth(ob_display, self->rgrip, self->bwidth);
214
215 /* position/size and map/unmap all the windows */
216
217 /* they all default off, they're turned on in layout_title */
218 self->icon_x = -1;
219 self->desk_x = -1;
220 self->shade_x = -1;
221 self->iconify_x = -1;
222 self->label_x = -1;
223 self->max_x = -1;
224 self->close_x = -1;
225
226 if (self->client->decorations & Decor_Titlebar) {
227 XMoveResizeWindow(ob_display, self->title,
228 -self->bwidth, -self->bwidth,
229 self->width, ob_rr_theme->title_height);
230 self->innersize.top += ob_rr_theme->title_height + self->bwidth;
231 XMapWindow(ob_display, self->title);
232
233 /* layout the title bar elements */
234 layout_title(self);
235 } else
236 XUnmapWindow(ob_display, self->title);
237
238 if (self->client->decorations & Decor_Handle) {
239 XMoveResizeWindow(ob_display, self->handle,
240 -self->bwidth, FRAME_HANDLE_Y(self),
241 self->width, ob_rr_theme->handle_height);
242 XMoveWindow(ob_display, self->lgrip,
243 -self->bwidth, -self->bwidth);
244 XMoveWindow(ob_display, self->rgrip,
245 -self->bwidth + self->width -
246 ob_rr_theme->grip_width, -self->bwidth);
247 self->innersize.bottom += ob_rr_theme->handle_height +
248 self->bwidth;
249 XMapWindow(ob_display, self->handle);
250
251 /* XXX make a subwindow with these dimentions?
252 ob_rr_theme->grip_width + self->bwidth, 0,
253 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
254 ob_rr_theme->handle_height);
255 */
256 } else
257 XUnmapWindow(ob_display, self->handle);
258 }
259
260 if (resized) {
261 /* move and resize the plate */
262 XMoveResizeWindow(ob_display, self->plate,
263 self->innersize.left - self->cbwidth,
264 self->innersize.top - self->cbwidth,
265 self->client->area.width,
266 self->client->area.height);
267 /* when the client has StaticGravity, it likes to move around. */
268 XMoveWindow(ob_display, self->client->window, 0, 0);
269 }
270
271 if (resized) {
272 STRUT_SET(self->size,
273 self->innersize.left + self->bwidth,
274 self->innersize.top + self->bwidth,
275 self->innersize.right + self->bwidth,
276 self->innersize.bottom + self->bwidth);
277 }
278
279 /* shading can change without being moved or resized */
280 RECT_SET_SIZE(self->area,
281 self->client->area.width +
282 self->size.left + self->size.right,
283 (self->client->shaded ? ob_rr_theme->title_height + self->bwidth*2:
284 self->client->area.height +
285 self->size.top + self->size.bottom));
286
287 if (moved) {
288 /* find the new coordinates, done after setting the frame.size, for
289 frame_client_gravity. */
290 self->area.x = self->client->area.x;
291 self->area.y = self->client->area.y;
292 frame_client_gravity((Frame*)self,
293 &self->area.x, &self->area.y);
294 }
295
296 /* move and resize the top level frame.
297 shading can change without being moved or resized */
298 XMoveResizeWindow(ob_display, self->window,
299 self->area.x, self->area.y,
300 self->width,
301 self->area.height - self->bwidth * 2);
302
303 if (resized) {
304 framerender_frame(self);
305
306 frame_adjust_shape(self);
307 }
308 }
309
310 void frame_adjust_state(Frame *self)
311 {
312 framerender_frame(self);
313 }
314
315 void frame_adjust_focus(Frame *self, gboolean hilite)
316 {
317 self->focused = hilite;
318 framerender_frame(self);
319 }
320
321 void frame_adjust_title(Frame *self)
322 {
323 framerender_frame(self);
324 }
325
326 void frame_adjust_icon(Frame *self)
327 {
328 framerender_frame(self);
329 }
330
331 void frame_grab_client(Frame *self, Client *client)
332 {
333 self->client = client;
334
335 /* reparent the client to the frame */
336 XReparentWindow(ob_display, client->window, self->plate, 0, 0);
337 /*
338 When reparenting the client window, it is usually not mapped yet, since
339 this occurs from a MapRequest. However, in the case where Openbox is
340 starting up, the window is already mapped, so we'll see unmap events for
341 it. There are 2 unmap events generated that we see, one with the 'event'
342 member set the root window, and one set to the client, but both get
343 handled and need to be ignored.
344 */
345 if (ob_state == State_Starting)
346 client->ignore_unmaps += 2;
347
348 /* select the event mask on the client's parent (to receive config/map
349 req's) the ButtonPress is to catch clicks on the client border */
350 XSelectInput(ob_display, self->plate, PLATE_EVENTMASK);
351
352 /* map the client so it maps when the frame does */
353 XMapWindow(ob_display, client->window);
354
355 frame_adjust_area(self, TRUE, TRUE);
356
357 /* set all the windows for the frame in the window_map */
358 g_hash_table_insert(window_map, &self->window, client);
359 g_hash_table_insert(window_map, &self->plate, client);
360 g_hash_table_insert(window_map, &self->title, client);
361 g_hash_table_insert(window_map, &self->label, client);
362 g_hash_table_insert(window_map, &self->max, client);
363 g_hash_table_insert(window_map, &self->close, client);
364 g_hash_table_insert(window_map, &self->desk, client);
365 g_hash_table_insert(window_map, &self->shade, client);
366 g_hash_table_insert(window_map, &self->icon, client);
367 g_hash_table_insert(window_map, &self->iconify, client);
368 g_hash_table_insert(window_map, &self->handle, client);
369 g_hash_table_insert(window_map, &self->lgrip, client);
370 g_hash_table_insert(window_map, &self->rgrip, client);
371 }
372
373 void frame_release_client(Frame *self, Client *client)
374 {
375 XEvent ev;
376
377 g_assert(self->client == client);
378
379 /* check if the app has already reparented its window away */
380 if (XCheckTypedWindowEvent(ob_display, client->window,
381 ReparentNotify, &ev)) {
382 XPutBackEvent(ob_display, &ev);
383
384 /* re-map the window since the unmanaging process unmaps it */
385
386 /* XXX ... um no it doesnt it unmaps its parent, the window itself
387 retains its mapped state, no?! XXX
388 XMapWindow(ob_display, client->window); */
389 } else {
390 /* according to the ICCCM - if the client doesn't reparent itself,
391 then we will reparent the window to root for them */
392 XReparentWindow(ob_display, client->window, ob_root,
393 client->area.x,
394 client->area.y);
395 }
396
397 /* remove all the windows for the frame from the window_map */
398 g_hash_table_remove(window_map, &self->window);
399 g_hash_table_remove(window_map, &self->plate);
400 g_hash_table_remove(window_map, &self->title);
401 g_hash_table_remove(window_map, &self->label);
402 g_hash_table_remove(window_map, &self->max);
403 g_hash_table_remove(window_map, &self->close);
404 g_hash_table_remove(window_map, &self->desk);
405 g_hash_table_remove(window_map, &self->shade);
406 g_hash_table_remove(window_map, &self->icon);
407 g_hash_table_remove(window_map, &self->iconify);
408 g_hash_table_remove(window_map, &self->handle);
409 g_hash_table_remove(window_map, &self->lgrip);
410 g_hash_table_remove(window_map, &self->rgrip);
411
412 frame_free(self);
413 }
414
415 static void layout_title(Frame *self)
416 {
417 char *lc;
418 int x;
419 gboolean n, d, i, l, m, c, s;
420
421 n = d = i = l = m = c = s = FALSE;
422
423 /* figure out whats being shown, and the width of the label */
424 self->label_width = self->width - (ob_rr_theme->bevel + 1) * 2;
425 for (lc = ob_rr_theme->title_layout; *lc != '\0'; ++lc) {
426 switch (*lc) {
427 case 'N':
428 if (!(self->client->decorations & Decor_Icon)) break;
429 if (n) { *lc = ' '; break; } /* rm duplicates */
430 n = TRUE;
431 self->label_width -= (ob_rr_theme->button_size + 2 +
432 ob_rr_theme->bevel + 1);
433 break;
434 case 'D':
435 if (!(self->client->decorations & Decor_AllDesktops)) break;
436 if (d) { *lc = ' '; break; } /* rm duplicates */
437 d = TRUE;
438 self->label_width -= (ob_rr_theme->button_size +
439 ob_rr_theme->bevel + 1);
440 break;
441 case 'S':
442 if (!(self->client->decorations & Decor_Shade)) break;
443 if (s) { *lc = ' '; break; } /* rm duplicates */
444 s = TRUE;
445 self->label_width -= (ob_rr_theme->button_size +
446 ob_rr_theme->bevel + 1);
447 break;
448 case 'I':
449 if (!(self->client->decorations & Decor_Iconify)) break;
450 if (i) { *lc = ' '; break; } /* rm duplicates */
451 i = TRUE;
452 self->label_width -= (ob_rr_theme->button_size +
453 ob_rr_theme->bevel + 1);
454 break;
455 case 'L':
456 if (l) { *lc = ' '; break; } /* rm duplicates */
457 l = TRUE;
458 break;
459 case 'M':
460 if (!(self->client->decorations & Decor_Maximize)) break;
461 if (m) { *lc = ' '; break; } /* rm duplicates */
462 m = TRUE;
463 self->label_width -= (ob_rr_theme->button_size +
464 ob_rr_theme->bevel + 1);
465 break;
466 case 'C':
467 if (!(self->client->decorations & Decor_Close)) break;
468 if (c) { *lc = ' '; break; } /* rm duplicates */
469 c = TRUE;
470 self->label_width -= (ob_rr_theme->button_size +
471 ob_rr_theme->bevel + 1);
472 break;
473 }
474 }
475 if (self->label_width < 1) self->label_width = 1;
476
477 XResizeWindow(ob_display, self->label, self->label_width,
478 ob_rr_theme->label_height);
479
480 if (!n) XUnmapWindow(ob_display, self->icon);
481 if (!d) XUnmapWindow(ob_display, self->desk);
482 if (!s) XUnmapWindow(ob_display, self->shade);
483 if (!i) XUnmapWindow(ob_display, self->iconify);
484 if (!l) XUnmapWindow(ob_display, self->label);
485 if (!m) XUnmapWindow(ob_display, self->max);
486 if (!c) XUnmapWindow(ob_display, self->close);
487
488 x = ob_rr_theme->bevel + 1;
489 for (lc = ob_rr_theme->title_layout; *lc != '\0'; ++lc) {
490 switch (*lc) {
491 case 'N':
492 if (!n) break;
493 self->icon_x = x;
494 XMapWindow(ob_display, self->icon);
495 XMoveWindow(ob_display, self->icon, x, ob_rr_theme->bevel);
496 x += ob_rr_theme->button_size + 2 + ob_rr_theme->bevel + 1;
497 break;
498 case 'D':
499 if (!d) break;
500 self->desk_x = x;
501 XMapWindow(ob_display, self->desk);
502 XMoveWindow(ob_display, self->desk, x, ob_rr_theme->bevel + 1);
503 x += ob_rr_theme->button_size + ob_rr_theme->bevel + 1;
504 break;
505 case 'S':
506 if (!s) break;
507 self->shade_x = x;
508 XMapWindow(ob_display, self->shade);
509 XMoveWindow(ob_display, self->shade, x, ob_rr_theme->bevel + 1);
510 x += ob_rr_theme->button_size + ob_rr_theme->bevel + 1;
511 break;
512 case 'I':
513 if (!i) break;
514 self->iconify_x = x;
515 XMapWindow(ob_display, self->iconify);
516 XMoveWindow(ob_display, self->iconify, x, ob_rr_theme->bevel + 1);
517 x += ob_rr_theme->button_size + ob_rr_theme->bevel + 1;
518 break;
519 case 'L':
520 if (!l) break;
521 self->label_x = x;
522 XMapWindow(ob_display, self->label);
523 XMoveWindow(ob_display, self->label, x, ob_rr_theme->bevel);
524 x += self->label_width + ob_rr_theme->bevel + 1;
525 break;
526 case 'M':
527 if (!m) break;
528 self->max_x = x;
529 XMapWindow(ob_display, self->max);
530 XMoveWindow(ob_display, self->max, x, ob_rr_theme->bevel + 1);
531 x += ob_rr_theme->button_size + ob_rr_theme->bevel + 1;
532 break;
533 case 'C':
534 if (!c) break;
535 self->close_x = x;
536 XMapWindow(ob_display, self->close);
537 XMoveWindow(ob_display, self->close, x, ob_rr_theme->bevel + 1);
538 x += ob_rr_theme->button_size + ob_rr_theme->bevel + 1;
539 break;
540 }
541 }
542 }
543
544 Context frame_context_from_string(char *name)
545 {
546 if (!g_ascii_strcasecmp("root", name))
547 return Context_Root;
548 else if (!g_ascii_strcasecmp("client", name))
549 return Context_Client;
550 else if (!g_ascii_strcasecmp("titlebar", name))
551 return Context_Titlebar;
552 else if (!g_ascii_strcasecmp("handle", name))
553 return Context_Handle;
554 else if (!g_ascii_strcasecmp("frame", name))
555 return Context_Frame;
556 else if (!g_ascii_strcasecmp("blcorner", name))
557 return Context_BLCorner;
558 else if (!g_ascii_strcasecmp("tlcorner", name))
559 return Context_TLCorner;
560 else if (!g_ascii_strcasecmp("brcorner", name))
561 return Context_BRCorner;
562 else if (!g_ascii_strcasecmp("trcorner", name))
563 return Context_TRCorner;
564 else if (!g_ascii_strcasecmp("maximize", name))
565 return Context_Maximize;
566 else if (!g_ascii_strcasecmp("alldesktops", name))
567 return Context_AllDesktops;
568 else if (!g_ascii_strcasecmp("shade", name))
569 return Context_Shade;
570 else if (!g_ascii_strcasecmp("iconify", name))
571 return Context_Iconify;
572 else if (!g_ascii_strcasecmp("icon", name))
573 return Context_Icon;
574 else if (!g_ascii_strcasecmp("close", name))
575 return Context_Close;
576 return Context_None;
577 }
578
579 Context frame_context(Client *client, Window win)
580 {
581 Frame *self;
582
583 if (win == ob_root) return Context_Root;
584 if (client == NULL) return Context_None;
585 if (win == client->window) return Context_Client;
586
587 self = client->frame;
588 if (win == self->window) return Context_Frame;
589 if (win == self->plate) return Context_Client;
590 if (win == self->title) return Context_Titlebar;
591 if (win == self->label) return Context_Titlebar;
592 if (win == self->handle) return Context_Handle;
593 if (win == self->lgrip) return Context_BLCorner;
594 if (win == self->rgrip) return Context_BRCorner;
595 if (win == self->max) return Context_Maximize;
596 if (win == self->iconify)return Context_Iconify;
597 if (win == self->close) return Context_Close;
598 if (win == self->icon) return Context_Icon;
599 if (win == self->desk) return Context_AllDesktops;
600 if (win == self->shade) return Context_Shade;
601
602 return Context_None;
603 }
604
605 void frame_client_gravity(Frame *self, int *x, int *y)
606 {
607 /* horizontal */
608 switch (self->client->gravity) {
609 default:
610 case NorthWestGravity:
611 case SouthWestGravity:
612 case WestGravity:
613 break;
614
615 case NorthGravity:
616 case SouthGravity:
617 case CenterGravity:
618 *x -= (self->size.left + self->size.right) / 2;
619 break;
620
621 case NorthEastGravity:
622 case SouthEastGravity:
623 case EastGravity:
624 *x -= self->size.left + self->size.right;
625 break;
626
627 case ForgetGravity:
628 case StaticGravity:
629 *x -= self->size.left;
630 break;
631 }
632
633 /* vertical */
634 switch (self->client->gravity) {
635 default:
636 case NorthWestGravity:
637 case NorthEastGravity:
638 case NorthGravity:
639 break;
640
641 case CenterGravity:
642 case EastGravity:
643 case WestGravity:
644 *y -= (self->size.top + self->size.bottom) / 2;
645 break;
646
647 case SouthWestGravity:
648 case SouthEastGravity:
649 case SouthGravity:
650 *y -= self->size.top + self->size.bottom;
651 break;
652
653 case ForgetGravity:
654 case StaticGravity:
655 *y -= self->size.top;
656 break;
657 }
658 }
659
660 void frame_frame_gravity(Frame *self, int *x, int *y)
661 {
662 /* horizontal */
663 switch (self->client->gravity) {
664 default:
665 case NorthWestGravity:
666 case WestGravity:
667 case SouthWestGravity:
668 break;
669 case NorthGravity:
670 case CenterGravity:
671 case SouthGravity:
672 *x += (self->size.left + self->size.right) / 2;
673 break;
674 case NorthEastGravity:
675 case EastGravity:
676 case SouthEastGravity:
677 *x += self->size.left + self->size.right;
678 break;
679 case StaticGravity:
680 case ForgetGravity:
681 *x += self->size.left;
682 break;
683 }
684
685 /* vertical */
686 switch (self->client->gravity) {
687 default:
688 case NorthWestGravity:
689 case WestGravity:
690 case SouthWestGravity:
691 break;
692 case NorthGravity:
693 case CenterGravity:
694 case SouthGravity:
695 *y += (self->size.top + self->size.bottom) / 2;
696 break;
697 case NorthEastGravity:
698 case EastGravity:
699 case SouthEastGravity:
700 *y += self->size.top + self->size.bottom;
701 break;
702 case StaticGravity:
703 case ForgetGravity:
704 *y += self->size.top;
705 break;
706 }
707 }
This page took 0.069542 seconds and 4 git commands to generate.