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

This commit is contained in:
Ken Thomases 2013-02-17 19:28:27 -06:00 committed by Alexandre Julliard
parent 3799acb3ac
commit ba86e67792
3 changed files with 109 additions and 1 deletions

View File

@ -46,10 +46,13 @@
CGFloat primaryScreenHeight;
BOOL primaryScreenHeightValid;
NSMutableArray* orderedWineWindows;
}
@property (nonatomic) CGEventSourceKeyboardType keyboardType;
@property (readonly, copy, nonatomic) NSEvent* lastFlagsChanged;
@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);

View File

@ -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

View File

@ -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