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>
This commit is contained in:
Ken Thomases 2016-05-12 18:50:39 -05:00 committed by Alexandre Julliard
parent 833ff146c4
commit 742734b44f
1 changed files with 70 additions and 11 deletions

View File

@ -290,6 +290,8 @@ @interface WineContentView : NSView <NSTextInputClient>
{ {
NSMutableArray* glContexts; NSMutableArray* glContexts;
NSMutableArray* pendingGlContexts; NSMutableArray* pendingGlContexts;
BOOL _cachedHasGLDescendant;
BOOL _cachedHasGLDescendantValid;
BOOL clearedGlSurface; BOOL clearedGlSurface;
NSMutableAttributedString* markedText; NSMutableAttributedString* markedText;
@ -454,6 +456,7 @@ - (void) drawRect:(NSRect)rect
- (void) addGLContext:(WineOpenGLContext*)context - (void) addGLContext:(WineOpenGLContext*)context
{ {
BOOL hadContext = [self hasGLContext];
if (!glContexts) if (!glContexts)
glContexts = [[NSMutableArray alloc] init]; glContexts = [[NSMutableArray alloc] init];
if (!pendingGlContexts) if (!pendingGlContexts)
@ -475,13 +478,18 @@ - (void) addGLContext:(WineOpenGLContext*)context
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
} }
if (!hadContext)
[self invalidateHasGLDescendant];
[(WineWindow*)[self window] updateForGLSubviews]; [(WineWindow*)[self window] updateForGLSubviews];
} }
- (void) removeGLContext:(WineOpenGLContext*)context - (void) removeGLContext:(WineOpenGLContext*)context
{ {
BOOL hadContext = [self hasGLContext];
[glContexts removeObjectIdenticalTo:context]; [glContexts removeObjectIdenticalTo:context];
[pendingGlContexts removeObjectIdenticalTo:context]; [pendingGlContexts removeObjectIdenticalTo:context];
if (hadContext && ![self hasGLContext])
[self invalidateHasGLDescendant];
[(WineWindow*)[self window] updateForGLSubviews]; [(WineWindow*)[self window] updateForGLSubviews];
} }
@ -496,6 +504,40 @@ - (BOOL) hasGLContext
return [glContexts count] || [pendingGlContexts count]; 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 - (void) wine_getBackingSize:(int*)outBackingSize
{ {
@synchronized(self) { @synchronized(self) {
@ -560,6 +602,28 @@ - (NSFocusRingType) focusRingType
return NSFocusRingTypeNone; 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 ---------- * ---------- NSTextInputClient methods ----------
*/ */
@ -1606,7 +1670,7 @@ - (void) setDisabled:(BOOL)newValue
- (BOOL) needsTransparency - (BOOL) needsTransparency
{ {
return self.shape || self.colorKeyed || self.usePerPixelAlpha || 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 - (void) checkTransparency
@ -2194,17 +2258,12 @@ - (void) updateColorSpace
{ {
NSRect contentRect = [[self contentView] frame]; NSRect contentRect = [[self contentView] frame];
BOOL coveredByGLView = FALSE; 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))
NSRect frame = [view convertRect:[view bounds] toView:nil]; coveredByGLView = TRUE;
if (NSContainsRect(frame, contentRect))
{
coveredByGLView = TRUE;
break;
}
}
} }
if (coveredByGLView) if (coveredByGLView)