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.
This commit is contained in:
Ken Thomases 2013-09-02 22:48:59 -05:00 committed by Alexandre Julliard
parent 11b21f70ab
commit 987309e528
1 changed files with 47 additions and 11 deletions

View File

@ -160,6 +160,9 @@ @interface WineWindow ()
- (void) updateColorSpace;
- (BOOL) becameEligibleParentOrChild;
- (void) becameIneligibleChild;
@end
@ -626,6 +629,31 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state
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 @@ - (BOOL) addChildWineWindow:(WineWindow*)child assumeVisible:(BOOL)assumeVisible
{
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 @@ - (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.
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 @@ - (BOOL) becameEligibleParentOrChild
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 @@ - (BOOL) becameEligibleParentOrChild
return reordered;
}
- (void) becameIneligibleParentOrChild
- (void) becameIneligibleChild
{
WineWindow* parent = (WineWindow*)[self parentWindow];
NSArray* childWindows = [self childWindows];
if (parent)
{
if (!parent->latentChildWindows)
@ -767,6 +796,13 @@ - (void) becameIneligibleParentOrChild
self.latentParentWindow = parent;
[parent removeChildWindow:self];
}
}
- (void) becameIneligibleParentOrChild
{
NSArray* childWindows = [self childWindows];
[self becameIneligibleChild];
if ([childWindows count])
{