Module: wine Branch: master Commit: 742734b44f6d622053dca8f241c61f28ab7892c5 URL: http://source.winehq.org/git/wine.git/?a=commit;h=742734b44f6d622053dca8f241...
Author: Ken Thomases ken@codeweavers.com Date: Thu May 12 18:50:39 2016 -0500
winemac: Remove the assumption that OpenGL views are always immediate subviews of the window content view.
Signed-off-by: Ken Thomases ken@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/winemac.drv/cocoa_window.m | 81 +++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 11 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index aee9981..ec5eb2b 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -290,6 +290,8 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi { NSMutableArray* glContexts; NSMutableArray* pendingGlContexts; + BOOL _cachedHasGLDescendant; + BOOL _cachedHasGLDescendantValid; BOOL clearedGlSurface;
NSMutableAttributedString* markedText; @@ -454,6 +456,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi
- (void) addGLContext:(WineOpenGLContext*)context { + BOOL hadContext = [self hasGLContext]; if (!glContexts) glContexts = [[NSMutableArray alloc] init]; if (!pendingGlContexts) @@ -475,13 +478,18 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi [self setNeedsDisplay:YES]; }
+ if (!hadContext) + [self invalidateHasGLDescendant]; [(WineWindow*)[self window] updateForGLSubviews]; }
- (void) removeGLContext:(WineOpenGLContext*)context { + BOOL hadContext = [self hasGLContext]; [glContexts removeObjectIdenticalTo:context]; [pendingGlContexts removeObjectIdenticalTo:context]; + if (hadContext && ![self hasGLContext]) + [self invalidateHasGLDescendant]; [(WineWindow*)[self window] updateForGLSubviews]; }
@@ -496,6 +504,40 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi return [glContexts count] || [pendingGlContexts count]; }
+ - (BOOL) _hasGLDescendant + { + if ([self hasGLContext]) + return YES; + for (WineContentView* view in [self subviews]) + { + if ([view hasGLDescendant]) + return YES; + } + return NO; + } + + - (BOOL) hasGLDescendant + { + if (!_cachedHasGLDescendantValid) + { + _cachedHasGLDescendant = [self _hasGLDescendant]; + _cachedHasGLDescendantValid = YES; + } + return _cachedHasGLDescendant; + } + + - (void) invalidateHasGLDescendant + { + BOOL invalidateAncestors = _cachedHasGLDescendantValid; + _cachedHasGLDescendantValid = NO; + if (invalidateAncestors && self != [[self window] contentView]) + { + WineContentView* superview = (WineContentView*)[self superview]; + if ([superview isKindOfClass:[WineContentView class]]) + [superview invalidateHasGLDescendant]; + } + } + - (void) wine_getBackingSize:(int*)outBackingSize { @synchronized(self) { @@ -560,6 +602,28 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi return NSFocusRingTypeNone; }
+ - (void) didAddSubview:(NSView*)subview + { + if ([subview isKindOfClass:[WineContentView class]]) + { + WineContentView* view = (WineContentView*)subview; + if (!view->_cachedHasGLDescendantValid || view->_cachedHasGLDescendant) + [self invalidateHasGLDescendant]; + } + [super didAddSubview:subview]; + } + + - (void) willRemoveSubview:(NSView*)subview + { + if ([subview isKindOfClass:[WineContentView class]]) + { + WineContentView* view = (WineContentView*)subview; + if (!view->_cachedHasGLDescendantValid || view->_cachedHasGLDescendant) + [self invalidateHasGLDescendant]; + } + [super willRemoveSubview:subview]; + } + /* * ---------- NSTextInputClient methods ---------- */ @@ -1606,7 +1670,7 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi - (BOOL) needsTransparency { return self.shape || self.colorKeyed || self.usePerPixelAlpha || - (gl_surface_mode == GL_SURFACE_BEHIND && [[self.contentView valueForKeyPath:@"subviews.@max.hasGLContext"] boolValue]); + (gl_surface_mode == GL_SURFACE_BEHIND && [(WineContentView*)self.contentView hasGLDescendant]); }
- (void) checkTransparency @@ -2194,17 +2258,12 @@ static CVReturn WineDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTi { NSRect contentRect = [[self contentView] frame]; BOOL coveredByGLView = FALSE; - for (WineContentView* view in [[self contentView] subviews]) + WineContentView* view = (WineContentView*)[[self contentView] hitTest:NSMakePoint(NSMidX(contentRect), NSMidY(contentRect))]; + if ([view isKindOfClass:[WineContentView class]] && [view hasGLContext]) { - if ([view hasGLContext]) - { - NSRect frame = [view convertRect:[view bounds] toView:nil]; - if (NSContainsRect(frame, contentRect)) - { - coveredByGLView = TRUE; - break; - } - } + NSRect frame = [view convertRect:[view bounds] toView:nil]; + if (NSContainsRect(frame, contentRect)) + coveredByGLView = TRUE; }
if (coveredByGLView)