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