summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen W. Taylor <[email protected]>2011-03-20 16:26:27 -0400
committerVictor Kareh <[email protected]>2018-08-28 19:22:06 -0400
commit522ad73e73b9101dc8cf74f81669321fc28fac8e (patch)
treec158138406b0d63870c7c5f8c7a56f5a2554d813
parent93b5dd1cf945b59a1ec605e66c2ceda49ba9e397 (diff)
downloadmarco-522ad73e73b9101dc8cf74f81669321fc28fac8e.tar.bz2
marco-522ad73e73b9101dc8cf74f81669321fc28fac8e.tar.xz
Convert frame region handling to cairo regions
It's useful to get frame shapes and manipulate them within Mutter, for example so that the compositor can use them to clip drawing. For this, we'll need the regions as cairo regions not X regions, so convert frame shaping code to work in terms of cairo_region_t. https://bugzilla.gnome.org/show_bug.cgi?id=635268
-rw-r--r--src/ui/frames.c122
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 */
}