winemac: Don't invalidate the window shadow on every draw if it's merely shaped and not color-keyed or using per-pixel alpha.

This avoids flickering and tearing on some versions of OS X during frequent
redrawing in a shaped window, such as when scrolling a document in Word 2007.

Since we aren't guaranteed that the window surface has updated bits for us to
draw, we mark the whole content view as needing redisplay and draw the window's
shape in the background color on the first -drawRect: after the shape change.
This commit is contained in:
Ken Thomases 2014-10-02 17:06:14 -05:00 committed by Alexandre Julliard
parent 7c035744f6
commit 170d80dc90
1 changed files with 16 additions and 1 deletions

View File

@ -236,6 +236,17 @@ - (void) drawRect:(NSRect)rect
if ([window contentView] != self)
return;
if (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))
{
@ -289,7 +300,7 @@ - (void) drawRect:(NSRect)rect
// If the window may be transparent, then we have to invalidate the
// shadow every time we draw. Also, if this is the first time we've
// drawn since changing from transparent to opaque.
if (![window isOpaque] || window.shapeChangedSinceLastDraw)
if (window.colorKeyed || window.usePerPixelAlpha || window.shapeChangedSinceLastDraw)
{
window.shapeChangedSinceLastDraw = FALSE;
[window invalidateShadow];
@ -1373,11 +1384,15 @@ - (void) checkTransparency
{
if (![self isOpaque] && !self.needsTransparency)
{
self.shapeChangedSinceLastDraw = TRUE;
[[self contentView] setNeedsDisplay:YES];
[self setBackgroundColor:[NSColor windowBackgroundColor]];
[self setOpaque:YES];
}
else if ([self isOpaque] && self.needsTransparency)
{
self.shapeChangedSinceLastDraw = TRUE;
[[self contentView] setNeedsDisplay:YES];
[self setBackgroundColor:[NSColor clearColor]];
[self setOpaque:NO];
}