diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ui/frames.c | 122 |
1 files changed, 79 insertions, 43 deletions
diff --git a/src/ui/frames.c b/src/ui/frames.c index c0ad3ede..c7f411d7 100644 --- a/src/ui/frames.c +++ b/src/ui/frames.c @@ -780,6 +780,39 @@ meta_frames_unflicker_bg (MetaFrames *frames, set_background_none (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow); } +#ifdef HAVE_SHAPE +static void +apply_cairo_region_to_window (Display *display, + Window xwindow, + cairo_region_t *region, + int op) +{ + int n_rects, i; + XRectangle *rects; + + n_rects = cairo_region_num_rectangles (region); + rects = g_new (XRectangle, n_rects); + + for (i = 0; i < n_rects; i++) + { + cairo_rectangle_int_t rect; + + cairo_region_get_rectangle (region, i, &rect); + + rects[i].x = rect.x; + rects[i].y = rect.y; + rects[i].width = rect.width; + rects[i].height = rect.height; + } + + XShapeCombineRectangles (display, xwindow, + ShapeBounding, 0, 0, rects, n_rects, + ShapeSet, YXBanded); + + g_free (rects); +} +#endif + void meta_frames_apply_shapes (MetaFrames *frames, Window xwindow, @@ -794,6 +827,9 @@ meta_frames_apply_shapes (MetaFrames *frames, XRectangle xrect; Region corners_xregion; Region window_xregion; + cairo_rectangle_int_t rect; + cairo_region_t *corners_region; + cairo_region_t *window_region; gint scale; frame = meta_frames_lookup_window (frames, xwindow); @@ -827,7 +863,7 @@ meta_frames_apply_shapes (MetaFrames *frames, return; /* nothing to do */ } - corners_xregion = XCreateRegion (); + corners_region = cairo_region_create (); scale = gdk_window_get_scale_factor (frame->window); if (fgeom.top_left_corner_rounded_radius != 0) @@ -839,12 +875,12 @@ meta_frames_apply_shapes (MetaFrames *frames, for (i=0; i<corner; i++) { const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = 0; - xrect.y = i; - xrect.width = width; - xrect.height = 1; + rect.x = 0; + rect.y = i; + rect.width = width; + rect.height = 1; - XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion); + cairo_region_union_rectangle (corners_region, &rect); } } @@ -857,12 +893,12 @@ meta_frames_apply_shapes (MetaFrames *frames, for (i=0; i<corner; i++) { const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = new_window_width - width; - xrect.y = i; - xrect.width = width; - xrect.height = 1; + rect.x = new_window_width - width; + rect.y = i; + rect.width = width; + rect.height = 1; - XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion); + cairo_region_union_rectangle (corners_region, &rect); } } @@ -875,12 +911,12 @@ meta_frames_apply_shapes (MetaFrames *frames, for (i=0; i<corner; i++) { const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = 0; - xrect.y = new_window_height - i - 1; - xrect.width = width; - xrect.height = 1; + rect.x = 0; + rect.y = new_window_height - i - 1; + rect.width = width; + rect.height = 1; - XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion); + cairo_region_union_rectangle (corners_region, &rect); } } @@ -893,27 +929,27 @@ meta_frames_apply_shapes (MetaFrames *frames, for (i=0; i<corner; i++) { const int width = floor(0.5 + radius - sqrt(radius*radius - (radius-(i+0.5))*(radius-(i+0.5)))); - xrect.x = new_window_width - width; - xrect.y = new_window_height - i - 1; - xrect.width = width; - xrect.height = 1; + rect.x = new_window_width - width; + rect.y = new_window_height - i - 1; + rect.width = width; + rect.height = 1; - XUnionRectWithRegion (&xrect, corners_xregion, corners_xregion); + cairo_region_union_rectangle (corners_region, &rect); } } - window_xregion = XCreateRegion (); + window_region = cairo_region_create (); - xrect.x = 0; - xrect.y = 0; - xrect.width = new_window_width; - xrect.height = new_window_height; + rect.x = 0; + rect.y = 0; + rect.width = new_window_width; + rect.height = new_window_height; - XUnionRectWithRegion (&xrect, window_xregion, window_xregion); + cairo_region_union_rectangle (window_region, &rect); - XSubtractRegion (window_xregion, corners_xregion, window_xregion); + cairo_region_subtract (window_region, corners_region); - XDestroyRegion (corners_xregion); + cairo_region_destroy (corners_region); if (window_has_shape) { @@ -926,7 +962,7 @@ meta_frames_apply_shapes (MetaFrames *frames, XSetWindowAttributes attrs; Window shape_window; Window client_window; - Region client_xregion; + cairo_region_t *client_region; GdkScreen *screen; int screen_number; @@ -966,21 +1002,21 @@ meta_frames_apply_shapes (MetaFrames *frames, /* Punch the client area out of the normal frame shape, * then union it with the shape_window's existing shape */ - client_xregion = XCreateRegion (); + client_region = cairo_region_create (); - xrect.x = fgeom.left_width; - xrect.y = fgeom.top_height; - xrect.width = new_window_width - fgeom.right_width - xrect.x; - xrect.height = new_window_height - fgeom.bottom_height - xrect.y; + rect.x = fgeom.left_width; + rect.y = fgeom.top_height; + rect.width = new_window_width - fgeom.right_width - rect.x; + rect.height = new_window_height - fgeom.bottom_height - rect.y; - XUnionRectWithRegion (&xrect, client_xregion, client_xregion); + cairo_region_union_rectangle (client_region, &rect); - XSubtractRegion (window_xregion, client_xregion, window_xregion); + cairo_region_subtract (window_region, client_region); - XDestroyRegion (client_xregion); + cairo_region_destroy (client_region); - XShapeCombineRegion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window, - ShapeBounding, 0, 0, window_xregion, ShapeUnion); + apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), shape_window, + window_region, ShapeUnion); /* Now copy shape_window shape to the real frame */ XShapeCombineShape (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, ShapeBounding, @@ -999,13 +1035,13 @@ meta_frames_apply_shapes (MetaFrames *frames, "Frame 0x%lx has shaped corners\n", frame->xwindow); - XShapeCombineRegion (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, - ShapeBounding, 0, 0, window_xregion, ShapeSet); + apply_cairo_region_to_window (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), frame->xwindow, + window_region, ShapeSet); } frame->shape_applied = TRUE; - XDestroyRegion (window_xregion); + cairo_region_destroy (window_region); #endif /* HAVE_SHAPE */ } |