winemac: Better handle z-ordering windows that are in Cocoa parent-child window relationships.
The code had been handling ordering sibling windows relative to each other, including windows neither of which were child windows. However, it wasn't properly handling other relationships (e.g. cousins, nieces, uncles, etc.). The reason this is complicated is that Cocoa keeps child windows in a fixed relative order to their parent and siblings. The normal -orderWindow:relativeTo: method doesn't work. One has to remove the children from the parent and re-add them in the desired order. Signed-off-by: Ken Thomases <ken@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e30b1aef1b
commit
302593c9c0
|
@ -1457,8 +1457,15 @@ - (void) order:(NSWindowOrderingMode)mode childWindow:(WineWindow*)child relativ
|
||||||
windowNumbers = [[[[self class] windowNumbersWithOptions:NSWindowNumberListAllSpaces] mutableCopy] autorelease];
|
windowNumbers = [[[[self class] windowNumbersWithOptions:NSWindowNumberListAllSpaces] mutableCopy] autorelease];
|
||||||
childWindowNumber = [NSNumber numberWithInteger:[child windowNumber]];
|
childWindowNumber = [NSNumber numberWithInteger:[child windowNumber]];
|
||||||
[windowNumbers removeObject:childWindowNumber];
|
[windowNumbers removeObject:childWindowNumber];
|
||||||
|
if (other)
|
||||||
|
{
|
||||||
otherIndex = [windowNumbers indexOfObject:[NSNumber numberWithInteger:[other windowNumber]]];
|
otherIndex = [windowNumbers indexOfObject:[NSNumber numberWithInteger:[other windowNumber]]];
|
||||||
[windowNumbers insertObject:childWindowNumber atIndex:otherIndex + (mode == NSWindowAbove ? 0 : 1)];
|
[windowNumbers insertObject:childWindowNumber atIndex:otherIndex + (mode == NSWindowAbove ? 0 : 1)];
|
||||||
|
}
|
||||||
|
else if (mode == NSWindowAbove)
|
||||||
|
[windowNumbers insertObject:childWindowNumber atIndex:0];
|
||||||
|
else
|
||||||
|
[windowNumbers addObject:childWindowNumber];
|
||||||
|
|
||||||
// Get our child windows and sort them in the reverse of the desired
|
// Get our child windows and sort them in the reverse of the desired
|
||||||
// z-order (back-to-front).
|
// z-order (back-to-front).
|
||||||
|
@ -1472,6 +1479,52 @@ - (void) order:(NSWindowOrderingMode)mode childWindow:(WineWindow*)child relativ
|
||||||
[self setChildWineWindows:children];
|
[self setChildWineWindows:children];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Search the ancestor windows of self and other to find a place where some ancestors are siblings of each other.
|
||||||
|
// There are three possible results in terms of the values of *ancestor and *ancestorOfOther on return:
|
||||||
|
// (non-nil, non-nil) there is a level in the window tree where the two windows have sibling ancestors
|
||||||
|
// if *ancestor has a parent Wine window, then it's the parent of the other ancestor, too
|
||||||
|
// otherwise, the two ancestors are each roots of disjoint window trees
|
||||||
|
// (nil, non-nil) the other window is a descendent of self and *ancestorOfOther is the direct child
|
||||||
|
// (non-nil, nil) self is a descendent of other and *ancestor is the direct child
|
||||||
|
- (void) getSiblingWindowsForWindow:(WineWindow*)other ancestor:(WineWindow**)ancestor ancestorOfOther:(WineWindow**)ancestorOfOther
|
||||||
|
{
|
||||||
|
NSMutableArray* otherAncestors = [NSMutableArray arrayWithObject:other];
|
||||||
|
WineWindow* child;
|
||||||
|
WineWindow* parent;
|
||||||
|
for (child = other;
|
||||||
|
(parent = (WineWindow*)child.parentWindow) && [parent isKindOfClass:[WineWindow class]];
|
||||||
|
child = parent)
|
||||||
|
{
|
||||||
|
if (parent == self)
|
||||||
|
{
|
||||||
|
*ancestor = nil;
|
||||||
|
*ancestorOfOther = child;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[otherAncestors addObject:parent];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (child = self;
|
||||||
|
(parent = (WineWindow*)child.parentWindow) && [parent isKindOfClass:[WineWindow class]];
|
||||||
|
child = parent)
|
||||||
|
{
|
||||||
|
NSUInteger index = [otherAncestors indexOfObjectIdenticalTo:parent];
|
||||||
|
if (index != NSNotFound)
|
||||||
|
{
|
||||||
|
*ancestor = child;
|
||||||
|
if (index == 0)
|
||||||
|
*ancestorOfOther = nil;
|
||||||
|
else
|
||||||
|
*ancestorOfOther = [otherAncestors objectAtIndex:index - 1];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*ancestor = child;
|
||||||
|
*ancestorOfOther = otherAncestors.lastObject;;
|
||||||
|
}
|
||||||
|
|
||||||
/* Returns whether or not the window was ordered in, which depends on if
|
/* Returns whether or not the window was ordered in, which depends on if
|
||||||
its frame intersects any screen. */
|
its frame intersects any screen. */
|
||||||
- (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)activate
|
- (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)activate
|
||||||
|
@ -1481,6 +1534,8 @@ - (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)a
|
||||||
{
|
{
|
||||||
BOOL needAdjustWindowLevels = FALSE;
|
BOOL needAdjustWindowLevels = FALSE;
|
||||||
BOOL wasVisible;
|
BOOL wasVisible;
|
||||||
|
WineWindow* parent;
|
||||||
|
WineWindow* child;
|
||||||
|
|
||||||
[controller transformProcessToForeground];
|
[controller transformProcessToForeground];
|
||||||
if ([NSApp isHidden])
|
if ([NSApp isHidden])
|
||||||
|
@ -1502,30 +1557,53 @@ - (void) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next activate:(BOOL)a
|
||||||
|
|
||||||
if (![self isOrdered:orderingMode relativeTo:other])
|
if (![self isOrdered:orderingMode relativeTo:other])
|
||||||
{
|
{
|
||||||
WineWindow* parent = (WineWindow*)[self parentWindow];
|
WineWindow* ancestor;
|
||||||
WineWindow* otherParent = (WineWindow*)[other parentWindow];
|
WineWindow* ancestorOfOther;
|
||||||
|
|
||||||
|
[self getSiblingWindowsForWindow:other ancestor:&ancestor ancestorOfOther:&ancestorOfOther];
|
||||||
|
if (ancestor)
|
||||||
|
{
|
||||||
|
[self setAutodisplay:YES];
|
||||||
|
if (ancestorOfOther)
|
||||||
|
{
|
||||||
// This window level may not be right for this window based
|
// This window level may not be right for this window based
|
||||||
// on floating-ness, fullscreen-ness, etc. But we set it
|
// on floating-ness, fullscreen-ness, etc. But we set it
|
||||||
// temporarily to allow us to order the windows properly.
|
// temporarily to allow us to order the windows properly.
|
||||||
// Then the levels get fixed by -adjustWindowLevels.
|
// Then the levels get fixed by -adjustWindowLevels.
|
||||||
if ([self level] != [other level])
|
if ([ancestor level] != [ancestorOfOther level])
|
||||||
[self setLevel:[other level]];
|
[ancestor setLevel:[ancestorOfOther level]];
|
||||||
[self setAutodisplay:YES];
|
|
||||||
[self orderWindow:orderingMode relativeTo:[other windowNumber]];
|
parent = (WineWindow*)ancestor.parentWindow;
|
||||||
|
if ([parent isKindOfClass:[WineWindow class]])
|
||||||
|
[parent order:orderingMode childWindow:ancestor relativeTo:ancestorOfOther];
|
||||||
|
else
|
||||||
|
[ancestor orderWindow:orderingMode relativeTo:[ancestorOfOther windowNumber]];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (child = self;
|
||||||
|
(parent = (WineWindow*)child.parentWindow);
|
||||||
|
child = parent)
|
||||||
|
{
|
||||||
|
if ([parent isKindOfClass:[WineWindow class]])
|
||||||
|
[parent order:-orderingMode childWindow:child relativeTo:nil];
|
||||||
|
if (parent == ancestor)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
[self checkWineDisplayLink];
|
[self checkWineDisplayLink];
|
||||||
|
|
||||||
// The above call to -[NSWindow orderWindow:relativeTo:] won't
|
|
||||||
// reorder windows which are both children of the same parent
|
|
||||||
// relative to each other, so do that separately.
|
|
||||||
if (parent && parent == otherParent)
|
|
||||||
[parent order:orderingMode childWindow:self relativeTo:other];
|
|
||||||
|
|
||||||
needAdjustWindowLevels = TRUE;
|
needAdjustWindowLevels = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
for (child = self;
|
||||||
|
(parent = (WineWindow*)child.parentWindow) && [parent isKindOfClass:[WineWindow class]];
|
||||||
|
child = parent)
|
||||||
|
{
|
||||||
|
[parent order:NSWindowAbove childWindow:child relativeTo:nil];
|
||||||
|
}
|
||||||
|
|
||||||
// Again, temporarily set level to make sure we can order to
|
// Again, temporarily set level to make sure we can order to
|
||||||
// the right place.
|
// the right place.
|
||||||
next = [controller frontWineWindow];
|
next = [controller frontWineWindow];
|
||||||
|
|
Loading…
Reference in New Issue