Ken Thomases : winemac: Track latent child windows ( the inverse of the latent parent window relationship).
Alexandre Julliard
julliard at winehq.org
Fri Aug 30 11:00:37 CDT 2013
Module: wine
Branch: master
Commit: 84903c5db33c992dff916cee3dddbbbe980f1628
URL: http://source.winehq.org/git/wine.git/?a=commit;h=84903c5db33c992dff916cee3dddbbbe980f1628
Author: Ken Thomases <ken at 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
More information about the wine-cvs
mailing list