From: Ken Thomases Subject: winemac: Ignore Cocoa child windows which aren't instances of WineWindow. Message-Id: <800E7D02-F0F1-49E9-8F20-471FCB25579D@codeweavers.com> Date: Wed, 17 Dec 2014 08:59:09 -0600 On Yosemite, in full-screen mode, Cocoa adds child windows of its own to our windows. These windows are, of course, not instances of WineWindow. So, when we call WineWindow-specific methods on them, it throws exceptions. --- dlls/winemac.drv/cocoa_window.m | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index b2238cb..57ae2b8 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -195,6 +195,8 @@ @interface WineWindow () @property (retain, nonatomic) NSTimer* liveResizeDisplayTimer; +@property (readonly, copy, nonatomic) NSArray* childWineWindows; + - (void) updateColorSpace; - (BOOL) becameEligibleParentOrChild; @@ -834,7 +836,7 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state // Became non-floating. If parent of floating children, make that // relationship latent. WineWindow* child; - for (child in [[[self childWindows] copy] autorelease]) + for (child in [self childWineWindows]) { if (child.floating) [child becameIneligibleChild]; @@ -1012,7 +1014,7 @@ - (void) becameIneligibleChild - (void) becameIneligibleParentOrChild { - NSArray* childWindows = [self childWindows]; + NSArray* childWindows = [self childWineWindows]; [self becameIneligibleChild]; @@ -1020,7 +1022,6 @@ - (void) becameIneligibleParentOrChild { WineWindow* child; - childWindows = [[childWindows copy] autorelease]; for (child in childWindows) { child.latentParentWindow = self; @@ -1101,7 +1102,7 @@ - (void) order:(NSWindowOrderingMode)mode childWindow:(WineWindow*)child relativ // Get our child windows and sort them in the reverse of the desired // z-order (back-to-front). - origChildren = [self childWindows]; + origChildren = [self childWineWindows]; children = [[origChildren mutableCopy] autorelease]; [children sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(id obj1, id obj2){ @@ -1315,7 +1316,7 @@ - (void) setFrameFromWine:(NSRect)contentRect [self setContentMaxSize:NSMakeSize(FLT_MAX, FLT_MAX)]; } - if (equalSizes && [[self childWindows] count]) + if (equalSizes && [[self childWineWindows] count]) { // If we change the window frame such that the origin moves // but the size doesn't change, then Cocoa moves child @@ -1611,6 +1612,15 @@ - (void) toggleFullScreen:(id)sender [super toggleFullScreen:sender]; } + - (NSArray*) childWineWindows + { + NSArray* childWindows = self.childWindows; + NSIndexSet* indexes = [childWindows indexesOfObjectsPassingTest:^BOOL(id child, NSUInteger idx, BOOL *stop){ + return [child isKindOfClass:[WineWindow class]]; + }]; + return [childWindows objectsAtIndexes:indexes]; + } + // We normally use the generic/calibrated RGB color space for the window, // rather than the device color space, to avoid expensive color conversion // which slows down drawing. However, for windows displaying OpenGL, having