diff --git a/gdk/macos/GdkMacosCairoSubview.c b/gdk/macos/GdkMacosCairoSubview.c index 425b52ac78..e52acdf168 100644 --- a/gdk/macos/GdkMacosCairoSubview.c +++ b/gdk/macos/GdkMacosCairoSubview.c @@ -32,6 +32,12 @@ @implementation GdkMacosCairoSubview +-(void)dealloc +{ + g_clear_pointer (&self->clip, cairo_region_destroy); + [super dealloc]; +} + -(BOOL)isOpaque { return _isOpaque; @@ -95,6 +101,21 @@ cr = cairo_create (dest); cairo_translate (cr, -abs_bounds.origin.x, -abs_bounds.origin.y); + /* Apply the clip if provided one */ + if (self->clip != NULL) + { + cairo_rectangle_int_t area; + + n_rects = cairo_region_num_rectangles (self->clip); + for (guint i = 0; i < n_rects; i++) + { + cairo_region_get_rectangle (self->clip, i, &area); + cairo_rectangle (cr, area.x, area.y, area.width, area.height); + } + + cairo_clip (cr); + } + /* Clip the cairo context based on the rectangles to be drawn * within the bounding box :rect. */ @@ -168,4 +189,14 @@ self->_isOpaque = opaque; } +-(void)setClip:(cairo_region_t*)region +{ + if (region != self->clip) + { + g_clear_pointer (&self->clip, cairo_region_destroy); + if (region != NULL) + self->clip = cairo_region_reference (region); + } +} + @end diff --git a/gdk/macos/GdkMacosCairoSubview.h b/gdk/macos/GdkMacosCairoSubview.h index 9255347566..5eae734f8f 100644 --- a/gdk/macos/GdkMacosCairoSubview.h +++ b/gdk/macos/GdkMacosCairoSubview.h @@ -26,10 +26,12 @@ { BOOL _isOpaque; cairo_surface_t *cairoSurface; + cairo_region_t *clip; } -(void)setOpaque:(BOOL)opaque; -(void)setCairoSurface:(cairo_surface_t *)cairoSurface withDamage:(cairo_region_t *)region; +-(void)setClip:(cairo_region_t*)region; @end diff --git a/gdk/macos/GdkMacosCairoView.c b/gdk/macos/GdkMacosCairoView.c index 2f82488912..81ac8af6a3 100644 --- a/gdk/macos/GdkMacosCairoView.c +++ b/gdk/macos/GdkMacosCairoView.c @@ -78,6 +78,7 @@ -(void)setOpaqueRegion:(cairo_region_t *)region { + cairo_region_t *transparent_clip; NSRect abs_bounds; guint n_rects; @@ -87,6 +88,17 @@ abs_bounds = [self convertRect:[self bounds] toView:nil]; n_rects = cairo_region_num_rectangles (region); + /* First, we create a clip region for the transparent region to use so that + * we dont end up exposing too much other than the corners on CSD. + */ + transparent_clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) { + abs_bounds.origin.x, abs_bounds.origin.y, + abs_bounds.size.width, abs_bounds.size.height + }); + cairo_region_subtract (transparent_clip, region); + [(GdkMacosCairoSubview *)self->transparent setClip:transparent_clip]; + cairo_region_destroy (transparent_clip); + /* The common case (at least for opaque windows and CSD) is that we will * have either one or two opaque rectangles. If we detect that the same * number of them are available as the previous, we can just resize the