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