Ken Thomases : winemac: Track Cocoa windows in a z-ordered list.

Alexandre Julliard julliard at winehq.org
Mon Feb 18 13:27:05 CST 2013


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

Author: Ken Thomases <ken at codeweavers.com>
Date:   Sun Feb 17 19:28:27 2013 -0600

winemac: Track Cocoa windows in a z-ordered list.

---

 dlls/winemac.drv/cocoa_app.h    |    7 ++++
 dlls/winemac.drv/cocoa_app.m    |   64 ++++++++++++++++++++++++++++++++++++++-
 dlls/winemac.drv/cocoa_window.m |   39 +++++++++++++++++++++++
 3 files changed, 109 insertions(+), 1 deletions(-)

diff --git a/dlls/winemac.drv/cocoa_app.h b/dlls/winemac.drv/cocoa_app.h
index 1166087..f215b11 100644
--- a/dlls/winemac.drv/cocoa_app.h
+++ b/dlls/winemac.drv/cocoa_app.h
@@ -46,10 +46,13 @@
 
     CGFloat primaryScreenHeight;
     BOOL primaryScreenHeightValid;
+
+    NSMutableArray* orderedWineWindows;
 }
 
 @property (nonatomic) CGEventSourceKeyboardType keyboardType;
 @property (readonly, copy, nonatomic) NSEvent* lastFlagsChanged;
+ at property (readonly, nonatomic) NSArray* orderedWineWindows;
 
     - (void) transformProcessToForeground;
 
@@ -63,6 +66,10 @@
 
     - (void) keyboardSelectionDidChange;
 
+    - (void) wineWindow:(WineWindow*)window
+                ordered:(NSWindowOrderingMode)order
+             relativeTo:(WineWindow*)otherWindow;
+
 @end
 
 void OnMainThread(dispatch_block_t block);
diff --git a/dlls/winemac.drv/cocoa_app.m b/dlls/winemac.drv/cocoa_app.m
index ae2353b..d26682e 100644
--- a/dlls/winemac.drv/cocoa_app.m
+++ b/dlls/winemac.drv/cocoa_app.m
@@ -38,6 +38,7 @@ int macdrv_err_on;
 @implementation WineApplication
 
     @synthesize keyboardType, lastFlagsChanged;
+    @synthesize orderedWineWindows;
 
     - (id) init
     {
@@ -48,8 +49,9 @@ int macdrv_err_on;
             eventQueuesLock = [[NSLock alloc] init];
 
             keyWindows = [[NSMutableArray alloc] init];
+            orderedWineWindows = [[NSMutableArray alloc] init];
 
-            if (!eventQueues || !eventQueuesLock || !keyWindows)
+            if (!eventQueues || !eventQueuesLock || !keyWindows || !orderedWineWindows)
             {
                 [self release];
                 return nil;
@@ -60,6 +62,7 @@ int macdrv_err_on;
 
     - (void) dealloc
     {
+        [orderedWineWindows release];
         [keyWindows release];
         [eventQueues release];
         [eventQueuesLock release];
@@ -251,6 +254,64 @@ int macdrv_err_on;
         return point;
     }
 
+    - (void) wineWindow:(WineWindow*)window
+                ordered:(NSWindowOrderingMode)order
+             relativeTo:(WineWindow*)otherWindow
+    {
+        NSUInteger index;
+
+        switch (order)
+        {
+            case NSWindowAbove:
+                [window retain];
+                [orderedWineWindows removeObjectIdenticalTo:window];
+                if (otherWindow)
+                {
+                    index = [orderedWineWindows indexOfObjectIdenticalTo:otherWindow];
+                    if (index == NSNotFound)
+                        index = 0;
+                }
+                else
+                {
+                    index = 0;
+                    for (otherWindow in orderedWineWindows)
+                    {
+                        if ([otherWindow level] <= [window level])
+                            break;
+                        index++;
+                    }
+                }
+                [orderedWineWindows insertObject:window atIndex:index];
+                [window release];
+                break;
+            case NSWindowBelow:
+                [window retain];
+                [orderedWineWindows removeObjectIdenticalTo:window];
+                if (otherWindow)
+                {
+                    index = [orderedWineWindows indexOfObjectIdenticalTo:otherWindow];
+                    if (index == NSNotFound)
+                        index = [orderedWineWindows count];
+                }
+                else
+                {
+                    index = 0;
+                    for (otherWindow in orderedWineWindows)
+                    {
+                        if ([otherWindow level] < [window level])
+                            break;
+                        index++;
+                    }
+                }
+                [orderedWineWindows insertObject:window atIndex:index];
+                [window release];
+                break;
+            case NSWindowOut:
+            default:
+                break;
+        }
+    }
+
 
     /*
      * ---------- NSApplication method overrides ----------
@@ -307,6 +368,7 @@ int macdrv_err_on;
                     usingBlock:^(NSNotification *note){
             NSWindow* window = [note object];
             [keyWindows removeObjectIdenticalTo:window];
+            [orderedWineWindows removeObjectIdenticalTo:window];
         }];
 
         [nc addObserver:self
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m
index d8ea9ed..b3ccb92 100644
--- a/dlls/winemac.drv/cocoa_window.m
+++ b/dlls/winemac.drv/cocoa_window.m
@@ -380,12 +380,19 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             [NSApp transformProcessToForeground];
 
             if (prev)
+            {
                 [self orderWindow:NSWindowBelow relativeTo:[prev windowNumber]];
+                [NSApp wineWindow:self ordered:NSWindowBelow relativeTo:prev];
+            }
             else
+            {
                 [self orderWindow:NSWindowAbove relativeTo:[next windowNumber]];
+                [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:next];
+            }
             if (latentParentWindow)
             {
                 [latentParentWindow addChildWindow:self ordered:NSWindowAbove];
+                [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
                 self.latentParentWindow = nil;
             }
 
@@ -407,6 +414,7 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         [latentParentWindow removeChildWindow:self];
         forceNextMouseMoveAbsolute = TRUE;
         [self orderOut:nil];
+        [NSApp wineWindow:self ordered:NSWindowOut relativeTo:nil];
         [NSApp removeWindowsItem:self];
     }
 
@@ -467,7 +475,10 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
             [[self parentWindow] removeChildWindow:self];
             self.latentParentWindow = nil;
             if ([self isVisible] && parent)
+            {
                 [parent addChildWindow:self ordered:NSWindowAbove];
+                [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:parent];
+            }
             else
                 self.latentParentWindow = parent;
         }
@@ -556,12 +567,14 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         }
 
         [self orderFront:nil];
+        [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
         causing_becomeKeyWindow = TRUE;
         [self makeKeyWindow];
         causing_becomeKeyWindow = FALSE;
         if (latentParentWindow)
         {
             [latentParentWindow addChildWindow:self ordered:NSWindowAbove];
+            [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
             self.latentParentWindow = nil;
         }
         if (![self isExcludedFromWindowsMenu])
@@ -700,6 +713,9 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         {
             if ([event type] == NSLeftMouseDown)
             {
+                NSWindowButton windowButton;
+                BOOL broughtWindowForward = TRUE;
+
                 /* Since our windows generally claim they can't be made key, clicks
                    in their title bars are swallowed by the theme frame stuff.  So,
                    we hook directly into the event stream and assume that any click
@@ -707,6 +723,27 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
                    accept. */
                 if (![self isKeyWindow] && !self.disabled && !self.noActivate)
                     [NSApp windowGotFocus:self];
+
+                /* Any left-click on our window anyplace other than the close or
+                   minimize buttons will bring it forward. */
+                for (windowButton = NSWindowCloseButton;
+                     windowButton <= NSWindowMiniaturizeButton;
+                     windowButton++)
+                {
+                    NSButton* button = [[event window] standardWindowButton:windowButton];
+                    if (button)
+                    {
+                        NSPoint point = [button convertPoint:[event locationInWindow] fromView:nil];
+                        if ([button mouse:point inRect:[button bounds]])
+                        {
+                            broughtWindowForward = FALSE;
+                            break;
+                        }
+                    }
+                }
+
+                if (broughtWindowForward)
+                    [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
             }
 
             [super sendEvent:event];
@@ -908,6 +945,8 @@ static inline void fix_generic_modifiers_by_device(NSUInteger* modifiers)
         }
 
         ignore_windowDeminiaturize = FALSE;
+
+        [NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
     }
 
     - (void)windowDidMove:(NSNotification *)notification




More information about the wine-cvs mailing list