Module: wine Branch: master Commit: 84903c5db33c992dff916cee3dddbbbe980f1628 URL: http://source.winehq.org/git/wine.git/?a=commit;h=84903c5db33c992dff916cee3d...
Author: Ken Thomases ken@codeweavers.com Date: Fri Aug 30 00:00:56 2013 -0500
winemac: Track latent child windows (the inverse of the latent parent window relationship).
This allows the relationship to be restored when the window becomes eligible again.
---
dlls/winemac.drv/cocoa_window.h | 1 + dlls/winemac.drv/cocoa_window.m | 78 +++++++++++++++++++++++++++++++++++++- 2 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.h b/dlls/winemac.drv/cocoa_window.h index e0e581b..5cf47b4 100644 --- a/dlls/winemac.drv/cocoa_window.h +++ b/dlls/winemac.drv/cocoa_window.h @@ -32,6 +32,7 @@ BOOL fullscreen; BOOL pendingMinimize; WineWindow* latentParentWindow; + NSMutableArray* latentChildWindows;
void* hwnd; WineEventQueue* queue; diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index 1977ca0..512d2ff 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -537,6 +537,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) [liveResizeDisplayTimer invalidate]; [liveResizeDisplayTimer release]; [queue release]; + [latentChildWindows release]; [latentParentWindow release]; [shape release]; [super dealloc]; @@ -679,11 +680,18 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) if ([self level] > [child level]) [child setLevel:[self level]]; [self addChildWindow:child ordered:NSWindowAbove]; + [latentChildWindows removeObjectIdenticalTo:child]; child.latentParentWindow = nil; reordered = TRUE; } else + { + if (!latentChildWindows) + latentChildWindows = [[NSMutableArray alloc] init]; + if (![latentChildWindows containsObject:child]) + [latentChildWindows addObject:child]; child.latentParentWindow = self; + }
return reordered; } @@ -698,15 +706,52 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) [self removeChildWindow:child]; if (child.latentParentWindow == self) child.latentParentWindow = nil; + [latentChildWindows removeObjectIdenticalTo:child]; }
- (BOOL) becameEligibleParentOrChild { + BOOL reordered = FALSE; + NSUInteger count; + // If we aren't visible currently, we assume that we should be and soon // will be. So, if the latent parent is visible that's enough to assume // we can establish the parent-child relationship in Cocoa. That will // actually make us visible, which is fine. - return [latentParentWindow addChildWineWindow:self assumeVisible:TRUE]; + if ([latentParentWindow addChildWineWindow:self assumeVisible:TRUE]) + reordered = TRUE; + + // Here, though, we may not actually be visible yet and adding a child + // won't make us visible. The caller will have to call this method + // again after actually making us visible. + if ([self isVisible] && (count = [latentChildWindows count])) + { + NSMutableIndexSet* indexesToRemove = [NSMutableIndexSet indexSet]; + NSUInteger i; + + for (i = 0; i < count; i++) + { + WineWindow* child = [latentChildWindows objectAtIndex:i]; + if ([child isVisible]) + { + if (child.latentParentWindow == self) + { + if ([self level] > [child level]) + [child setLevel:[self level]]; + [self addChildWindow:child ordered:NSWindowAbove]; + child.latentParentWindow = nil; + reordered = TRUE; + } + else + ERR(@"shouldn't happen: %@ thinks %@ is a latent child, but it doesn't agree\n", self, child); + [indexesToRemove addIndex:i]; + } + } + + [latentChildWindows removeObjectsAtIndexes:indexesToRemove]; + } + + return reordered; }
- (void) becameIneligibleParentOrChild @@ -716,6 +761,9 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
if (parent) { + if (!parent->latentChildWindows) + parent->latentChildWindows = [[NSMutableArray alloc] init]; + [parent->latentChildWindows insertObject:self atIndex:0]; self.latentParentWindow = parent; [parent removeChildWindow:self]; } @@ -723,11 +771,18 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) if ([childWindows count]) { WineWindow* child; - for (child in [[childWindows copy] autorelease]) + + childWindows = [[childWindows copy] autorelease]; + for (child in childWindows) { child.latentParentWindow = self; [self removeChildWindow:child]; } + + if (latentChildWindows) + [latentChildWindows replaceObjectsInRange:NSMakeRange(0, 0) withObjectsFromArray:childWindows]; + else + latentChildWindows = [childWindows mutableCopy]; } }
@@ -887,6 +942,10 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers) [self orderFront:nil]; needAdjustWindowLevels = TRUE; } + + if ([self becameEligibleParentOrChild]) + needAdjustWindowLevels = TRUE; + if (needAdjustWindowLevels) { if (!wasVisible && fullscreen && [self isOnActiveSpace]) @@ -1406,7 +1465,20 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
- (void) windowWillClose:(NSNotification*)notification { - self.latentParentWindow = nil; + WineWindow* child; + + if (latentParentWindow) + { + [latentParentWindow->latentChildWindows removeObjectIdenticalTo:self]; + self.latentParentWindow = nil; + } + + for (child in latentChildWindows) + { + if (child.latentParentWindow == self) + child.latentParentWindow = nil; + } + [latentChildWindows removeAllObjects]; }
- (void)windowWillMiniaturize:(NSNotification *)notification