Ken Thomases : winemac: Don' t use Cocoa parent-child relationship when topmost state is enough to keep owned in front of owner .

Alexandre Julliard julliard at winehq.org
Tue Sep 3 13:38:03 CDT 2013


Module: wine
Branch: master
Commit: 987309e528832cfcf3f77fc123bbe00d90017628
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=987309e528832cfcf3f77fc123bbe00d90017628

Author: Ken Thomases <ken at codeweavers.com>
Date:   Mon Sep  2 22:48:59 2013 -0500

winemac: Don't use Cocoa parent-child relationship when topmost state is enough to keep owned in front of owner.

The Cocoa parent-child relationship has undesirable side effects and bugs.  In
the general case, it's the only way to maintain the z-order of owned windows
relative to their owner.  But when the owner is non-topmost and an owned
window is topmost, the Cocoa window level will enforce that and we don't
need it.

---

 dlls/winemac.drv/cocoa_window.m |   58 +++++++++++++++++++++++++++++++-------
 1 files changed, 47 insertions(+), 11 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index b71d31e..7553cfc 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -160,6 +160,9 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
 
     - (void) updateColorSpace;
 
+    - (BOOL) becameEligibleParentOrChild;
+    - (void) becameIneligibleChild;
+
 @end
 
 
@@ -626,6 +629,31 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         if (self.floating != state->floating)
         {
             self.floating = state->floating;
+            if (state->floating)
+            {
+                // Became floating.  If child of non-floating window, make that
+                // relationship latent.
+                WineWindow* parent = (WineWindow*)[self parentWindow];
+                if (parent && !parent.floating)
+                    [self becameIneligibleChild];
+            }
+            else
+            {
+                // Became non-floating.  If parent of floating children, make that
+                // relationship latent.
+                WineWindow* child;
+                for (child in [[[self childWindows] copy] autorelease])
+                {
+                    if (child.floating)
+                        [child becameIneligibleChild];
+                }
+            }
+
+            // Check our latent relationships.  If floating status was the only
+            // reason they were latent, then make them active.
+            if ([self isVisible])
+                [self becameEligibleParentOrChild];
+
             [[WineApplicationController sharedController] adjustWindowLevels];
         }
 
@@ -675,7 +703,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
     {
         BOOL reordered = FALSE;
 
-        if ([self isVisible] && (assumeVisible || [child isVisible]))
+        if ([self isVisible] && (assumeVisible || [child isVisible]) && (self.floating || !child.floating))
         {
             if ([self level] > [child level])
                 [child setLevel:[self level]];
@@ -714,12 +742,15 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         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.
-        if ([latentParentWindow addChildWineWindow:self assumeVisible:TRUE])
-            reordered = TRUE;
+        if (latentParentWindow.floating || !self.floating)
+        {
+            // 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.
+            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
@@ -732,7 +763,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             for (i = 0; i < count; i++)
             {
                 WineWindow* child = [latentChildWindows objectAtIndex:i];
-                if ([child isVisible])
+                if ([child isVisible] && (self.floating || !child.floating))
                 {
                     if (child.latentParentWindow == self)
                     {
@@ -754,11 +785,9 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         return reordered;
     }
 
-    - (void) becameIneligibleParentOrChild
+    - (void) becameIneligibleChild
     {
         WineWindow* parent = (WineWindow*)[self parentWindow];
-        NSArray* childWindows = [self childWindows];
-
         if (parent)
         {
             if (!parent->latentChildWindows)
@@ -767,6 +796,13 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             self.latentParentWindow = parent;
             [parent removeChildWindow:self];
         }
+    }
+
+    - (void) becameIneligibleParentOrChild
+    {
+        NSArray* childWindows = [self childWindows];
+
+        [self becameIneligibleChild];
 
         if ([childWindows count])
         {




More information about the wine-cvs mailing list