winemac: Refactor WineApplication class to separate most logic into a controller class.

This commit is contained in:
Ken Thomases 2013-04-16 00:38:01 -05:00 committed by Alexandre Julliard
parent 304463b4e1
commit e7d5f329e5
5 changed files with 219 additions and 131 deletions

View File

@ -35,7 +35,7 @@
@class WineWindow; @class WineWindow;
@interface WineApplication : NSApplication <NSApplicationDelegate> @interface WineApplicationController : NSObject <NSApplicationDelegate>
{ {
CFRunLoopSourceRef requestSource; CFRunLoopSourceRef requestSource;
NSMutableArray* requests; NSMutableArray* requests;
@ -84,6 +84,8 @@ @interface WineApplication : NSApplication <NSApplicationDelegate>
@property (readonly, nonatomic) NSArray* orderedWineWindows; @property (readonly, nonatomic) NSArray* orderedWineWindows;
@property (readonly, nonatomic) BOOL areDisplaysCaptured; @property (readonly, nonatomic) BOOL areDisplaysCaptured;
+ (WineApplicationController*) sharedController;
- (void) transformProcessToForeground; - (void) transformProcessToForeground;
- (BOOL) registerEventQueue:(WineEventQueue*)queue; - (BOOL) registerEventQueue:(WineEventQueue*)queue;
@ -104,8 +106,22 @@ - (void) wineWindow:(WineWindow*)window
ordered:(NSWindowOrderingMode)order ordered:(NSWindowOrderingMode)order
relativeTo:(WineWindow*)otherWindow; relativeTo:(WineWindow*)otherWindow;
- (BOOL) handleEvent:(NSEvent*)anEvent;
- (void) didSendEvent:(NSEvent*)anEvent;
@end @end
@interface WineApplication : NSApplication
{
WineApplicationController* wineController;
}
@property (readwrite, assign, nonatomic) WineApplicationController* wineController;
@end
void OnMainThreadAsync(dispatch_block_t block); void OnMainThreadAsync(dispatch_block_t block);
void LogError(const char* func, NSString* format, ...); void LogError(const char* func, NSString* format, ...);

View File

@ -32,6 +32,28 @@
int macdrv_err_on; int macdrv_err_on;
@implementation WineApplication
@synthesize wineController;
- (void) sendEvent:(NSEvent*)anEvent
{
if (![wineController handleEvent:anEvent])
{
[super sendEvent:anEvent];
[wineController didSendEvent:anEvent];
}
}
- (void) setWineController:(WineApplicationController*)newController
{
wineController = newController;
[self setDelegate:wineController];
}
@end
@interface WarpRecord : NSObject @interface WarpRecord : NSObject
{ {
CGEventTimestamp timeBefore, timeAfter; CGEventTimestamp timeBefore, timeAfter;
@ -53,24 +75,39 @@ @implementation WarpRecord
@end; @end;
@interface WineApplication () @interface WineApplicationController ()
@property (readwrite, copy, nonatomic) NSEvent* lastFlagsChanged; @property (readwrite, copy, nonatomic) NSEvent* lastFlagsChanged;
@property (copy, nonatomic) NSArray* cursorFrames; @property (copy, nonatomic) NSArray* cursorFrames;
@property (retain, nonatomic) NSTimer* cursorTimer; @property (retain, nonatomic) NSTimer* cursorTimer;
@property (retain, nonatomic) NSImage* applicationIcon; @property (retain, nonatomic) NSImage* applicationIcon;
- (void) setupObservations;
- (void) applicationDidBecomeActive:(NSNotification *)notification;
static void PerformRequest(void *info); static void PerformRequest(void *info);
@end @end
@implementation WineApplication @implementation WineApplicationController
@synthesize keyboardType, lastFlagsChanged; @synthesize keyboardType, lastFlagsChanged;
@synthesize orderedWineWindows, applicationIcon; @synthesize orderedWineWindows, applicationIcon;
@synthesize cursorFrames, cursorTimer; @synthesize cursorFrames, cursorTimer;
+ (WineApplicationController*) sharedController
{
static WineApplicationController* sharedController;
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedController = [[self alloc] init];
});
return sharedController;
}
- (id) init - (id) init
{ {
self = [super init]; self = [super init];
@ -106,6 +143,13 @@ - (id) init
[self release]; [self release];
return nil; return nil;
} }
[self setupObservations];
keyboardType = LMGetKbdType();
if ([NSApp isActive])
[self applicationDidBecomeActive:nil];
} }
return self; return self;
} }
@ -133,7 +177,7 @@ - (void) dealloc
- (void) transformProcessToForeground - (void) transformProcessToForeground
{ {
if ([self activationPolicy] != NSApplicationActivationPolicyRegular) if ([NSApp activationPolicy] != NSApplicationActivationPolicyRegular)
{ {
NSMenu* mainMenu; NSMenu* mainMenu;
NSMenu* submenu; NSMenu* submenu;
@ -141,8 +185,8 @@ - (void) transformProcessToForeground
NSString* title; NSString* title;
NSMenuItem* item; NSMenuItem* item;
[self setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[self activateIgnoringOtherApps:YES]; [NSApp activateIgnoringOtherApps:YES];
mainMenu = [[[NSMenu alloc] init] autorelease]; mainMenu = [[[NSMenu alloc] init] autorelease];
@ -169,10 +213,10 @@ - (void) transformProcessToForeground
[item setSubmenu:submenu]; [item setSubmenu:submenu];
[mainMenu addItem:item]; [mainMenu addItem:item];
[self setMainMenu:mainMenu]; [NSApp setMainMenu:mainMenu];
[self setWindowsMenu:submenu]; [NSApp setWindowsMenu:submenu];
[self setApplicationIconImage:self.applicationIcon]; [NSApp setApplicationIconImage:self.applicationIcon];
} }
} }
@ -245,7 +289,7 @@ - (void) windowGotFocus:(WineWindow*)window
{ {
macdrv_event* event; macdrv_event* event;
[NSApp invalidateGotFocusEvents]; [self invalidateGotFocusEvents];
event = macdrv_create_event(WINDOW_GOT_FOCUS, window); event = macdrv_create_event(WINDOW_GOT_FOCUS, window);
event->window_got_focus.serial = windowFocusSerial; event->window_got_focus.serial = windowFocusSerial;
@ -263,7 +307,7 @@ - (void) windowRejectedFocusEvent:(const macdrv_event*)event
{ {
triedWindows = (NSMutableSet*)event->window_got_focus.tried_windows; triedWindows = (NSMutableSet*)event->window_got_focus.tried_windows;
[triedWindows addObject:(WineWindow*)event->window]; [triedWindows addObject:(WineWindow*)event->window];
for (NSWindow* window in [keyWindows arrayByAddingObjectsFromArray:[self orderedWindows]]) for (NSWindow* window in [keyWindows arrayByAddingObjectsFromArray:[self orderedWineWindows]])
{ {
if (![triedWindows containsObject:window] && [window canBecomeKeyWindow]) if (![triedWindows containsObject:window] && [window canBecomeKeyWindow])
{ {
@ -673,12 +717,12 @@ - (void) setApplicationIconFromCGImageArray:(NSArray*)images
} }
self.applicationIcon = nsimage; self.applicationIcon = nsimage;
[self setApplicationIconImage:nsimage]; [NSApp setApplicationIconImage:nsimage];
} }
- (void) handleCommandTab - (void) handleCommandTab
{ {
if ([self isActive]) if ([NSApp isActive])
{ {
NSRunningApplication* thisApp = [NSRunningApplication currentApplication]; NSRunningApplication* thisApp = [NSRunningApplication currentApplication];
NSRunningApplication* app; NSRunningApplication* app;
@ -700,7 +744,7 @@ - (void) handleCommandTab
{ {
// There's another visible app. Just hide ourselves and let // There's another visible app. Just hide ourselves and let
// the system activate the other app. // the system activate the other app.
[self hide:self]; [NSApp hide:self];
return; return;
} }
@ -894,8 +938,8 @@ - (CGEventRef) eventTapWithProxy:(CGEventTapProxy)proxy
CGEventRef WineAppEventTapCallBack(CGEventTapProxy proxy, CGEventType type, CGEventRef WineAppEventTapCallBack(CGEventTapProxy proxy, CGEventType type,
CGEventRef event, void *refcon) CGEventRef event, void *refcon)
{ {
WineApplication* app = refcon; WineApplicationController* controller = refcon;
return [app eventTapWithProxy:proxy type:type event:event]; return [controller eventTapWithProxy:proxy type:type event:event];
} }
- (BOOL) installEventTap - (BOOL) installEventTap
@ -1042,7 +1086,7 @@ - (BOOL) startClippingCursor:(CGRect)rect
clippingCursor = TRUE; clippingCursor = TRUE;
cursorClipRect = rect; cursorClipRect = rect;
if ([self isActive]) if ([NSApp isActive])
[self activateCursorClipping]; [self activateCursorClipping];
return TRUE; return TRUE;
@ -1061,16 +1105,19 @@ - (BOOL) stopClippingCursor
} }
/* // Returns TRUE if the event was handled and caller should do nothing more
* ---------- NSApplication method overrides ---------- // with it. Returns FALSE if the caller should process it as normal and
*/ // then call -didSendEvent:.
- (void) sendEvent:(NSEvent*)anEvent - (BOOL) handleEvent:(NSEvent*)anEvent
{
if ([anEvent type] == NSFlagsChanged)
self.lastFlagsChanged = anEvent;
return FALSE;
}
- (void) didSendEvent:(NSEvent*)anEvent
{ {
NSEventType type = [anEvent type]; NSEventType type = [anEvent type];
if (type == NSFlagsChanged)
self.lastFlagsChanged = anEvent;
[super sendEvent:anEvent];
if (type == NSMouseMoved || type == NSLeftMouseDragged || if (type == NSMouseMoved || type == NSLeftMouseDragged ||
type == NSRightMouseDragged || type == NSOtherMouseDragged) type == NSRightMouseDragged || type == NSOtherMouseDragged)
@ -1089,7 +1136,7 @@ - (void) sendEvent:(NSEvent*)anEvent
windowUnderNumber = [NSWindow windowNumberAtPoint:point windowUnderNumber = [NSWindow windowNumberAtPoint:point
belowWindowWithWindowNumber:0]; belowWindowWithWindowNumber:0];
targetWindow = (WineWindow*)[self windowWithWindowNumber:windowUnderNumber]; targetWindow = (WineWindow*)[NSApp windowWithWindowNumber:windowUnderNumber];
} }
else else
targetWindow = (WineWindow*)[anEvent window]; targetWindow = (WineWindow*)[anEvent window];
@ -1146,6 +1193,40 @@ - (void) sendEvent:(NSEvent*)anEvent
} }
} }
- (void) setupObservations
{
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc addObserverForName:NSWindowDidBecomeKeyNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note){
NSWindow* window = [note object];
[keyWindows removeObjectIdenticalTo:window];
[keyWindows insertObject:window atIndex:0];
}];
[nc addObserverForName:NSWindowWillCloseNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
NSWindow* window = [note object];
[keyWindows removeObjectIdenticalTo:window];
[orderedWineWindows removeObjectIdenticalTo:window];
if (window == lastTargetWindow)
lastTargetWindow = nil;
}];
[nc addObserver:self
selector:@selector(keyboardSelectionDidChange)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
/* The above notification isn't sent unless the NSTextInputContext
class has initialized itself. Poke it. */
[NSTextInputContext self];
}
/* /*
* ---------- NSApplicationDelegate methods ---------- * ---------- NSApplicationDelegate methods ----------
@ -1249,42 +1330,6 @@ - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)send
return ret; return ret;
} }
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
[nc addObserverForName:NSWindowDidBecomeKeyNotification
object:nil
queue:nil
usingBlock:^(NSNotification *note){
NSWindow* window = [note object];
[keyWindows removeObjectIdenticalTo:window];
[keyWindows insertObject:window atIndex:0];
}];
[nc addObserverForName:NSWindowWillCloseNotification
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
NSWindow* window = [note object];
[keyWindows removeObjectIdenticalTo:window];
[orderedWineWindows removeObjectIdenticalTo:window];
if (window == lastTargetWindow)
lastTargetWindow = nil;
}];
[nc addObserver:self
selector:@selector(keyboardSelectionDidChange)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
/* The above notification isn't sent unless the NSTextInputContext
class has initialized itself. Poke it. */
[NSTextInputContext self];
self.keyboardType = LMGetKbdType();
}
- (void)applicationWillResignActive:(NSNotification *)notification - (void)applicationWillResignActive:(NSNotification *)notification
{ {
[self deactivateCursorClipping]; [self deactivateCursorClipping];
@ -1305,17 +1350,17 @@ - (void)applicationWillResignActive:(NSNotification *)notification
*/ */
static void PerformRequest(void *info) static void PerformRequest(void *info)
{ {
WineApplication* app = (WineApplication*)NSApp; WineApplicationController* controller = [WineApplicationController sharedController];
for (;;) for (;;)
{ {
__block dispatch_block_t block; __block dispatch_block_t block;
dispatch_sync(app->requestsManipQueue, ^{ dispatch_sync(controller->requestsManipQueue, ^{
if ([app->requests count]) if ([controller->requests count])
{ {
block = (dispatch_block_t)[[app->requests objectAtIndex:0] retain]; block = (dispatch_block_t)[[controller->requests objectAtIndex:0] retain];
[app->requests removeObjectAtIndex:0]; [controller->requests removeObjectAtIndex:0];
} }
else else
block = nil; block = nil;
@ -1336,14 +1381,14 @@ static void PerformRequest(void *info)
*/ */
void OnMainThreadAsync(dispatch_block_t block) void OnMainThreadAsync(dispatch_block_t block)
{ {
WineApplication* app = (WineApplication*)NSApp; WineApplicationController* controller = [WineApplicationController sharedController];
block = [block copy]; block = [block copy];
dispatch_sync(app->requestsManipQueue, ^{ dispatch_sync(controller->requestsManipQueue, ^{
[app->requests addObject:block]; [controller->requests addObject:block];
}); });
[block release]; [block release];
CFRunLoopSourceSignal(app->requestSource); CFRunLoopSourceSignal(controller->requestSource);
CFRunLoopWakeUp(CFRunLoopGetMain()); CFRunLoopWakeUp(CFRunLoopGetMain());
} }
@ -1379,7 +1424,7 @@ void LogErrorv(const char* func, NSString* format, va_list args)
void macdrv_window_rejected_focus(const macdrv_event *event) void macdrv_window_rejected_focus(const macdrv_event *event)
{ {
OnMainThread(^{ OnMainThread(^{
[NSApp windowRejectedFocusEvent:event]; [[WineApplicationController sharedController] windowRejectedFocusEvent:event];
}); });
} }
@ -1403,7 +1448,7 @@ CFDataRef macdrv_copy_keyboard_layout(CGEventSourceKeyboardType* keyboard_type,
result = CFDataCreateCopy(NULL, uchr); result = CFDataCreateCopy(NULL, uchr);
CFRelease(inputSource); CFRelease(inputSource);
*keyboard_type = ((WineApplication*)NSApp).keyboardType; *keyboard_type = [WineApplicationController sharedController].keyboardType;
*is_iso = (KBGetLayoutType(*keyboard_type) == kKeyboardISO); *is_iso = (KBGetLayoutType(*keyboard_type) == kKeyboardISO);
} }
}); });
@ -1432,7 +1477,7 @@ int macdrv_set_display_mode(const struct macdrv_display* display,
__block int ret; __block int ret;
OnMainThread(^{ OnMainThread(^{
ret = [NSApp setMode:display_mode forDisplay:display->displayID]; ret = [[WineApplicationController sharedController] setMode:display_mode forDisplay:display->displayID];
}); });
return ret; return ret;
@ -1467,10 +1512,11 @@ void macdrv_set_cursor(CFStringRef name, CFArrayRef frames)
if (sel) if (sel)
{ {
OnMainThreadAsync(^{ OnMainThreadAsync(^{
WineApplicationController* controller = [WineApplicationController sharedController];
NSCursor* cursor = [NSCursor performSelector:sel]; NSCursor* cursor = [NSCursor performSelector:sel];
[NSApp setCursorWithFrames:nil]; [controller setCursorWithFrames:nil];
[cursor set]; [cursor set];
[NSApp unhideCursor]; [controller unhideCursor];
}); });
} }
else else
@ -1479,14 +1525,15 @@ void macdrv_set_cursor(CFStringRef name, CFArrayRef frames)
if ([nsframes count]) if ([nsframes count])
{ {
OnMainThreadAsync(^{ OnMainThreadAsync(^{
[NSApp setCursorWithFrames:nsframes]; [[WineApplicationController sharedController] setCursorWithFrames:nsframes];
}); });
} }
else else
{ {
OnMainThreadAsync(^{ OnMainThreadAsync(^{
[NSApp setCursorWithFrames:nil]; WineApplicationController* controller = [WineApplicationController sharedController];
[NSApp hideCursor]; [controller setCursorWithFrames:nil];
[controller hideCursor];
}); });
} }
} }
@ -1502,7 +1549,7 @@ int macdrv_get_cursor_position(CGPoint *pos)
{ {
OnMainThread(^{ OnMainThread(^{
NSPoint location = [NSEvent mouseLocation]; NSPoint location = [NSEvent mouseLocation];
location = [NSApp flippedMouseLocation:location]; location = [[WineApplicationController sharedController] flippedMouseLocation:location];
*pos = NSPointToCGPoint(location); *pos = NSPointToCGPoint(location);
}); });
@ -1520,7 +1567,7 @@ int macdrv_set_cursor_position(CGPoint pos)
__block int ret; __block int ret;
OnMainThread(^{ OnMainThread(^{
ret = [NSApp setCursorPosition:pos]; ret = [[WineApplicationController sharedController] setCursorPosition:pos];
}); });
return ret; return ret;
@ -1538,6 +1585,7 @@ int macdrv_clip_cursor(CGRect rect)
__block int ret; __block int ret;
OnMainThread(^{ OnMainThread(^{
WineApplicationController* controller = [WineApplicationController sharedController];
BOOL clipping = FALSE; BOOL clipping = FALSE;
if (!CGRectIsInfinite(rect)) if (!CGRectIsInfinite(rect))
@ -1546,7 +1594,7 @@ int macdrv_clip_cursor(CGRect rect)
NSScreen* screen; NSScreen* screen;
/* Convert the rectangle from top-down coords to bottom-up. */ /* Convert the rectangle from top-down coords to bottom-up. */
[NSApp flipRect:&nsrect]; [controller flipRect:&nsrect];
clipping = FALSE; clipping = FALSE;
for (screen in [NSScreen screens]) for (screen in [NSScreen screens])
@ -1560,9 +1608,9 @@ int macdrv_clip_cursor(CGRect rect)
} }
if (clipping) if (clipping)
ret = [NSApp startClippingCursor:rect]; ret = [controller startClippingCursor:rect];
else else
ret = [NSApp stopClippingCursor]; ret = [controller stopClippingCursor];
}); });
return ret; return ret;
@ -1581,7 +1629,7 @@ void macdrv_set_application_icon(CFArrayRef images)
NSArray* imageArray = (NSArray*)images; NSArray* imageArray = (NSArray*)images;
OnMainThreadAsync(^{ OnMainThreadAsync(^{
[NSApp setApplicationIconFromCGImageArray:imageArray]; [[WineApplicationController sharedController] setApplicationIconFromCGImageArray:imageArray];
}); });
} }

View File

@ -269,7 +269,9 @@ - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvent
[self postEvent:event]; [self postEvent:event];
macdrv_release_event(event); macdrv_release_event(event);
timedout = ![NSApp waitUntilQueryDone:&query->done timeout:timeoutDate processEvents:processEvents]; timedout = ![[WineApplicationController sharedController] waitUntilQueryDone:&query->done
timeout:timeoutDate
processEvents:processEvents];
return !timedout && query->status; return !timedout && query->status;
} }
@ -347,7 +349,7 @@ macdrv_event_queue macdrv_create_event_queue(macdrv_event_handler handler)
queue = [[[WineEventQueue alloc] initWithEventHandler:handler] autorelease]; queue = [[[WineEventQueue alloc] initWithEventHandler:handler] autorelease];
if (queue) if (queue)
{ {
if ([NSApp registerEventQueue:queue]) if ([[WineApplicationController sharedController] registerEventQueue:queue])
[threadDict setObject:queue forKey:WineEventQueueThreadDictionaryKey]; [threadDict setObject:queue forKey:WineEventQueueThreadDictionaryKey];
else else
queue = nil; queue = nil;
@ -370,7 +372,7 @@ void macdrv_destroy_event_queue(macdrv_event_queue queue)
WineEventQueue* q = (WineEventQueue*)queue; WineEventQueue* q = (WineEventQueue*)queue;
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary]; NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
[NSApp unregisterEventQueue:q]; [[WineApplicationController sharedController] unregisterEventQueue:q];
[threadDict removeObjectForKey:WineEventQueueThreadDictionaryKey]; [threadDict removeObjectForKey:WineEventQueueThreadDictionaryKey];
[pool release]; [pool release];

View File

@ -39,6 +39,7 @@
NSConditionLock* lock; NSConditionLock* lock;
unsigned long long tickcount; unsigned long long tickcount;
uint64_t uptime_ns; uint64_t uptime_ns;
BOOL success;
}; };
@ -61,12 +62,23 @@ static void run_cocoa_app(void* info)
{ {
struct cocoa_app_startup_info* startup_info = info; struct cocoa_app_startup_info* startup_info = info;
NSConditionLock* lock = startup_info->lock; NSConditionLock* lock = startup_info->lock;
BOOL created_app = FALSE;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[WineApplication sharedApplication]; if (!NSApp)
[NSApp setDelegate:(WineApplication*)NSApp]; {
[NSApp computeEventTimeAdjustmentFromTicks:startup_info->tickcount uptime:startup_info->uptime_ns]; [WineApplication sharedApplication];
created_app = TRUE;
}
if ([NSApp respondsToSelector:@selector(setWineController:)])
{
WineApplicationController* controller = [WineApplicationController sharedController];
[NSApp setWineController:controller];
[controller computeEventTimeAdjustmentFromTicks:startup_info->tickcount uptime:startup_info->uptime_ns];
startup_info->success = TRUE;
}
/* Retain the lock while we're using it, so macdrv_start_cocoa_app() /* Retain the lock while we're using it, so macdrv_start_cocoa_app()
doesn't deallocate it in the middle of us unlocking it. */ doesn't deallocate it in the middle of us unlocking it. */
@ -77,8 +89,11 @@ static void run_cocoa_app(void* info)
[pool release]; [pool release];
/* Never returns */ if (created_app && startup_info->success)
[NSApp run]; {
/* Never returns */
[NSApp run];
}
} }
@ -109,6 +124,7 @@ int macdrv_start_cocoa_app(unsigned long long tickcount)
startup_info.lock = [[NSConditionLock alloc] initWithCondition:COCOA_APP_NOT_RUNNING]; startup_info.lock = [[NSConditionLock alloc] initWithCondition:COCOA_APP_NOT_RUNNING];
startup_info.tickcount = tickcount; startup_info.tickcount = tickcount;
startup_info.success = FALSE;
mach_timebase_info(&mach_timebase); mach_timebase_info(&mach_timebase);
startup_info.uptime_ns = uptime_mach * mach_timebase.numer / mach_timebase.denom; startup_info.uptime_ns = uptime_mach * mach_timebase.numer / mach_timebase.denom;
@ -128,7 +144,7 @@ int macdrv_start_cocoa_app(unsigned long long tickcount)
if ([startup_info.lock lockWhenCondition:COCOA_APP_RUNNING beforeDate:timeLimit]) if ([startup_info.lock lockWhenCondition:COCOA_APP_RUNNING beforeDate:timeLimit])
{ {
[startup_info.lock unlock]; [startup_info.lock unlock];
ret = 0; ret = !startup_info.success;
} }
} }

View File

@ -310,7 +310,7 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
WineContentView* contentView; WineContentView* contentView;
NSTrackingArea* trackingArea; NSTrackingArea* trackingArea;
[NSApp flipRect:&window_frame]; [[WineApplicationController sharedController] flipRect:&window_frame];
window = [[[self alloc] initWithContentRect:window_frame window = [[[self alloc] initWithContentRect:window_frame
styleMask:style_mask_for_features(wf) styleMask:style_mask_for_features(wf)
@ -394,6 +394,7 @@ - (void) setWindowFeatures:(const struct macdrv_window_features*)wf
- (void) adjustWindowLevel - (void) adjustWindowLevel
{ {
WineApplicationController* controller = [WineApplicationController sharedController];
NSInteger level; NSInteger level;
BOOL fullscreen, captured; BOOL fullscreen, captured;
NSScreen* screen; NSScreen* screen;
@ -402,7 +403,7 @@ - (void) adjustWindowLevel
screen = screen_covered_by_rect([self frame], [NSScreen screens]); screen = screen_covered_by_rect([self frame], [NSScreen screens]);
fullscreen = (screen != nil); fullscreen = (screen != nil);
captured = (screen || [self screen]) && [NSApp areDisplaysCaptured]; captured = (screen || [self screen]) && [controller areDisplaysCaptured];
if (captured || fullscreen) if (captured || fullscreen)
{ {
@ -419,10 +420,10 @@ - (void) adjustWindowLevel
else else
level = NSNormalWindowLevel; level = NSNormalWindowLevel;
index = [[NSApp orderedWineWindows] indexOfObjectIdenticalTo:self]; index = [[controller orderedWineWindows] indexOfObjectIdenticalTo:self];
if (index != NSNotFound && index + 1 < [[NSApp orderedWineWindows] count]) if (index != NSNotFound && index + 1 < [[controller orderedWineWindows] count])
{ {
other = [[NSApp orderedWineWindows] objectAtIndex:index + 1]; other = [[controller orderedWineWindows] objectAtIndex:index + 1];
if (level < [other level]) if (level < [other level])
level = [other level]; level = [other level];
} }
@ -441,7 +442,7 @@ - (void) adjustWindowLevel
{ {
for (; index > 0; index--) for (; index > 0; index--)
{ {
other = [[NSApp orderedWineWindows] objectAtIndex:index - 1]; other = [[controller orderedWineWindows] objectAtIndex:index - 1];
if ([other level] < level) if ([other level] < level)
[other setLevelWhenActive:level]; [other setLevelWhenActive:level];
else else
@ -504,10 +505,11 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state
its frame intersects any screen. */ its frame intersects any screen. */
- (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
{ {
WineApplicationController* controller = [WineApplicationController sharedController];
BOOL on_screen = frame_intersects_screens([self frame], [NSScreen screens]); BOOL on_screen = frame_intersects_screens([self frame], [NSScreen screens]);
if (on_screen) if (on_screen)
{ {
[NSApp transformProcessToForeground]; [controller transformProcessToForeground];
if (prev) if (prev)
{ {
@ -517,20 +519,20 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
it out of the z-order that Win32 would otherwise establish. */ it out of the z-order that Win32 would otherwise establish. */
if ([prev level] < [self level]) if ([prev level] < [self level])
{ {
NSUInteger index = [[NSApp orderedWineWindows] indexOfObjectIdenticalTo:prev]; NSUInteger index = [[controller orderedWineWindows] indexOfObjectIdenticalTo:prev];
if (index != NSNotFound) if (index != NSNotFound)
{ {
[prev setLevelWhenActive:[self level]]; [prev setLevelWhenActive:[self level]];
for (; index > 0; index--) for (; index > 0; index--)
{ {
WineWindow* other = [[NSApp orderedWineWindows] objectAtIndex:index - 1]; WineWindow* other = [[controller orderedWineWindows] objectAtIndex:index - 1];
if ([other level] < [self level]) if ([other level] < [self level])
[other setLevelWhenActive:[self level]]; [other setLevelWhenActive:[self level]];
} }
} }
} }
[self orderWindow:NSWindowBelow relativeTo:[prev windowNumber]]; [self orderWindow:NSWindowBelow relativeTo:[prev windowNumber]];
[NSApp wineWindow:self ordered:NSWindowBelow relativeTo:prev]; [controller wineWindow:self ordered:NSWindowBelow relativeTo:prev];
} }
else else
{ {
@ -538,14 +540,14 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
if (next && [next level] > [self level]) if (next && [next level] > [self level])
[self setLevelWhenActive:[next level]]; [self setLevelWhenActive:[next level]];
[self orderWindow:NSWindowAbove relativeTo:[next windowNumber]]; [self orderWindow:NSWindowAbove relativeTo:[next windowNumber]];
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:next]; [controller wineWindow:self ordered:NSWindowAbove relativeTo:next];
} }
if (latentParentWindow) if (latentParentWindow)
{ {
if ([latentParentWindow level] > [self level]) if ([latentParentWindow level] > [self level])
[self setLevelWhenActive:[latentParentWindow level]]; [self setLevelWhenActive:[latentParentWindow level]];
[latentParentWindow addChildWindow:self ordered:NSWindowAbove]; [latentParentWindow addChildWindow:self ordered:NSWindowAbove];
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow]; [controller wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
self.latentParentWindow = nil; self.latentParentWindow = nil;
} }
@ -566,7 +568,7 @@ - (void) doOrderOut
self.latentParentWindow = [self parentWindow]; self.latentParentWindow = [self parentWindow];
[latentParentWindow removeChildWindow:self]; [latentParentWindow removeChildWindow:self];
[self orderOut:nil]; [self orderOut:nil];
[NSApp wineWindow:self ordered:NSWindowOut relativeTo:nil]; [[WineApplicationController sharedController] wineWindow:self ordered:NSWindowOut relativeTo:nil];
[NSApp removeWindowsItem:self]; [NSApp removeWindowsItem:self];
} }
@ -580,7 +582,7 @@ - (BOOL) setFrameIfOnScreen:(NSRect)contentRect
/* Origin is (left, top) in a top-down space. Need to convert it to /* Origin is (left, top) in a top-down space. Need to convert it to
(left, bottom) in a bottom-up space. */ (left, bottom) in a bottom-up space. */
[NSApp flipRect:&contentRect]; [[WineApplicationController sharedController] flipRect:&contentRect];
if (on_screen) if (on_screen)
{ {
@ -633,7 +635,7 @@ - (void) setMacDrvParentWindow:(WineWindow*)parent
if ([parent level] > [self level]) if ([parent level] > [self level])
[self setLevelWhenActive:[parent level]]; [self setLevelWhenActive:[parent level]];
[parent addChildWindow:self ordered:NSWindowAbove]; [parent addChildWindow:self ordered:NSWindowAbove];
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:parent]; [[WineApplicationController sharedController] wineWindow:self ordered:NSWindowAbove relativeTo:parent];
} }
else else
self.latentParentWindow = parent; self.latentParentWindow = parent;
@ -697,7 +699,7 @@ - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
event->mouse_button.pressed = pressed; event->mouse_button.pressed = pressed;
event->mouse_button.x = pt.x; event->mouse_button.x = pt.x;
event->mouse_button.y = pt.y; event->mouse_button.y = pt.y;
event->mouse_button.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; event->mouse_button.time_ms = [[WineApplicationController sharedController] ticksForEventTime:[theEvent timestamp]];
[queue postEvent:event]; [queue postEvent:event];
@ -706,9 +708,10 @@ - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
- (void) makeFocused - (void) makeFocused
{ {
WineApplicationController* controller = [WineApplicationController sharedController];
NSArray* screens; NSArray* screens;
[NSApp transformProcessToForeground]; [controller transformProcessToForeground];
/* If a borderless window is offscreen, orderFront: won't move /* If a borderless window is offscreen, orderFront: won't move
it onscreen like it would for a titled window. Do that ourselves. */ it onscreen like it would for a titled window. Do that ourselves. */
@ -723,21 +726,21 @@ - (void) makeFocused
[self setFrame:frame display:YES]; [self setFrame:frame display:YES];
} }
if ([[NSApp orderedWineWindows] count]) if ([[controller orderedWineWindows] count])
{ {
WineWindow* front; WineWindow* front;
if (self.floating) if (self.floating)
front = [[NSApp orderedWineWindows] objectAtIndex:0]; front = [[controller orderedWineWindows] objectAtIndex:0];
else else
{ {
for (front in [NSApp orderedWineWindows]) for (front in [controller orderedWineWindows])
if (!front.floating) break; if (!front.floating) break;
} }
if (front && [front levelWhenActive] > [self levelWhenActive]) if (front && [front levelWhenActive] > [self levelWhenActive])
[self setLevelWhenActive:[front levelWhenActive]]; [self setLevelWhenActive:[front levelWhenActive]];
} }
[self orderFront:nil]; [self orderFront:nil];
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil]; [controller wineWindow:self ordered:NSWindowAbove relativeTo:nil];
causing_becomeKeyWindow = TRUE; causing_becomeKeyWindow = TRUE;
[self makeKeyWindow]; [self makeKeyWindow];
causing_becomeKeyWindow = FALSE; causing_becomeKeyWindow = FALSE;
@ -746,7 +749,7 @@ - (void) makeFocused
if ([latentParentWindow level] > [self level]) if ([latentParentWindow level] > [self level])
[self setLevelWhenActive:[latentParentWindow level]]; [self setLevelWhenActive:[latentParentWindow level]];
[latentParentWindow addChildWindow:self ordered:NSWindowAbove]; [latentParentWindow addChildWindow:self ordered:NSWindowAbove];
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow]; [controller wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
self.latentParentWindow = nil; self.latentParentWindow = nil;
} }
if (![self isExcludedFromWindowsMenu]) if (![self isExcludedFromWindowsMenu])
@ -765,21 +768,21 @@ - (void) postKey:(uint16_t)keyCode
{ {
macdrv_event* event; macdrv_event* event;
CGEventRef cgevent; CGEventRef cgevent;
WineApplication* app = (WineApplication*)NSApp; WineApplicationController* controller = [WineApplicationController sharedController];
event = macdrv_create_event(pressed ? KEY_PRESS : KEY_RELEASE, self); event = macdrv_create_event(pressed ? KEY_PRESS : KEY_RELEASE, self);
event->key.keycode = keyCode; event->key.keycode = keyCode;
event->key.modifiers = modifiers; event->key.modifiers = modifiers;
event->key.time_ms = [app ticksForEventTime:[theEvent timestamp]]; event->key.time_ms = [controller ticksForEventTime:[theEvent timestamp]];
if ((cgevent = [theEvent CGEvent])) if ((cgevent = [theEvent CGEvent]))
{ {
CGEventSourceKeyboardType keyboardType = CGEventGetIntegerValueField(cgevent, CGEventSourceKeyboardType keyboardType = CGEventGetIntegerValueField(cgevent,
kCGKeyboardEventKeyboardType); kCGKeyboardEventKeyboardType);
if (keyboardType != app.keyboardType) if (keyboardType != controller.keyboardType)
{ {
app.keyboardType = keyboardType; controller.keyboardType = keyboardType;
[app keyboardSelectionDidChange]; [controller keyboardSelectionDidChange];
} }
} }
@ -830,7 +833,7 @@ - (void) postMouseMovedEvent:(NSEvent *)theEvent absolute:(BOOL)absolute
if (event->type == MOUSE_MOVED_ABSOLUTE || event->mouse_moved.x || event->mouse_moved.y) if (event->type == MOUSE_MOVED_ABSOLUTE || event->mouse_moved.x || event->mouse_moved.y)
{ {
event->mouse_moved.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; event->mouse_moved.time_ms = [[WineApplicationController sharedController] ticksForEventTime:[theEvent timestamp]];
[queue postEvent:event]; [queue postEvent:event];
} }
@ -889,11 +892,13 @@ - (BOOL) validateMenuItem:(NSMenuItem *)menuItem
- (void) makeKeyAndOrderFront:(id)sender - (void) makeKeyAndOrderFront:(id)sender
{ {
if (![self isKeyWindow] && !self.disabled && !self.noActivate) if (![self isKeyWindow] && !self.disabled && !self.noActivate)
[NSApp windowGotFocus:self]; [[WineApplicationController sharedController] windowGotFocus:self];
} }
- (void) sendEvent:(NSEvent*)event - (void) sendEvent:(NSEvent*)event
{ {
WineApplicationController* controller = [WineApplicationController sharedController];
/* NSWindow consumes certain key-down events as part of Cocoa's keyboard /* NSWindow consumes certain key-down events as part of Cocoa's keyboard
interface control. For example, Control-Tab switches focus among interface control. For example, Control-Tab switches focus among
views. We want to bypass that feature, so directly route key-down views. We want to bypass that feature, so directly route key-down
@ -913,7 +918,7 @@ - (void) sendEvent:(NSEvent*)event
in the window will activate it, if Wine and the Win32 program in the window will activate it, if Wine and the Win32 program
accept. */ accept. */
if (![self isKeyWindow] && !self.disabled && !self.noActivate) if (![self isKeyWindow] && !self.disabled && !self.noActivate)
[NSApp windowGotFocus:self]; [controller windowGotFocus:self];
/* Any left-click on our window anyplace other than the close or /* Any left-click on our window anyplace other than the close or
minimize buttons will bring it forward. */ minimize buttons will bring it forward. */
@ -934,7 +939,7 @@ - (void) sendEvent:(NSEvent*)event
} }
if (broughtWindowForward) if (broughtWindowForward)
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil]; [controller wineWindow:self ordered:NSWindowAbove relativeTo:nil];
} }
[super sendEvent:event]; [super sendEvent:event];
@ -1032,7 +1037,7 @@ - (void) scrollWheel:(NSEvent *)theEvent
event = macdrv_create_event(MOUSE_SCROLL, self); event = macdrv_create_event(MOUSE_SCROLL, self);
event->mouse_scroll.x = pt.x; event->mouse_scroll.x = pt.x;
event->mouse_scroll.y = pt.y; event->mouse_scroll.y = pt.y;
event->mouse_scroll.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]]; event->mouse_scroll.time_ms = [[WineApplicationController sharedController] ticksForEventTime:[theEvent timestamp]];
if (CGEventGetIntegerValueField(cgevent, kCGScrollWheelEventIsContinuous)) if (CGEventGetIntegerValueField(cgevent, kCGScrollWheelEventIsContinuous))
{ {
@ -1103,13 +1108,14 @@ - (void) scrollWheel:(NSEvent *)theEvent
*/ */
- (void)windowDidBecomeKey:(NSNotification *)notification - (void)windowDidBecomeKey:(NSNotification *)notification
{ {
NSEvent* event = [NSApp lastFlagsChanged]; WineApplicationController* controller = [WineApplicationController sharedController];
NSEvent* event = [controller lastFlagsChanged];
if (event) if (event)
[self flagsChanged:event]; [self flagsChanged:event];
if (causing_becomeKeyWindow) return; if (causing_becomeKeyWindow) return;
[NSApp windowGotFocus:self]; [controller windowGotFocus:self];
} }
- (void)windowDidDeminiaturize:(NSNotification *)notification - (void)windowDidDeminiaturize:(NSNotification *)notification
@ -1130,7 +1136,7 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification
ignore_windowDeminiaturize = FALSE; ignore_windowDeminiaturize = FALSE;
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil]; [[WineApplicationController sharedController] wineWindow:self ordered:NSWindowAbove relativeTo:nil];
} }
- (void) windowDidEndLiveResize:(NSNotification *)notification - (void) windowDidEndLiveResize:(NSNotification *)notification
@ -1161,7 +1167,7 @@ - (void)windowDidResize:(NSNotification *)notification
macdrv_event* event; macdrv_event* event;
NSRect frame = [self contentRectForFrameRect:[self frame]]; NSRect frame = [self contentRectForFrameRect:[self frame]];
[NSApp flipRect:&frame]; [[WineApplicationController sharedController] flipRect:&frame];
/* Coalesce events by discarding any previous ones still in the queue. */ /* Coalesce events by discarding any previous ones still in the queue. */
[queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED) [queue discardEventsMatchingMask:event_mask_for_type(WINDOW_FRAME_CHANGED)
@ -1493,7 +1499,7 @@ void macdrv_get_cocoa_window_frame(macdrv_window w, CGRect* out_frame)
NSRect frame; NSRect frame;
frame = [window contentRectForFrameRect:[window frame]]; frame = [window contentRectForFrameRect:[window frame]];
[NSApp flipRect:&frame]; [[WineApplicationController sharedController] flipRect:&frame];
*out_frame = NSRectToCGRect(frame); *out_frame = NSRectToCGRect(frame);
}); });
} }