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