4 #include "extensions.h"
6 #include "framerender.h"
7 #include "render/theme.h"
9 #define PLATE_EVENTMASK (SubstructureRedirectMask | ButtonPressMask)
10 #define FRAME_EVENTMASK (EnterWindowMask | LeaveWindowMask | \
11 ButtonPressMask | ButtonReleaseMask | \
13 #define ELEMENT_EVENTMASK (ButtonPressMask | ButtonReleaseMask | \
14 ButtonMotionMask | ExposureMask | \
15 EnterWindowMask | LeaveWindowMask)
17 #define FRAME_HANDLE_Y(f) (f->innersize.top + f->client->area.height + \
20 static void layout_title(ObFrame
*self
);
22 static Window
createWindow(Window parent
, unsigned long mask
,
23 XSetWindowAttributes
*attrib
)
25 return XCreateWindow(ob_display
, parent
, 0, 0, 1, 1, 0,
26 RrDepth(ob_rr_inst
), InputOutput
,
27 RrVisual(ob_rr_inst
), mask
, attrib
);
33 XSetWindowAttributes attrib
;
37 self
= g_new(ObFrame
, 1);
39 self
->visible
= FALSE
;
40 self
->obscured
= TRUE
;
41 self
->decorations
= 0;
43 /* create all of the decor windows */
44 mask
= CWOverrideRedirect
| CWEventMask
;
45 attrib
.event_mask
= FRAME_EVENTMASK
;
46 attrib
.override_redirect
= TRUE
;
47 self
->window
= createWindow(RootWindow(ob_display
, ob_screen
),
51 self
->plate
= createWindow(self
->window
, mask
, &attrib
);
54 attrib
.event_mask
= ELEMENT_EVENTMASK
;
55 self
->title
= createWindow(self
->window
, mask
, &attrib
);
58 attrib
.cursor
= ob_cursor(OB_CURSOR_NORTHWEST
);
59 self
->tlresize
= createWindow(self
->title
, mask
, &attrib
);
60 attrib
.cursor
= ob_cursor(OB_CURSOR_NORTHEAST
);
61 self
->trresize
= createWindow(self
->title
, mask
, &attrib
);
64 self
->label
= createWindow(self
->title
, mask
, &attrib
);
65 self
->max
= createWindow(self
->title
, mask
, &attrib
);
66 self
->close
= createWindow(self
->title
, mask
, &attrib
);
67 self
->desk
= createWindow(self
->title
, mask
, &attrib
);
68 self
->shade
= createWindow(self
->title
, mask
, &attrib
);
69 self
->icon
= createWindow(self
->title
, mask
, &attrib
);
70 self
->iconify
= createWindow(self
->title
, mask
, &attrib
);
71 self
->handle
= createWindow(self
->window
, mask
, &attrib
);
74 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHWEST
);
75 self
->lgrip
= createWindow(self
->handle
, mask
, &attrib
);
76 attrib
.cursor
= ob_cursor(OB_CURSOR_SOUTHEAST
);
77 self
->rgrip
= createWindow(self
->handle
, mask
, &attrib
);
79 self
->focused
= FALSE
;
81 /* the other stuff is shown based on decor settings */
82 XMapWindow(ob_display
, self
->plate
);
83 XMapWindow(ob_display
, self
->lgrip
);
84 XMapWindow(ob_display
, self
->rgrip
);
85 XMapWindow(ob_display
, self
->label
);
87 /* set colors/appearance/sizes for stuff that doesn't change */
88 XSetWindowBorder(ob_display
, self
->window
, ob_rr_theme
->b_color
->pixel
);
89 XSetWindowBorder(ob_display
, self
->title
, ob_rr_theme
->b_color
->pixel
);
90 XSetWindowBorder(ob_display
, self
->handle
, ob_rr_theme
->b_color
->pixel
);
91 XSetWindowBorder(ob_display
, self
->rgrip
, ob_rr_theme
->b_color
->pixel
);
92 XSetWindowBorder(ob_display
, self
->lgrip
, ob_rr_theme
->b_color
->pixel
);
94 XResizeWindow(ob_display
, self
->max
,
95 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
96 XResizeWindow(ob_display
, self
->iconify
,
97 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
98 XResizeWindow(ob_display
, self
->icon
,
99 ob_rr_theme
->button_size
+ 2, ob_rr_theme
->button_size
+ 2);
100 XResizeWindow(ob_display
, self
->close
,
101 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
102 XResizeWindow(ob_display
, self
->desk
,
103 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
104 XResizeWindow(ob_display
, self
->shade
,
105 ob_rr_theme
->button_size
, ob_rr_theme
->button_size
);
106 XResizeWindow(ob_display
, self
->lgrip
,
107 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
108 XResizeWindow(ob_display
, self
->rgrip
,
109 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
110 XResizeWindow(ob_display
, self
->tlresize
,
111 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
112 XResizeWindow(ob_display
, self
->trresize
,
113 ob_rr_theme
->grip_width
, ob_rr_theme
->handle_height
);
115 /* set up the dynamic appearances */
116 self
->a_unfocused_title
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_title
);
117 self
->a_focused_title
= RrAppearanceCopy(ob_rr_theme
->a_focused_title
);
118 self
->a_unfocused_label
= RrAppearanceCopy(ob_rr_theme
->a_unfocused_label
);
119 self
->a_focused_label
= RrAppearanceCopy(ob_rr_theme
->a_focused_label
);
120 self
->a_unfocused_handle
=
121 RrAppearanceCopy(ob_rr_theme
->a_unfocused_handle
);
122 self
->a_focused_handle
= RrAppearanceCopy(ob_rr_theme
->a_focused_handle
);
123 self
->a_icon
= RrAppearanceCopy(ob_rr_theme
->a_icon
);
125 self
->max_press
= self
->close_press
= self
->desk_press
=
126 self
->iconify_press
= self
->shade_press
= FALSE
;
127 self
->max_hover
= self
->close_hover
= self
->desk_hover
=
128 self
->iconify_hover
= self
->shade_hover
= FALSE
;
130 return (ObFrame
*)self
;
133 static void frame_free(ObFrame
*self
)
135 RrAppearanceFree(self
->a_unfocused_title
);
136 RrAppearanceFree(self
->a_focused_title
);
137 RrAppearanceFree(self
->a_unfocused_label
);
138 RrAppearanceFree(self
->a_focused_label
);
139 RrAppearanceFree(self
->a_unfocused_handle
);
140 RrAppearanceFree(self
->a_focused_handle
);
141 RrAppearanceFree(self
->a_icon
);
143 XDestroyWindow(ob_display
, self
->window
);
148 void frame_show(ObFrame
*self
)
150 if (!self
->visible
) {
151 self
->visible
= TRUE
;
152 XMapWindow(ob_display
, self
->window
);
156 void frame_hide(ObFrame
*self
)
159 self
->visible
= FALSE
;
160 self
->client
->ignore_unmaps
++;
161 XUnmapWindow(ob_display
, self
->window
);
165 void frame_adjust_shape(ObFrame
*self
)
171 if (!self
->client
->shaped
) {
172 /* clear the shape on the frame window */
173 XShapeCombineMask(ob_display
, self
->window
, ShapeBounding
,
174 self
->innersize
.left
,
178 /* make the frame's shape match the clients */
179 XShapeCombineShape(ob_display
, self
->window
, ShapeBounding
,
180 self
->innersize
.left
,
182 self
->client
->window
,
183 ShapeBounding
, ShapeSet
);
186 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
187 xrect
[0].x
= -ob_rr_theme
->bwidth
;
188 xrect
[0].y
= -ob_rr_theme
->bwidth
;
189 xrect
[0].width
= self
->width
+ self
->rbwidth
* 2;
190 xrect
[0].height
= ob_rr_theme
->title_height
+
195 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
196 xrect
[1].x
= -ob_rr_theme
->bwidth
;
197 xrect
[1].y
= FRAME_HANDLE_Y(self
);
198 xrect
[1].width
= self
->width
+ self
->rbwidth
* 2;
199 xrect
[1].height
= ob_rr_theme
->handle_height
+
204 XShapeCombineRectangles(ob_display
, self
->window
,
205 ShapeBounding
, 0, 0, xrect
, num
,
206 ShapeUnion
, Unsorted
);
211 void frame_adjust_area(ObFrame
*self
, gboolean moved
,
212 gboolean resized
, gboolean fake
)
215 self
->decorations
= self
->client
->decorations
;
216 self
->max_horz
= self
->client
->max_horz
;
218 if (self
->decorations
& OB_FRAME_DECOR_BORDER
) {
219 self
->bwidth
= ob_rr_theme
->bwidth
;
220 self
->cbwidth_x
= self
->cbwidth_y
= ob_rr_theme
->cbwidth
;
222 self
->bwidth
= self
->cbwidth_x
= self
->cbwidth_y
= 0;
224 self
->rbwidth
= self
->bwidth
;
227 self
->bwidth
= self
->cbwidth_x
= 0;
229 STRUT_SET(self
->innersize
,
234 self
->width
= self
->client
->area
.width
+ self
->cbwidth_x
* 2 -
235 (self
->max_horz
? self
->rbwidth
* 2 : 0);
236 self
->width
= MAX(self
->width
, 1); /* no lower than 1 */
238 /* set border widths */
240 XSetWindowBorderWidth(ob_display
, self
->window
, self
->bwidth
);
241 XSetWindowBorderWidth(ob_display
, self
->title
, self
->rbwidth
);
242 XSetWindowBorderWidth(ob_display
, self
->handle
, self
->rbwidth
);
243 XSetWindowBorderWidth(ob_display
, self
->lgrip
, self
->rbwidth
);
244 XSetWindowBorderWidth(ob_display
, self
->rgrip
, self
->rbwidth
);
247 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
)
248 self
->innersize
.top
+= ob_rr_theme
->title_height
+ self
->rbwidth
+
249 (self
->rbwidth
- self
->bwidth
);
250 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
)
251 self
->innersize
.bottom
+= ob_rr_theme
->handle_height
+
252 self
->rbwidth
+ (self
->rbwidth
- self
->bwidth
);
254 /* they all default off, they're turned on in layout_title */
258 self
->iconify_x
= -1;
263 /* position/size and map/unmap all the windows */
266 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
) {
267 XMoveResizeWindow(ob_display
, self
->title
,
268 -self
->bwidth
, -self
->bwidth
,
269 self
->width
, ob_rr_theme
->title_height
);
270 XMapWindow(ob_display
, self
->title
);
272 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
273 XMoveWindow(ob_display
, self
->tlresize
, 0, 0);
274 XMoveWindow(ob_display
, self
->trresize
,
275 self
->width
- ob_rr_theme
->grip_width
, 0);
276 XMapWindow(ob_display
, self
->tlresize
);
277 XMapWindow(ob_display
, self
->trresize
);
279 XUnmapWindow(ob_display
, self
->tlresize
);
280 XUnmapWindow(ob_display
, self
->trresize
);
283 XUnmapWindow(ob_display
, self
->title
);
286 if (self
->decorations
& OB_FRAME_DECOR_TITLEBAR
)
287 /* layout the title bar elements */
291 if (self
->decorations
& OB_FRAME_DECOR_HANDLE
) {
292 XMoveResizeWindow(ob_display
, self
->handle
,
293 -self
->bwidth
, FRAME_HANDLE_Y(self
),
294 self
->width
, ob_rr_theme
->handle_height
);
295 XMapWindow(ob_display
, self
->handle
);
297 if (self
->decorations
& OB_FRAME_DECOR_GRIPS
) {
298 XMoveWindow(ob_display
, self
->lgrip
,
299 -self
->rbwidth
, -self
->rbwidth
);
300 XMoveWindow(ob_display
, self
->rgrip
,
301 -self
->rbwidth
+ self
->width
-
302 ob_rr_theme
->grip_width
, -self
->rbwidth
);
303 XMapWindow(ob_display
, self
->lgrip
);
304 XMapWindow(ob_display
, self
->rgrip
);
306 XUnmapWindow(ob_display
, self
->lgrip
);
307 XUnmapWindow(ob_display
, self
->rgrip
);
310 /* XXX make a subwindow with these dimentions?
311 ob_rr_theme->grip_width + self->bwidth, 0,
312 self->width - (ob_rr_theme->grip_width + self->bwidth) * 2,
313 ob_rr_theme->handle_height);
316 XUnmapWindow(ob_display
, self
->handle
);
318 /* move and resize the plate */
319 XMoveResizeWindow(ob_display
, self
->plate
,
320 self
->innersize
.left
- self
->cbwidth_x
,
321 self
->innersize
.top
- self
->cbwidth_y
,
322 self
->client
->area
.width
+ self
->cbwidth_x
* 2,
323 self
->client
->area
.height
+ self
->cbwidth_y
* 2);
324 /* when the client has StaticGravity, it likes to move around. */
325 XMoveWindow(ob_display
, self
->client
->window
,
326 self
->cbwidth_x
, self
->cbwidth_y
);
329 STRUT_SET(self
->size
,
330 self
->innersize
.left
+ self
->bwidth
,
331 self
->innersize
.top
+ self
->bwidth
,
332 self
->innersize
.right
+ self
->bwidth
,
333 self
->innersize
.bottom
+ self
->bwidth
);
336 /* shading can change without being moved or resized */
337 RECT_SET_SIZE(self
->area
,
338 self
->client
->area
.width
+
339 self
->size
.left
+ self
->size
.right
,
340 (self
->client
->shaded
?
341 ob_rr_theme
->title_height
+ self
->rbwidth
* 2:
342 self
->client
->area
.height
+
343 self
->size
.top
+ self
->size
.bottom
));
346 /* find the new coordinates, done after setting the frame.size, for
347 frame_client_gravity. */
348 self
->area
.x
= self
->client
->area
.x
;
349 self
->area
.y
= self
->client
->area
.y
;
350 frame_client_gravity(self
, &self
->area
.x
, &self
->area
.y
);
354 /* move and resize the top level frame.
355 shading can change without being moved or resized */
356 XMoveResizeWindow(ob_display
, self
->window
,
357 self
->area
.x
, self
->area
.y
,
358 self
->area
.width
- self
->bwidth
* 2,
359 self
->area
.height
- self
->bwidth
* 2);
362 framerender_frame(self
);
364 frame_adjust_shape(self
);
369 void frame_adjust_state(ObFrame
*self
)
371 framerender_frame(self
);
374 void frame_adjust_focus(ObFrame
*self
, gboolean hilite
)
376 self
->focused
= hilite
;
377 framerender_frame(self
);
380 void frame_adjust_title(ObFrame
*self
)
382 framerender_frame(self
);
385 void frame_adjust_icon(ObFrame
*self
)
387 framerender_frame(self
);
390 void frame_grab_client(ObFrame
*self
, ObClient
*client
)
392 self
->client
= client
;
394 /* reparent the client to the frame */
395 XReparentWindow(ob_display
, client
->window
, self
->plate
, 0, 0);
397 When reparenting the client window, it is usually not mapped yet, since
398 this occurs from a MapRequest. However, in the case where Openbox is
399 starting up, the window is already mapped, so we'll see unmap events for
400 it. There are 2 unmap events generated that we see, one with the 'event'
401 member set the root window, and one set to the client, but both get
402 handled and need to be ignored.
404 if (ob_state() == OB_STATE_STARTING
)
405 client
->ignore_unmaps
+= 2;
407 /* select the event mask on the client's parent (to receive config/map
408 req's) the ButtonPress is to catch clicks on the client border */
409 XSelectInput(ob_display
, self
->plate
, PLATE_EVENTMASK
);
411 /* map the client so it maps when the frame does */
412 XMapWindow(ob_display
, client
->window
);
414 frame_adjust_area(self
, TRUE
, TRUE
, FALSE
);
416 /* set all the windows for the frame in the window_map */
417 g_hash_table_insert(window_map
, &self
->window
, client
);
418 g_hash_table_insert(window_map
, &self
->plate
, client
);
419 g_hash_table_insert(window_map
, &self
->title
, client
);
420 g_hash_table_insert(window_map
, &self
->label
, client
);
421 g_hash_table_insert(window_map
, &self
->max
, client
);
422 g_hash_table_insert(window_map
, &self
->close
, client
);
423 g_hash_table_insert(window_map
, &self
->desk
, client
);
424 g_hash_table_insert(window_map
, &self
->shade
, client
);
425 g_hash_table_insert(window_map
, &self
->icon
, client
);
426 g_hash_table_insert(window_map
, &self
->iconify
, client
);
427 g_hash_table_insert(window_map
, &self
->handle
, client
);
428 g_hash_table_insert(window_map
, &self
->lgrip
, client
);
429 g_hash_table_insert(window_map
, &self
->rgrip
, client
);
430 g_hash_table_insert(window_map
, &self
->tlresize
, client
);
431 g_hash_table_insert(window_map
, &self
->trresize
, client
);
434 void frame_release_client(ObFrame
*self
, ObClient
*client
)
438 g_assert(self
->client
== client
);
440 /* check if the app has already reparented its window away */
441 if (XCheckTypedWindowEvent(ob_display
, client
->window
,
442 ReparentNotify
, &ev
)) {
443 XPutBackEvent(ob_display
, &ev
);
445 /* re-map the window since the unmanaging process unmaps it */
447 /* XXX ... um no it doesnt it unmaps its parent, the window itself
448 retains its mapped state, no?! XXX
449 XMapWindow(ob_display, client->window); */
451 /* according to the ICCCM - if the client doesn't reparent itself,
452 then we will reparent the window to root for them */
453 XReparentWindow(ob_display
, client
->window
,
454 RootWindow(ob_display
, ob_screen
),
459 /* remove all the windows for the frame from the window_map */
460 g_hash_table_remove(window_map
, &self
->window
);
461 g_hash_table_remove(window_map
, &self
->plate
);
462 g_hash_table_remove(window_map
, &self
->title
);
463 g_hash_table_remove(window_map
, &self
->label
);
464 g_hash_table_remove(window_map
, &self
->max
);
465 g_hash_table_remove(window_map
, &self
->close
);
466 g_hash_table_remove(window_map
, &self
->desk
);
467 g_hash_table_remove(window_map
, &self
->shade
);
468 g_hash_table_remove(window_map
, &self
->icon
);
469 g_hash_table_remove(window_map
, &self
->iconify
);
470 g_hash_table_remove(window_map
, &self
->handle
);
471 g_hash_table_remove(window_map
, &self
->lgrip
);
472 g_hash_table_remove(window_map
, &self
->rgrip
);
473 g_hash_table_remove(window_map
, &self
->tlresize
);
474 g_hash_table_remove(window_map
, &self
->trresize
);
479 static void layout_title(ObFrame
*self
)
483 gboolean n
, d
, i
, l
, m
, c
, s
;
485 n
= d
= i
= l
= m
= c
= s
= FALSE
;
487 /* figure out whats being shown, and the width of the label */
488 self
->label_width
= self
->width
- (ob_rr_theme
->bevel
+ 1) * 2;
489 for (lc
= config_title_layout
; *lc
!= '\0'; ++lc
) {
492 if (n
) { *lc
= ' '; break; } /* rm duplicates */
494 self
->label_width
-= (ob_rr_theme
->button_size
+ 2 +
495 ob_rr_theme
->bevel
+ 1);
498 if (d
) { *lc
= ' '; break; } /* rm duplicates */
500 self
->label_width
-= (ob_rr_theme
->button_size
+
501 ob_rr_theme
->bevel
+ 1);
504 if (s
) { *lc
= ' '; break; } /* rm duplicates */
506 self
->label_width
-= (ob_rr_theme
->button_size
+
507 ob_rr_theme
->bevel
+ 1);
510 if (i
) { *lc
= ' '; break; } /* rm duplicates */
512 self
->label_width
-= (ob_rr_theme
->button_size
+
513 ob_rr_theme
->bevel
+ 1);
516 if (l
) { *lc
= ' '; break; } /* rm duplicates */
520 if (m
) { *lc
= ' '; break; } /* rm duplicates */
522 self
->label_width
-= (ob_rr_theme
->button_size
+
523 ob_rr_theme
->bevel
+ 1);
526 if (c
) { *lc
= ' '; break; } /* rm duplicates */
528 self
->label_width
-= (ob_rr_theme
->button_size
+
529 ob_rr_theme
->bevel
+ 1);
533 if (self
->label_width
< 1) self
->label_width
= 1;
535 XResizeWindow(ob_display
, self
->label
, self
->label_width
,
536 ob_rr_theme
->label_height
);
538 if (!n
) XUnmapWindow(ob_display
, self
->icon
);
539 if (!d
) XUnmapWindow(ob_display
, self
->desk
);
540 if (!s
) XUnmapWindow(ob_display
, self
->shade
);
541 if (!i
) XUnmapWindow(ob_display
, self
->iconify
);
542 if (!l
) XUnmapWindow(ob_display
, self
->label
);
543 if (!m
) XUnmapWindow(ob_display
, self
->max
);
544 if (!c
) XUnmapWindow(ob_display
, self
->close
);
546 x
= ob_rr_theme
->bevel
+ 1;
547 for (lc
= config_title_layout
; *lc
!= '\0'; ++lc
) {
552 XMapWindow(ob_display
, self
->icon
);
553 XMoveWindow(ob_display
, self
->icon
, x
, ob_rr_theme
->bevel
);
554 x
+= ob_rr_theme
->button_size
+ 2 + ob_rr_theme
->bevel
+ 1;
559 XMapWindow(ob_display
, self
->desk
);
560 XMoveWindow(ob_display
, self
->desk
, x
, ob_rr_theme
->bevel
+ 1);
561 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
566 XMapWindow(ob_display
, self
->shade
);
567 XMoveWindow(ob_display
, self
->shade
, x
, ob_rr_theme
->bevel
+ 1);
568 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
573 XMapWindow(ob_display
, self
->iconify
);
574 XMoveWindow(ob_display
, self
->iconify
, x
, ob_rr_theme
->bevel
+ 1);
575 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
580 XMapWindow(ob_display
, self
->label
);
581 XMoveWindow(ob_display
, self
->label
, x
, ob_rr_theme
->bevel
);
582 x
+= self
->label_width
+ ob_rr_theme
->bevel
+ 1;
587 XMapWindow(ob_display
, self
->max
);
588 XMoveWindow(ob_display
, self
->max
, x
, ob_rr_theme
->bevel
+ 1);
589 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
594 XMapWindow(ob_display
, self
->close
);
595 XMoveWindow(ob_display
, self
->close
, x
, ob_rr_theme
->bevel
+ 1);
596 x
+= ob_rr_theme
->button_size
+ ob_rr_theme
->bevel
+ 1;
602 ObFrameContext
frame_context_from_string(char *name
)
604 if (!g_ascii_strcasecmp("desktop", name
))
605 return OB_FRAME_CONTEXT_DESKTOP
;
606 else if (!g_ascii_strcasecmp("client", name
))
607 return OB_FRAME_CONTEXT_CLIENT
;
608 else if (!g_ascii_strcasecmp("titlebar", name
))
609 return OB_FRAME_CONTEXT_TITLEBAR
;
610 else if (!g_ascii_strcasecmp("handle", name
))
611 return OB_FRAME_CONTEXT_HANDLE
;
612 else if (!g_ascii_strcasecmp("frame", name
))
613 return OB_FRAME_CONTEXT_FRAME
;
614 else if (!g_ascii_strcasecmp("tlcorner", name
))
615 return OB_FRAME_CONTEXT_TLCORNER
;
616 else if (!g_ascii_strcasecmp("trcorner", name
))
617 return OB_FRAME_CONTEXT_TRCORNER
;
618 else if (!g_ascii_strcasecmp("blcorner", name
))
619 return OB_FRAME_CONTEXT_BLCORNER
;
620 else if (!g_ascii_strcasecmp("brcorner", name
))
621 return OB_FRAME_CONTEXT_BRCORNER
;
622 else if (!g_ascii_strcasecmp("maximize", name
))
623 return OB_FRAME_CONTEXT_MAXIMIZE
;
624 else if (!g_ascii_strcasecmp("alldesktops", name
))
625 return OB_FRAME_CONTEXT_ALLDESKTOPS
;
626 else if (!g_ascii_strcasecmp("shade", name
))
627 return OB_FRAME_CONTEXT_SHADE
;
628 else if (!g_ascii_strcasecmp("iconify", name
))
629 return OB_FRAME_CONTEXT_ICONIFY
;
630 else if (!g_ascii_strcasecmp("icon", name
))
631 return OB_FRAME_CONTEXT_ICON
;
632 else if (!g_ascii_strcasecmp("close", name
))
633 return OB_FRAME_CONTEXT_CLOSE
;
634 return OB_FRAME_CONTEXT_NONE
;
637 ObFrameContext
frame_context(ObClient
*client
, Window win
)
641 if (win
== RootWindow(ob_display
, ob_screen
))
642 return OB_FRAME_CONTEXT_DESKTOP
;
643 if (client
== NULL
) return OB_FRAME_CONTEXT_NONE
;
644 if (win
== client
->window
) {
645 /* conceptually, this is the desktop, as far as users are
647 if (client
->type
== OB_CLIENT_TYPE_DESKTOP
)
648 return OB_FRAME_CONTEXT_DESKTOP
;
649 return OB_FRAME_CONTEXT_CLIENT
;
652 self
= client
->frame
;
653 if (win
== self
->plate
) {
654 /* conceptually, this is the desktop, as far as users are
656 if (client
->type
== OB_CLIENT_TYPE_DESKTOP
)
657 return OB_FRAME_CONTEXT_DESKTOP
;
658 return OB_FRAME_CONTEXT_CLIENT
;
661 if (win
== self
->window
) return OB_FRAME_CONTEXT_FRAME
;
662 if (win
== self
->title
) return OB_FRAME_CONTEXT_TITLEBAR
;
663 if (win
== self
->label
) return OB_FRAME_CONTEXT_TITLEBAR
;
664 if (win
== self
->handle
) return OB_FRAME_CONTEXT_HANDLE
;
665 if (win
== self
->lgrip
) return OB_FRAME_CONTEXT_BLCORNER
;
666 if (win
== self
->rgrip
) return OB_FRAME_CONTEXT_BRCORNER
;
667 if (win
== self
->tlresize
) return OB_FRAME_CONTEXT_TLCORNER
;
668 if (win
== self
->trresize
) return OB_FRAME_CONTEXT_TRCORNER
;
669 if (win
== self
->max
) return OB_FRAME_CONTEXT_MAXIMIZE
;
670 if (win
== self
->iconify
) return OB_FRAME_CONTEXT_ICONIFY
;
671 if (win
== self
->close
) return OB_FRAME_CONTEXT_CLOSE
;
672 if (win
== self
->icon
) return OB_FRAME_CONTEXT_ICON
;
673 if (win
== self
->desk
) return OB_FRAME_CONTEXT_ALLDESKTOPS
;
674 if (win
== self
->shade
) return OB_FRAME_CONTEXT_SHADE
;
676 return OB_FRAME_CONTEXT_NONE
;
679 void frame_client_gravity(ObFrame
*self
, int *x
, int *y
)
682 switch (self
->client
->gravity
) {
684 case NorthWestGravity
:
685 case SouthWestGravity
:
692 *x
-= (self
->size
.left
+ self
->size
.right
) / 2;
695 case NorthEastGravity
:
696 case SouthEastGravity
:
698 *x
-= self
->size
.left
+ self
->size
.right
;
703 *x
-= self
->size
.left
;
708 switch (self
->client
->gravity
) {
710 case NorthWestGravity
:
711 case NorthEastGravity
:
718 *y
-= (self
->size
.top
+ self
->size
.bottom
) / 2;
721 case SouthWestGravity
:
722 case SouthEastGravity
:
724 *y
-= self
->size
.top
+ self
->size
.bottom
;
729 *y
-= self
->size
.top
;
734 void frame_frame_gravity(ObFrame
*self
, int *x
, int *y
)
737 switch (self
->client
->gravity
) {
739 case NorthWestGravity
:
741 case SouthWestGravity
:
746 *x
+= (self
->size
.left
+ self
->size
.right
) / 2;
748 case NorthEastGravity
:
750 case SouthEastGravity
:
751 *x
+= self
->size
.left
+ self
->size
.right
;
755 *x
+= self
->size
.left
;
760 switch (self
->client
->gravity
) {
762 case NorthWestGravity
:
764 case NorthEastGravity
:
769 *y
+= (self
->size
.top
+ self
->size
.bottom
) / 2;
771 case SouthWestGravity
:
773 case SouthEastGravity
:
774 *y
+= self
->size
.top
+ self
->size
.bottom
;
778 *y
+= self
->size
.top
;