]> Dogcows Code - chaz/openbox/blob - openbox/frame.c
use the new sm_client_id function so all windows who should save state do. session...
[chaz/openbox] / openbox / frame.c
1 #include "frame.h"
2 #include "client.h"
3 #include "openbox.h"
4 #include "extensions.h"
5 #include "config.h"
6 #include "framerender.h"
7 #include "render/theme.h"
8
9 #define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
10 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
11 ButtonPressMask | ButtonReleaseMask)
12 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
13 ButtonMotionMask | ExposureMask | \
14 EnterWindowMask | LeaveWindowMask)
15
16 #define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
17 f->cbwidth)
18
19 static void layout_title(ObFrame *self);
20
21 static Window createWindow(Window parent, unsigned long mask,
22 XSetWindowAttributes *attrib)
23 {
24 return XCreateWindow(ob_display, parent, 0, 0, 1, 1, 0,
25 RrDepth(ob_rr_inst), InputOutput,
26 RrVisual(ob_rr_inst), mask, attrib);
27
28 }
29
30 ObFrame *frame_new()
31 {
32 XSetWindowAttributes attrib;
33 unsigned long mask;
34 ObFrame *self;
35
36 self = g_new(ObFrame, 1);
37
38 self->visible = FALSE;
39 self->decorations = 0;
40
41 /* create all of the decor windows */
42 mask = CWOverrideRedirect | CWEventMask;
43 attrib.event_mask = FRAME_EVENTMASK;
44 attrib.override_redirect = TRUE;
45 self->window = createWindow(RootWindow(ob_display, ob_screen),
46 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_cursor(OB_CURSOR_SOUTHWEST);
64 self->lgrip = createWindow(self->handle, mask, &attrib);
65 attrib.cursor = ob_cursor(OB_CURSOR_SOUTHEAST);
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 self->max_hover = self->close_hover = self->desk_hover =
112 self->iconify_hover = self->shade_hover = FALSE;
113
114 return (ObFrame*)self;
115 }
116
117 static void frame_free(ObFrame *self)
118 {
119 RrAppearanceFree(self->a_unfocused_title);
120 RrAppearanceFree(self->a_focused_title);
121 RrAppearanceFree(self->a_unfocused_label);
122 RrAppearanceFree(self->a_focused_label);
123 RrAppearanceFree(self->a_unfocused_handle);
124 RrAppearanceFree(self->a_focused_handle);
125 RrAppearanceFree(self->a_icon);
126
127 XDestroyWindow(ob_display, self->window);
128
129 g_free(self);
130 }
131
132 void frame_show(ObFrame *self)
133 {
134 if (!self->visible) {
135 self->visible = TRUE;
136 XMapWindow(ob_display, self->window);
137 }
138 }
139
140 void frame_hide(ObFrame *self)
141 {
142 if (self->visible) {
143 self->visible = FALSE;
144 self->client->ignore_unmaps++;
145 XUnmapWindow(ob_display, self->window);
146 }
147 }
148
149 void frame_adjust_shape(ObFrame *self)
150 {
151 #ifdef SHAPE
152 int num;
153 XRectangle xrect[2];
154
155 if (!self->client->shaped) {
156 /* clear the shape on the frame window */
157 XShapeCombineMask(ob_display, self->window, ShapeBounding,
158 self->innersize.left,
159 self->innersize.top,
160 None, ShapeSet);
161 } else {
162 /* make the frame's shape match the clients */
163 XShapeCombineShape(ob_display, self->window, ShapeBounding,
164 self->innersize.left,
165 self->innersize.top,
166 self->client->window,
167 ShapeBounding, ShapeSet);
168
169 num = 0;
170 if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
171 xrect[0].x = -ob_rr_theme->bevel;
172 xrect[0].y = -ob_rr_theme->bevel;
173 xrect[0].width = self->width + self->bwidth * 2;
174 xrect[0].height = ob_rr_theme->title_height +
175 self->bwidth * 2;
176 ++num;
177 }
178
179 if (self->decorations & OB_FRAME_DECOR_HANDLE) {
180 xrect[1].x = -ob_rr_theme->bevel;
181 xrect[1].y = FRAME_HANDLE_Y(self);
182 xrect[1].width = self->width + self->bwidth * 2;
183 xrect[1].height = ob_rr_theme->handle_height +
184 self->bwidth * 2;
185 ++num;
186 }
187
188 XShapeCombineRectangles(ob_display, self->window,
189 ShapeBounding, 0, 0, xrect, num,
190 ShapeUnion, Unsorted);
191 }
192 #endif
193 }
194
195 void frame_adjust_area(ObFrame *self, gboolean moved, gboolean resized)
196 {
197 if (resized) {
198 self->decorations = self->client->decorations;
199 if (self->decorations & OB_FRAME_DECOR_BORDER) {
200 self->bwidth = ob_rr_theme->bwidth;
201 self->cbwidth = ob_rr_theme->cbwidth;
202 } else {
203 self->bwidth = self->cbwidth = 0;
204 }
205 STRUT_SET(self->innersize, self->cbwidth, self->cbwidth,
206 self->cbwidth, self->cbwidth);
207 self->width = self->client->area.width + self->cbwidth * 2;
208 g_assert(self->width > 0);
209
210 /* set border widths */
211 XSetWindowBorderWidth(ob_display, self->plate, self->cbwidth);
212 XSetWindowBorderWidth(ob_display, self->window, self->bwidth);
213 XSetWindowBorderWidth(ob_display, self->title, self->bwidth);
214 XSetWindowBorderWidth(ob_display, self->handle, self->bwidth);
215 XSetWindowBorderWidth(ob_display, self->lgrip, self->bwidth);
216 XSetWindowBorderWidth(ob_display, self->rgrip, self->bwidth);
217
218 /* position/size and map/unmap all the windows */
219
220 /* they all default off, they're turned on in layout_title */
221 self->icon_x = -1;
222 self->desk_x = -1;
223 self->shade_x = -1;
224 self->iconify_x = -1;
225 self->label_x = -1;
226 self->max_x = -1;
227 self->close_x = -1;
228
229 if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
230 XMoveResizeWindow(ob_display, self->title,
231 -self->bwidth, -self->bwidth,
232 self->width, ob_rr_theme->title_height);
233 self->innersize.top += ob_rr_theme->title_height + self->bwidth;
234 XMapWindow(ob_display, self->title);
235
236 /* layout the title bar elements */
237 layout_title(self);
238 } else
239 XUnmapWindow(ob_display, self->title);
240
241 if (self->decorations & OB_FRAME_DECOR_HANDLE) {
242 XMoveResizeWindow(ob_display, self->handle,
243 -self->bwidth, FRAME_HANDLE_Y(self),
244 self->width, ob_rr_theme->handle_height);
245 self->innersize.bottom += ob_rr_theme->handle_height +
246 self->bwidth;
247 XMapWindow(ob_display, self->handle);
248
249 if (self->decorations & OB_FRAME_DECOR_GRIPS) {
250 XMoveWindow(ob_display, self->lgrip,
251 -self->bwidth, -self->bwidth);
252 XMoveWindow(ob_display, self->rgrip,
253 -self->bwidth + self->width -
254 ob_rr_theme->grip_width, -self->bwidth);
255 XMapWindow(ob_display, self->lgrip);
256 XMapWindow(ob_display, self->rgrip);
257 } else {
258 XUnmapWindow(ob_display, self->lgrip);
259 XUnmapWindow(ob_display, self->rgrip);
260 }
261
262 /* XXX make a subwindow with these dimentions?
263 ob_rr_theme->grip_width + self->bwidth, 0,
264 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
265 ob_rr_theme->handle_height);
266 */
267 } else
268 XUnmapWindow(ob_display, self->handle);
269
270 /* move and resize the plate */
271 XMoveResizeWindow(ob_display, self->plate,
272 self->innersize.left - self->cbwidth,
273 self->innersize.top - self->cbwidth,
274 self->client->area.width,
275 self->client->area.height);
276 /* when the client has StaticGravity, it likes to move around. */
277 XMoveWindow(ob_display, self->client->window, 0, 0);
278
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 ?
291 ob_rr_theme->title_height + self->bwidth*2:
292 self->client->area.height +
293 self->size.top + self->size.bottom));
294
295 if (moved) {
296 /* find the new coordinates, done after setting the frame.size, for
297 frame_client_gravity. */
298 self->area.x = self->client->area.x;
299 self->area.y = self->client->area.y;
300 frame_client_gravity(self, &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 = config_title_layout; *lc != '\0'; ++lc) {
434 switch (*lc) {
435 case 'N':
436 if (n) { *lc = ' '; break; } /* rm duplicates */
437 n = TRUE;
438 self->label_width -= (ob_rr_theme->button_size + 2 +
439 ob_rr_theme->bevel + 1);
440 break;
441 case 'D':
442 if (d) { *lc = ' '; break; } /* rm duplicates */
443 d = TRUE;
444 self->label_width -= (ob_rr_theme->button_size +
445 ob_rr_theme->bevel + 1);
446 break;
447 case 'S':
448 if (s) { *lc = ' '; break; } /* rm duplicates */
449 s = TRUE;
450 self->label_width -= (ob_rr_theme->button_size +
451 ob_rr_theme->bevel + 1);
452 break;
453 case 'I':
454 if (i) { *lc = ' '; break; } /* rm duplicates */
455 i = TRUE;
456 self->label_width -= (ob_rr_theme->button_size +
457 ob_rr_theme->bevel + 1);
458 break;
459 case 'L':
460 if (l) { *lc = ' '; break; } /* rm duplicates */
461 l = TRUE;
462 break;
463 case 'M':
464 if (m) { *lc = ' '; break; } /* rm duplicates */
465 m = TRUE;
466 self->label_width -= (ob_rr_theme->button_size +
467 ob_rr_theme->bevel + 1);
468 break;
469 case 'C':
470 if (c) { *lc = ' '; break; } /* rm duplicates */
471 c = TRUE;
472 self->label_width -= (ob_rr_theme->button_size +
473 ob_rr_theme->bevel + 1);
474 break;
475 }
476 }
477 if (self->label_width < 1) self->label_width = 1;
478
479 XResizeWindow(ob_display, self->label, self->label_width,
480 ob_rr_theme->label_height);
481
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);
489
490 x = ob_rr_theme->bevel + 1;
491 for (lc = config_title_layout; *lc != '\0'; ++lc) {
492 switch (*lc) {
493 case 'N':
494 if (!n) break;
495 self->icon_x = x;
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;
499 break;
500 case 'D':
501 if (!d) break;
502 self->desk_x = x;
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;
506 break;
507 case 'S':
508 if (!s) break;
509 self->shade_x = x;
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;
513 break;
514 case 'I':
515 if (!i) break;
516 self->iconify_x = x;
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;
520 break;
521 case 'L':
522 if (!l) break;
523 self->label_x = x;
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;
527 break;
528 case 'M':
529 if (!m) break;
530 self->max_x = x;
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;
534 break;
535 case 'C':
536 if (!c) break;
537 self->close_x = x;
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;
541 break;
542 }
543 }
544 }
545
546 ObFrameContext frame_context_from_string(char *name)
547 {
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;
575 }
576
577 ObFrameContext frame_context(ObClient *client, Window win)
578 {
579 ObFrame *self;
580
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;
584
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;
599
600 return OB_FRAME_CONTEXT_NONE;
601 }
602
603 void frame_client_gravity(ObFrame *self, int *x, int *y)
604 {
605 /* horizontal */
606 switch (self->client->gravity) {
607 default:
608 case NorthWestGravity:
609 case SouthWestGravity:
610 case WestGravity:
611 break;
612
613 case NorthGravity:
614 case SouthGravity:
615 case CenterGravity:
616 *x -= (self->size.left + self->size.right) / 2;
617 break;
618
619 case NorthEastGravity:
620 case SouthEastGravity:
621 case EastGravity:
622 *x -= self->size.left + self->size.right;
623 break;
624
625 case ForgetGravity:
626 case StaticGravity:
627 *x -= self->size.left;
628 break;
629 }
630
631 /* vertical */
632 switch (self->client->gravity) {
633 default:
634 case NorthWestGravity:
635 case NorthEastGravity:
636 case NorthGravity:
637 break;
638
639 case CenterGravity:
640 case EastGravity:
641 case WestGravity:
642 *y -= (self->size.top + self->size.bottom) / 2;
643 break;
644
645 case SouthWestGravity:
646 case SouthEastGravity:
647 case SouthGravity:
648 *y -= self->size.top + self->size.bottom;
649 break;
650
651 case ForgetGravity:
652 case StaticGravity:
653 *y -= self->size.top;
654 break;
655 }
656 }
657
658 void frame_frame_gravity(ObFrame *self, int *x, int *y)
659 {
660 /* horizontal */
661 switch (self->client->gravity) {
662 default:
663 case NorthWestGravity:
664 case WestGravity:
665 case SouthWestGravity:
666 break;
667 case NorthGravity:
668 case CenterGravity:
669 case SouthGravity:
670 *x += (self->size.left + self->size.right) / 2;
671 break;
672 case NorthEastGravity:
673 case EastGravity:
674 case SouthEastGravity:
675 *x += self->size.left + self->size.right;
676 break;
677 case StaticGravity:
678 case ForgetGravity:
679 *x += self->size.left;
680 break;
681 }
682
683 /* vertical */
684 switch (self->client->gravity) {
685 default:
686 case NorthWestGravity:
687 case WestGravity:
688 case SouthWestGravity:
689 break;
690 case NorthGravity:
691 case CenterGravity:
692 case SouthGravity:
693 *y += (self->size.top + self->size.bottom) / 2;
694 break;
695 case NorthEastGravity:
696 case EastGravity:
697 case SouthEastGravity:
698 *y += self->size.top + self->size.bottom;
699 break;
700 case StaticGravity:
701 case ForgetGravity:
702 *y += self->size.top;
703 break;
704 }
705 }
This page took 0.069707 seconds and 4 git commands to generate.