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 */  } | 
