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 @@ @interface WineApplication : NSApplication <NSApplicationDelegate>
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) windowGotFocus:(WineWindow*)window;
- (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 @@ @interface WineApplication ()
@implementation WineApplication
@synthesize keyboardType, lastFlagsChanged;
@synthesize orderedWineWindows;
- (id) init
{
@ -48,8 +49,9 @@ - (id) init
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 @@ - (id) init
- (void) dealloc
{
[orderedWineWindows release];
[keyWindows release];
[eventQueues release];
[eventQueuesLock release];
@ -251,6 +254,64 @@ actually off by one (precisely because they were flipped from
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 @@ - (void)applicationWillFinishLaunching:(NSNotification *)notification
usingBlock:^(NSNotification *note){
NSWindow* window = [note object];
[keyWindows removeObjectIdenticalTo:window];
[orderedWineWindows removeObjectIdenticalTo:window];
}];
[nc addObserver:self

View File

@ -380,12 +380,19 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
[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 @@ - (void) doOrderOut
[latentParentWindow removeChildWindow:self];
forceNextMouseMoveAbsolute = TRUE;
[self orderOut:nil];
[NSApp wineWindow:self ordered:NSWindowOut relativeTo:nil];
[NSApp removeWindowsItem:self];
}
@ -467,7 +475,10 @@ - (void) setMacDrvParentWindow:(WineWindow*)parent
[[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 @@ - (void) makeFocused
}
[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 @@ - (void) sendEvent:(NSEvent*)event
{
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 @@ - (void) sendEvent:(NSEvent*)event
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 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification
}
ignore_windowDeminiaturize = FALSE;
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
}
- (void)windowDidMove:(NSNotification *)notification