[PATCH 2/5] winemac.drv: Use a mask layer to support window regions.
Chip Davis
cdavis at codeweavers.com
Tue Aug 31 17:27:34 CDT 2021
Signed-off-by: Chip Davis <cdavis at codeweavers.com>
---
dlls/winemac.drv/cocoa_window.h | 2 -
dlls/winemac.drv/cocoa_window.m | 89 ++++++++++++++++-----------------
2 files changed, 44 insertions(+), 47 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h
index f9c3902dc36..d04961f8251 100644
--- a/dlls/winemac.drv/cocoa_window.h
+++ b/dlls/winemac.drv/cocoa_window.h
@@ -51,8 +51,6 @@ @interface WineWindow : NSPanel <NSWindowDelegate>
NSRect wineFrame;
NSRect roundedWineFrame;
- NSBezierPath* shape;
- NSData* shapeData;
BOOL shapeChangedSinceLastDraw;
BOOL colorKeyed;
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index bc06a9506ee..4d7aa570552 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -321,6 +321,22 @@ - (BOOL) layer:(CALayer*)layer shouldInheritContentsScale:(CGFloat)newScale from
#endif
+ at interface CAShapeLayer (WineShapeMaskExtensions)
+
+ at property(readonly, nonatomic, getter=isEmptyShaped) BOOL emptyShaped;
+
+ at end
+
+ at implementation CAShapeLayer (WineShapeMaskExtensions)
+
+ - (BOOL) isEmptyShaped
+ {
+ return CGRectEqualToRect(CGPathGetBoundingBox(self.path), CGRectZero);
+ }
+
+ at end
+
+
@interface WineBaseView : NSView
@end
@@ -388,8 +404,6 @@ @interface WineWindow ()
@property (nonatomic) void* surface;
@property (nonatomic) pthread_mutex_t* surface_mutex;
- at property (copy, nonatomic) NSBezierPath* shape;
- at property (copy, nonatomic) NSData* shapeData;
@property (nonatomic) BOOL shapeChangedSinceLastDraw;
@property (readonly, nonatomic) BOOL needsTransparency;
@@ -402,6 +416,8 @@ @interface WineWindow ()
@property (readonly, copy, nonatomic) NSArray* childWineWindows;
+ - (void) setShape:(CGPathRef)newShape;
+
- (void) updateForGLSubviews;
- (BOOL) becameEligibleParentOrChild;
@@ -494,17 +510,6 @@ - (void) drawRect:(NSRect)rect
if ([window contentView] != self)
return;
- if (window.drawnSinceShown && window.shapeChangedSinceLastDraw && window.shape && !window.colorKeyed && !window.usePerPixelAlpha)
- {
- [[NSColor clearColor] setFill];
- NSRectFill(rect);
-
- [window.shape addClip];
-
- [[NSColor windowBackgroundColor] setFill];
- NSRectFill(rect);
- }
-
if (window.surface && window.surface_mutex &&
!pthread_mutex_lock(window.surface_mutex))
{
@@ -517,8 +522,6 @@ - (void) drawRect:(NSRect)rect
CGContextRef context;
int i;
- [window.shape addClip];
-
context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
CGContextSetBlendMode(context, kCGBlendModeCopy);
CGContextSetInterpolationQuality(context, retina_on ? kCGInterpolationHigh : kCGInterpolationNone);
@@ -968,7 +971,7 @@ @implementation WineWindow
@synthesize disabled, noActivate, floating, fullscreen, fakingClose, latentParentWindow, hwnd, queue;
@synthesize drawnSinceShown;
@synthesize surface, surface_mutex;
- @synthesize shape, shapeData, shapeChangedSinceLastDraw;
+ @synthesize shapeChangedSinceLastDraw;
@synthesize colorKeyed, colorKeyRed, colorKeyGreen, colorKeyBlue;
@synthesize usePerPixelAlpha;
@synthesize imeData, commandDone;
@@ -1069,8 +1072,6 @@ - (void) dealloc
[queue release];
[latentChildWindows release];
[latentParentWindow release];
- [shape release];
- [shapeData release];
[super dealloc];
}
@@ -2013,7 +2014,7 @@ - (void) setDisabled:(BOOL)newValue
- (BOOL) needsTransparency
{
- return self.shape || self.colorKeyed || self.usePerPixelAlpha ||
+ return self.contentView.layer.mask || self.colorKeyed || self.usePerPixelAlpha ||
(gl_surface_mode == GL_SURFACE_BEHIND && [(WineContentView*)self.contentView hasGLDescendant]);
}
@@ -2035,22 +2036,27 @@ - (void) checkTransparency
}
}
- - (void) setShape:(NSBezierPath*)newShape
+ - (void) setShape:(CGPathRef)newShape
{
- if (shape == newShape) return;
+ CALayer* layer = [[self contentView] layer];
+ CAShapeLayer* mask = layer.mask;
+ if (CGPathEqualToPath(newShape, mask.path)) return;
- if (shape)
- {
- [[self contentView] setNeedsDisplayInRect:[shape bounds]];
- [shape release];
- }
+ if (newShape && !layer.mask)
+ layer.mask = mask = [CAShapeLayer layer];
+ else if (!newShape)
+ layer.mask = mask = nil;
+
+ if (mask.path)
+ [[self contentView] setNeedsDisplayInRect:NSRectFromCGRect(CGPathGetBoundingBox(mask.path))];
if (newShape)
- [[self contentView] setNeedsDisplayInRect:[newShape bounds]];
+ [[self contentView] setNeedsDisplayInRect:NSRectFromCGRect(CGPathGetBoundingBox(newShape))];
- shape = [newShape copy];
+ mask.path = newShape;
self.shapeChangedSinceLastDraw = TRUE;
[self checkTransparency];
+ [self checkEmptyShaped];
}
- (void) makeFocused:(BOOL)activate
@@ -2247,7 +2253,7 @@ - (void) checkWineDisplayLink
- (BOOL) isEmptyShaped
{
- return (self.shapeData.length == sizeof(CGRectZero) && !memcmp(self.shapeData.bytes, &CGRectZero, sizeof(CGRectZero)));
+ return ([[[self contentView] layer].mask isEmptyShaped]);
}
- (BOOL) canProvideSnapshot
@@ -2650,8 +2656,7 @@ - (void) setRetinaMode:(int)mode
[transform scaleBy:scale];
- if (shape)
- [shape transformUsingAffineTransform:transform];
+ [[self contentView] layer].mask.contentsScale = mode ? 2.0 : 1.0;
for (WineBaseView* subview in [self.contentView subviews])
{
@@ -3456,25 +3461,19 @@ void macdrv_set_window_shape(macdrv_window w, const CGRect *rects, int count)
OnMainThread(^{
if (!rects || !count)
{
- window.shape = nil;
- window.shapeData = nil;
+ [window setShape:NULL];
[window checkEmptyShaped];
}
else
{
- size_t length = sizeof(*rects) * count;
- if (window.shapeData.length != length || memcmp(window.shapeData.bytes, rects, length))
- {
- NSBezierPath* path;
- unsigned int i;
+ CGMutablePathRef path;
+ unsigned int i;
- path = [NSBezierPath bezierPath];
- for (i = 0; i < count; i++)
- [path appendBezierPathWithRect:NSRectFromCGRect(cgrect_mac_from_win(rects[i]))];
- window.shape = path;
- window.shapeData = [NSData dataWithBytes:rects length:length];
- [window checkEmptyShaped];
- }
+ path = CGPathCreateMutable();
+ for (i = 0; i < count; i++)
+ CGPathAddRect(path, NULL, cgrect_mac_from_win(rects[i]));
+ [window setShape:path];
+ CGPathRelease(path);
}
});
--
2.33.0
More information about the wine-devel
mailing list