winemac: Refactor WineApplication class to separate most logic into a controller class.
This commit is contained in:
parent
304463b4e1
commit
e7d5f329e5
|
@ -35,7 +35,7 @@
|
|||
@class WineWindow;
|
||||
|
||||
|
||||
@interface WineApplication : NSApplication <NSApplicationDelegate>
|
||||
@interface WineApplicationController : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
CFRunLoopSourceRef requestSource;
|
||||
NSMutableArray* requests;
|
||||
|
@ -84,6 +84,8 @@ @interface WineApplication : NSApplication <NSApplicationDelegate>
|
|||
@property (readonly, nonatomic) NSArray* orderedWineWindows;
|
||||
@property (readonly, nonatomic) BOOL areDisplaysCaptured;
|
||||
|
||||
+ (WineApplicationController*) sharedController;
|
||||
|
||||
- (void) transformProcessToForeground;
|
||||
|
||||
- (BOOL) registerEventQueue:(WineEventQueue*)queue;
|
||||
|
@ -104,8 +106,22 @@ - (void) wineWindow:(WineWindow*)window
|
|||
ordered:(NSWindowOrderingMode)order
|
||||
relativeTo:(WineWindow*)otherWindow;
|
||||
|
||||
- (BOOL) handleEvent:(NSEvent*)anEvent;
|
||||
- (void) didSendEvent:(NSEvent*)anEvent;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface WineApplication : NSApplication
|
||||
{
|
||||
WineApplicationController* wineController;
|
||||
}
|
||||
|
||||
@property (readwrite, assign, nonatomic) WineApplicationController* wineController;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
void OnMainThreadAsync(dispatch_block_t block);
|
||||
|
||||
void LogError(const char* func, NSString* format, ...);
|
||||
|
|
|
@ -32,6 +32,28 @@
|
|||
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
|
||||
{
|
||||
CGEventTimestamp timeBefore, timeAfter;
|
||||
|
@ -53,24 +75,39 @@ @implementation WarpRecord
|
|||
@end;
|
||||
|
||||
|
||||
@interface WineApplication ()
|
||||
@interface WineApplicationController ()
|
||||
|
||||
@property (readwrite, copy, nonatomic) NSEvent* lastFlagsChanged;
|
||||
@property (copy, nonatomic) NSArray* cursorFrames;
|
||||
@property (retain, nonatomic) NSTimer* cursorTimer;
|
||||
@property (retain, nonatomic) NSImage* applicationIcon;
|
||||
|
||||
- (void) setupObservations;
|
||||
- (void) applicationDidBecomeActive:(NSNotification *)notification;
|
||||
|
||||
static void PerformRequest(void *info);
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation WineApplication
|
||||
@implementation WineApplicationController
|
||||
|
||||
@synthesize keyboardType, lastFlagsChanged;
|
||||
@synthesize orderedWineWindows, applicationIcon;
|
||||
@synthesize cursorFrames, cursorTimer;
|
||||
|
||||
+ (WineApplicationController*) sharedController
|
||||
{
|
||||
static WineApplicationController* sharedController;
|
||||
static dispatch_once_t once;
|
||||
|
||||
dispatch_once(&once, ^{
|
||||
sharedController = [[self alloc] init];
|
||||
});
|
||||
|
||||
return sharedController;
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
|
@ -106,6 +143,13 @@ - (id) init
|
|||
[self release];
|
||||
return nil;
|
||||
}
|
||||
|
||||
[self setupObservations];
|
||||
|
||||
keyboardType = LMGetKbdType();
|
||||
|
||||
if ([NSApp isActive])
|
||||
[self applicationDidBecomeActive:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -133,7 +177,7 @@ - (void) dealloc
|
|||
|
||||
- (void) transformProcessToForeground
|
||||
{
|
||||
if ([self activationPolicy] != NSApplicationActivationPolicyRegular)
|
||||
if ([NSApp activationPolicy] != NSApplicationActivationPolicyRegular)
|
||||
{
|
||||
NSMenu* mainMenu;
|
||||
NSMenu* submenu;
|
||||
|
@ -141,8 +185,8 @@ - (void) transformProcessToForeground
|
|||
NSString* title;
|
||||
NSMenuItem* item;
|
||||
|
||||
[self setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[self activateIgnoringOtherApps:YES];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
[NSApp activateIgnoringOtherApps:YES];
|
||||
|
||||
mainMenu = [[[NSMenu alloc] init] autorelease];
|
||||
|
||||
|
@ -169,10 +213,10 @@ - (void) transformProcessToForeground
|
|||
[item setSubmenu:submenu];
|
||||
[mainMenu addItem:item];
|
||||
|
||||
[self setMainMenu:mainMenu];
|
||||
[self setWindowsMenu:submenu];
|
||||
[NSApp setMainMenu:mainMenu];
|
||||
[NSApp setWindowsMenu:submenu];
|
||||
|
||||
[self setApplicationIconImage:self.applicationIcon];
|
||||
[NSApp setApplicationIconImage:self.applicationIcon];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -245,7 +289,7 @@ - (void) windowGotFocus:(WineWindow*)window
|
|||
{
|
||||
macdrv_event* event;
|
||||
|
||||
[NSApp invalidateGotFocusEvents];
|
||||
[self invalidateGotFocusEvents];
|
||||
|
||||
event = macdrv_create_event(WINDOW_GOT_FOCUS, window);
|
||||
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 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])
|
||||
{
|
||||
|
@ -673,12 +717,12 @@ - (void) setApplicationIconFromCGImageArray:(NSArray*)images
|
|||
}
|
||||
|
||||
self.applicationIcon = nsimage;
|
||||
[self setApplicationIconImage:nsimage];
|
||||
[NSApp setApplicationIconImage:nsimage];
|
||||
}
|
||||
|
||||
- (void) handleCommandTab
|
||||
{
|
||||
if ([self isActive])
|
||||
if ([NSApp isActive])
|
||||
{
|
||||
NSRunningApplication* thisApp = [NSRunningApplication currentApplication];
|
||||
NSRunningApplication* app;
|
||||
|
@ -700,7 +744,7 @@ - (void) handleCommandTab
|
|||
{
|
||||
// There's another visible app. Just hide ourselves and let
|
||||
// the system activate the other app.
|
||||
[self hide:self];
|
||||
[NSApp hide:self];
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -894,8 +938,8 @@ - (CGEventRef) eventTapWithProxy:(CGEventTapProxy)proxy
|
|||
CGEventRef WineAppEventTapCallBack(CGEventTapProxy proxy, CGEventType type,
|
||||
CGEventRef event, void *refcon)
|
||||
{
|
||||
WineApplication* app = refcon;
|
||||
return [app eventTapWithProxy:proxy type:type event:event];
|
||||
WineApplicationController* controller = refcon;
|
||||
return [controller eventTapWithProxy:proxy type:type event:event];
|
||||
}
|
||||
|
||||
- (BOOL) installEventTap
|
||||
|
@ -1042,7 +1086,7 @@ - (BOOL) startClippingCursor:(CGRect)rect
|
|||
|
||||
clippingCursor = TRUE;
|
||||
cursorClipRect = rect;
|
||||
if ([self isActive])
|
||||
if ([NSApp isActive])
|
||||
[self activateCursorClipping];
|
||||
|
||||
return TRUE;
|
||||
|
@ -1061,16 +1105,19 @@ - (BOOL) stopClippingCursor
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* ---------- NSApplication method overrides ----------
|
||||
*/
|
||||
- (void) sendEvent:(NSEvent*)anEvent
|
||||
// Returns TRUE if the event was handled and caller should do nothing more
|
||||
// with it. Returns FALSE if the caller should process it as normal and
|
||||
// then call -didSendEvent:.
|
||||
- (BOOL) handleEvent:(NSEvent*)anEvent
|
||||
{
|
||||
if ([anEvent type] == NSFlagsChanged)
|
||||
self.lastFlagsChanged = anEvent;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
- (void) didSendEvent:(NSEvent*)anEvent
|
||||
{
|
||||
NSEventType type = [anEvent type];
|
||||
if (type == NSFlagsChanged)
|
||||
self.lastFlagsChanged = anEvent;
|
||||
|
||||
[super sendEvent:anEvent];
|
||||
|
||||
if (type == NSMouseMoved || type == NSLeftMouseDragged ||
|
||||
type == NSRightMouseDragged || type == NSOtherMouseDragged)
|
||||
|
@ -1089,7 +1136,7 @@ - (void) sendEvent:(NSEvent*)anEvent
|
|||
|
||||
windowUnderNumber = [NSWindow windowNumberAtPoint:point
|
||||
belowWindowWithWindowNumber:0];
|
||||
targetWindow = (WineWindow*)[self windowWithWindowNumber:windowUnderNumber];
|
||||
targetWindow = (WineWindow*)[NSApp windowWithWindowNumber:windowUnderNumber];
|
||||
}
|
||||
else
|
||||
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 ----------
|
||||
|
@ -1249,42 +1330,6 @@ - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)send
|
|||
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
|
||||
{
|
||||
[self deactivateCursorClipping];
|
||||
|
@ -1305,17 +1350,17 @@ - (void)applicationWillResignActive:(NSNotification *)notification
|
|||
*/
|
||||
static void PerformRequest(void *info)
|
||||
{
|
||||
WineApplication* app = (WineApplication*)NSApp;
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
|
||||
for (;;)
|
||||
{
|
||||
__block dispatch_block_t block;
|
||||
|
||||
dispatch_sync(app->requestsManipQueue, ^{
|
||||
if ([app->requests count])
|
||||
dispatch_sync(controller->requestsManipQueue, ^{
|
||||
if ([controller->requests count])
|
||||
{
|
||||
block = (dispatch_block_t)[[app->requests objectAtIndex:0] retain];
|
||||
[app->requests removeObjectAtIndex:0];
|
||||
block = (dispatch_block_t)[[controller->requests objectAtIndex:0] retain];
|
||||
[controller->requests removeObjectAtIndex:0];
|
||||
}
|
||||
else
|
||||
block = nil;
|
||||
|
@ -1336,14 +1381,14 @@ static void PerformRequest(void *info)
|
|||
*/
|
||||
void OnMainThreadAsync(dispatch_block_t block)
|
||||
{
|
||||
WineApplication* app = (WineApplication*)NSApp;
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
|
||||
block = [block copy];
|
||||
dispatch_sync(app->requestsManipQueue, ^{
|
||||
[app->requests addObject:block];
|
||||
dispatch_sync(controller->requestsManipQueue, ^{
|
||||
[controller->requests addObject:block];
|
||||
});
|
||||
[block release];
|
||||
CFRunLoopSourceSignal(app->requestSource);
|
||||
CFRunLoopSourceSignal(controller->requestSource);
|
||||
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)
|
||||
{
|
||||
OnMainThread(^{
|
||||
[NSApp windowRejectedFocusEvent:event];
|
||||
[[WineApplicationController sharedController] windowRejectedFocusEvent:event];
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1403,7 +1448,7 @@ CFDataRef macdrv_copy_keyboard_layout(CGEventSourceKeyboardType* keyboard_type,
|
|||
result = CFDataCreateCopy(NULL, uchr);
|
||||
CFRelease(inputSource);
|
||||
|
||||
*keyboard_type = ((WineApplication*)NSApp).keyboardType;
|
||||
*keyboard_type = [WineApplicationController sharedController].keyboardType;
|
||||
*is_iso = (KBGetLayoutType(*keyboard_type) == kKeyboardISO);
|
||||
}
|
||||
});
|
||||
|
@ -1432,7 +1477,7 @@ int macdrv_set_display_mode(const struct macdrv_display* display,
|
|||
__block int ret;
|
||||
|
||||
OnMainThread(^{
|
||||
ret = [NSApp setMode:display_mode forDisplay:display->displayID];
|
||||
ret = [[WineApplicationController sharedController] setMode:display_mode forDisplay:display->displayID];
|
||||
});
|
||||
|
||||
return ret;
|
||||
|
@ -1467,10 +1512,11 @@ void macdrv_set_cursor(CFStringRef name, CFArrayRef frames)
|
|||
if (sel)
|
||||
{
|
||||
OnMainThreadAsync(^{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
NSCursor* cursor = [NSCursor performSelector:sel];
|
||||
[NSApp setCursorWithFrames:nil];
|
||||
[controller setCursorWithFrames:nil];
|
||||
[cursor set];
|
||||
[NSApp unhideCursor];
|
||||
[controller unhideCursor];
|
||||
});
|
||||
}
|
||||
else
|
||||
|
@ -1479,14 +1525,15 @@ void macdrv_set_cursor(CFStringRef name, CFArrayRef frames)
|
|||
if ([nsframes count])
|
||||
{
|
||||
OnMainThreadAsync(^{
|
||||
[NSApp setCursorWithFrames:nsframes];
|
||||
[[WineApplicationController sharedController] setCursorWithFrames:nsframes];
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
OnMainThreadAsync(^{
|
||||
[NSApp setCursorWithFrames:nil];
|
||||
[NSApp hideCursor];
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
[controller setCursorWithFrames:nil];
|
||||
[controller hideCursor];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1502,7 +1549,7 @@ int macdrv_get_cursor_position(CGPoint *pos)
|
|||
{
|
||||
OnMainThread(^{
|
||||
NSPoint location = [NSEvent mouseLocation];
|
||||
location = [NSApp flippedMouseLocation:location];
|
||||
location = [[WineApplicationController sharedController] flippedMouseLocation:location];
|
||||
*pos = NSPointToCGPoint(location);
|
||||
});
|
||||
|
||||
|
@ -1520,7 +1567,7 @@ int macdrv_set_cursor_position(CGPoint pos)
|
|||
__block int ret;
|
||||
|
||||
OnMainThread(^{
|
||||
ret = [NSApp setCursorPosition:pos];
|
||||
ret = [[WineApplicationController sharedController] setCursorPosition:pos];
|
||||
});
|
||||
|
||||
return ret;
|
||||
|
@ -1538,6 +1585,7 @@ int macdrv_clip_cursor(CGRect rect)
|
|||
__block int ret;
|
||||
|
||||
OnMainThread(^{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
BOOL clipping = FALSE;
|
||||
|
||||
if (!CGRectIsInfinite(rect))
|
||||
|
@ -1546,7 +1594,7 @@ int macdrv_clip_cursor(CGRect rect)
|
|||
NSScreen* screen;
|
||||
|
||||
/* Convert the rectangle from top-down coords to bottom-up. */
|
||||
[NSApp flipRect:&nsrect];
|
||||
[controller flipRect:&nsrect];
|
||||
|
||||
clipping = FALSE;
|
||||
for (screen in [NSScreen screens])
|
||||
|
@ -1560,9 +1608,9 @@ int macdrv_clip_cursor(CGRect rect)
|
|||
}
|
||||
|
||||
if (clipping)
|
||||
ret = [NSApp startClippingCursor:rect];
|
||||
ret = [controller startClippingCursor:rect];
|
||||
else
|
||||
ret = [NSApp stopClippingCursor];
|
||||
ret = [controller stopClippingCursor];
|
||||
});
|
||||
|
||||
return ret;
|
||||
|
@ -1581,7 +1629,7 @@ void macdrv_set_application_icon(CFArrayRef images)
|
|||
NSArray* imageArray = (NSArray*)images;
|
||||
|
||||
OnMainThreadAsync(^{
|
||||
[NSApp setApplicationIconFromCGImageArray:imageArray];
|
||||
[[WineApplicationController sharedController] setApplicationIconFromCGImageArray:imageArray];
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,9 @@ - (BOOL) query:(macdrv_query*)query timeout:(NSTimeInterval)timeout processEvent
|
|||
|
||||
[self postEvent: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;
|
||||
}
|
||||
|
||||
|
@ -347,7 +349,7 @@ macdrv_event_queue macdrv_create_event_queue(macdrv_event_handler handler)
|
|||
queue = [[[WineEventQueue alloc] initWithEventHandler:handler] autorelease];
|
||||
if (queue)
|
||||
{
|
||||
if ([NSApp registerEventQueue:queue])
|
||||
if ([[WineApplicationController sharedController] registerEventQueue:queue])
|
||||
[threadDict setObject:queue forKey:WineEventQueueThreadDictionaryKey];
|
||||
else
|
||||
queue = nil;
|
||||
|
@ -370,7 +372,7 @@ void macdrv_destroy_event_queue(macdrv_event_queue queue)
|
|||
WineEventQueue* q = (WineEventQueue*)queue;
|
||||
NSMutableDictionary* threadDict = [[NSThread currentThread] threadDictionary];
|
||||
|
||||
[NSApp unregisterEventQueue:q];
|
||||
[[WineApplicationController sharedController] unregisterEventQueue:q];
|
||||
[threadDict removeObjectForKey:WineEventQueueThreadDictionaryKey];
|
||||
|
||||
[pool release];
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
NSConditionLock* lock;
|
||||
unsigned long long tickcount;
|
||||
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;
|
||||
NSConditionLock* lock = startup_info->lock;
|
||||
BOOL created_app = FALSE;
|
||||
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
[WineApplication sharedApplication];
|
||||
[NSApp setDelegate:(WineApplication*)NSApp];
|
||||
[NSApp computeEventTimeAdjustmentFromTicks:startup_info->tickcount uptime:startup_info->uptime_ns];
|
||||
if (!NSApp)
|
||||
{
|
||||
[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()
|
||||
doesn't deallocate it in the middle of us unlocking it. */
|
||||
|
@ -77,8 +89,11 @@ static void run_cocoa_app(void* info)
|
|||
|
||||
[pool release];
|
||||
|
||||
/* Never returns */
|
||||
[NSApp run];
|
||||
if (created_app && startup_info->success)
|
||||
{
|
||||
/* 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.tickcount = tickcount;
|
||||
startup_info.success = FALSE;
|
||||
|
||||
mach_timebase_info(&mach_timebase);
|
||||
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])
|
||||
{
|
||||
[startup_info.lock unlock];
|
||||
ret = 0;
|
||||
ret = !startup_info.success;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -310,7 +310,7 @@ + (WineWindow*) createWindowWithFeatures:(const struct macdrv_window_features*)w
|
|||
WineContentView* contentView;
|
||||
NSTrackingArea* trackingArea;
|
||||
|
||||
[NSApp flipRect:&window_frame];
|
||||
[[WineApplicationController sharedController] flipRect:&window_frame];
|
||||
|
||||
window = [[[self alloc] initWithContentRect:window_frame
|
||||
styleMask:style_mask_for_features(wf)
|
||||
|
@ -394,6 +394,7 @@ - (void) setWindowFeatures:(const struct macdrv_window_features*)wf
|
|||
|
||||
- (void) adjustWindowLevel
|
||||
{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
NSInteger level;
|
||||
BOOL fullscreen, captured;
|
||||
NSScreen* screen;
|
||||
|
@ -402,7 +403,7 @@ - (void) adjustWindowLevel
|
|||
|
||||
screen = screen_covered_by_rect([self frame], [NSScreen screens]);
|
||||
fullscreen = (screen != nil);
|
||||
captured = (screen || [self screen]) && [NSApp areDisplaysCaptured];
|
||||
captured = (screen || [self screen]) && [controller areDisplaysCaptured];
|
||||
|
||||
if (captured || fullscreen)
|
||||
{
|
||||
|
@ -419,10 +420,10 @@ - (void) adjustWindowLevel
|
|||
else
|
||||
level = NSNormalWindowLevel;
|
||||
|
||||
index = [[NSApp orderedWineWindows] indexOfObjectIdenticalTo:self];
|
||||
if (index != NSNotFound && index + 1 < [[NSApp orderedWineWindows] count])
|
||||
index = [[controller orderedWineWindows] indexOfObjectIdenticalTo:self];
|
||||
if (index != NSNotFound && index + 1 < [[controller orderedWineWindows] count])
|
||||
{
|
||||
other = [[NSApp orderedWineWindows] objectAtIndex:index + 1];
|
||||
other = [[controller orderedWineWindows] objectAtIndex:index + 1];
|
||||
if (level < [other level])
|
||||
level = [other level];
|
||||
}
|
||||
|
@ -441,7 +442,7 @@ - (void) adjustWindowLevel
|
|||
{
|
||||
for (; index > 0; index--)
|
||||
{
|
||||
other = [[NSApp orderedWineWindows] objectAtIndex:index - 1];
|
||||
other = [[controller orderedWineWindows] objectAtIndex:index - 1];
|
||||
if ([other level] < level)
|
||||
[other setLevelWhenActive:level];
|
||||
else
|
||||
|
@ -504,10 +505,11 @@ - (void) setMacDrvState:(const struct macdrv_window_state*)state
|
|||
its frame intersects any screen. */
|
||||
- (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
||||
{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
BOOL on_screen = frame_intersects_screens([self frame], [NSScreen screens]);
|
||||
if (on_screen)
|
||||
{
|
||||
[NSApp transformProcessToForeground];
|
||||
[controller transformProcessToForeground];
|
||||
|
||||
if (prev)
|
||||
{
|
||||
|
@ -517,20 +519,20 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
|||
it out of the z-order that Win32 would otherwise establish. */
|
||||
if ([prev level] < [self level])
|
||||
{
|
||||
NSUInteger index = [[NSApp orderedWineWindows] indexOfObjectIdenticalTo:prev];
|
||||
NSUInteger index = [[controller orderedWineWindows] indexOfObjectIdenticalTo:prev];
|
||||
if (index != NSNotFound)
|
||||
{
|
||||
[prev setLevelWhenActive:[self level]];
|
||||
for (; index > 0; index--)
|
||||
{
|
||||
WineWindow* other = [[NSApp orderedWineWindows] objectAtIndex:index - 1];
|
||||
WineWindow* other = [[controller orderedWineWindows] objectAtIndex:index - 1];
|
||||
if ([other level] < [self level])
|
||||
[other setLevelWhenActive:[self level]];
|
||||
}
|
||||
}
|
||||
}
|
||||
[self orderWindow:NSWindowBelow relativeTo:[prev windowNumber]];
|
||||
[NSApp wineWindow:self ordered:NSWindowBelow relativeTo:prev];
|
||||
[controller wineWindow:self ordered:NSWindowBelow relativeTo:prev];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -538,14 +540,14 @@ - (BOOL) orderBelow:(WineWindow*)prev orAbove:(WineWindow*)next
|
|||
if (next && [next level] > [self level])
|
||||
[self setLevelWhenActive:[next level]];
|
||||
[self orderWindow:NSWindowAbove relativeTo:[next windowNumber]];
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:next];
|
||||
[controller wineWindow:self ordered:NSWindowAbove relativeTo:next];
|
||||
}
|
||||
if (latentParentWindow)
|
||||
{
|
||||
if ([latentParentWindow level] > [self level])
|
||||
[self setLevelWhenActive:[latentParentWindow level]];
|
||||
[latentParentWindow addChildWindow:self ordered:NSWindowAbove];
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
|
||||
[controller wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
|
||||
self.latentParentWindow = nil;
|
||||
}
|
||||
|
||||
|
@ -566,7 +568,7 @@ - (void) doOrderOut
|
|||
self.latentParentWindow = [self parentWindow];
|
||||
[latentParentWindow removeChildWindow:self];
|
||||
[self orderOut:nil];
|
||||
[NSApp wineWindow:self ordered:NSWindowOut relativeTo:nil];
|
||||
[[WineApplicationController sharedController] wineWindow:self ordered:NSWindowOut relativeTo:nil];
|
||||
[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
|
||||
(left, bottom) in a bottom-up space. */
|
||||
[NSApp flipRect:&contentRect];
|
||||
[[WineApplicationController sharedController] flipRect:&contentRect];
|
||||
|
||||
if (on_screen)
|
||||
{
|
||||
|
@ -633,7 +635,7 @@ - (void) setMacDrvParentWindow:(WineWindow*)parent
|
|||
if ([parent level] > [self level])
|
||||
[self setLevelWhenActive:[parent level]];
|
||||
[parent addChildWindow:self ordered:NSWindowAbove];
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:parent];
|
||||
[[WineApplicationController sharedController] wineWindow:self ordered:NSWindowAbove relativeTo:parent];
|
||||
}
|
||||
else
|
||||
self.latentParentWindow = parent;
|
||||
|
@ -697,7 +699,7 @@ - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
|
|||
event->mouse_button.pressed = pressed;
|
||||
event->mouse_button.x = pt.x;
|
||||
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];
|
||||
|
||||
|
@ -706,9 +708,10 @@ - (void) postMouseButtonEvent:(NSEvent *)theEvent pressed:(int)pressed
|
|||
|
||||
- (void) makeFocused
|
||||
{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
NSArray* screens;
|
||||
|
||||
[NSApp transformProcessToForeground];
|
||||
[controller transformProcessToForeground];
|
||||
|
||||
/* If a borderless window is offscreen, orderFront: won't move
|
||||
it onscreen like it would for a titled window. Do that ourselves. */
|
||||
|
@ -723,21 +726,21 @@ - (void) makeFocused
|
|||
[self setFrame:frame display:YES];
|
||||
}
|
||||
|
||||
if ([[NSApp orderedWineWindows] count])
|
||||
if ([[controller orderedWineWindows] count])
|
||||
{
|
||||
WineWindow* front;
|
||||
if (self.floating)
|
||||
front = [[NSApp orderedWineWindows] objectAtIndex:0];
|
||||
front = [[controller orderedWineWindows] objectAtIndex:0];
|
||||
else
|
||||
{
|
||||
for (front in [NSApp orderedWineWindows])
|
||||
for (front in [controller orderedWineWindows])
|
||||
if (!front.floating) break;
|
||||
}
|
||||
if (front && [front levelWhenActive] > [self levelWhenActive])
|
||||
[self setLevelWhenActive:[front levelWhenActive]];
|
||||
}
|
||||
[self orderFront:nil];
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
[controller wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
causing_becomeKeyWindow = TRUE;
|
||||
[self makeKeyWindow];
|
||||
causing_becomeKeyWindow = FALSE;
|
||||
|
@ -746,7 +749,7 @@ - (void) makeFocused
|
|||
if ([latentParentWindow level] > [self level])
|
||||
[self setLevelWhenActive:[latentParentWindow level]];
|
||||
[latentParentWindow addChildWindow:self ordered:NSWindowAbove];
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
|
||||
[controller wineWindow:self ordered:NSWindowAbove relativeTo:latentParentWindow];
|
||||
self.latentParentWindow = nil;
|
||||
}
|
||||
if (![self isExcludedFromWindowsMenu])
|
||||
|
@ -765,21 +768,21 @@ - (void) postKey:(uint16_t)keyCode
|
|||
{
|
||||
macdrv_event* event;
|
||||
CGEventRef cgevent;
|
||||
WineApplication* app = (WineApplication*)NSApp;
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
|
||||
event = macdrv_create_event(pressed ? KEY_PRESS : KEY_RELEASE, self);
|
||||
event->key.keycode = keyCode;
|
||||
event->key.modifiers = modifiers;
|
||||
event->key.time_ms = [app ticksForEventTime:[theEvent timestamp]];
|
||||
event->key.time_ms = [controller ticksForEventTime:[theEvent timestamp]];
|
||||
|
||||
if ((cgevent = [theEvent CGEvent]))
|
||||
{
|
||||
CGEventSourceKeyboardType keyboardType = CGEventGetIntegerValueField(cgevent,
|
||||
kCGKeyboardEventKeyboardType);
|
||||
if (keyboardType != app.keyboardType)
|
||||
if (keyboardType != controller.keyboardType)
|
||||
{
|
||||
app.keyboardType = keyboardType;
|
||||
[app keyboardSelectionDidChange];
|
||||
controller.keyboardType = keyboardType;
|
||||
[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)
|
||||
{
|
||||
event->mouse_moved.time_ms = [NSApp ticksForEventTime:[theEvent timestamp]];
|
||||
event->mouse_moved.time_ms = [[WineApplicationController sharedController] ticksForEventTime:[theEvent timestamp]];
|
||||
|
||||
[queue postEvent:event];
|
||||
}
|
||||
|
@ -889,11 +892,13 @@ - (BOOL) validateMenuItem:(NSMenuItem *)menuItem
|
|||
- (void) makeKeyAndOrderFront:(id)sender
|
||||
{
|
||||
if (![self isKeyWindow] && !self.disabled && !self.noActivate)
|
||||
[NSApp windowGotFocus:self];
|
||||
[[WineApplicationController sharedController] windowGotFocus:self];
|
||||
}
|
||||
|
||||
- (void) sendEvent:(NSEvent*)event
|
||||
{
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
|
||||
/* NSWindow consumes certain key-down events as part of Cocoa's keyboard
|
||||
interface control. For example, Control-Tab switches focus among
|
||||
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
|
||||
accept. */
|
||||
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
|
||||
minimize buttons will bring it forward. */
|
||||
|
@ -934,7 +939,7 @@ - (void) sendEvent:(NSEvent*)event
|
|||
}
|
||||
|
||||
if (broughtWindowForward)
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
[controller wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
}
|
||||
|
||||
[super sendEvent:event];
|
||||
|
@ -1032,7 +1037,7 @@ - (void) scrollWheel:(NSEvent *)theEvent
|
|||
event = macdrv_create_event(MOUSE_SCROLL, self);
|
||||
event->mouse_scroll.x = pt.x;
|
||||
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))
|
||||
{
|
||||
|
@ -1103,13 +1108,14 @@ - (void) scrollWheel:(NSEvent *)theEvent
|
|||
*/
|
||||
- (void)windowDidBecomeKey:(NSNotification *)notification
|
||||
{
|
||||
NSEvent* event = [NSApp lastFlagsChanged];
|
||||
WineApplicationController* controller = [WineApplicationController sharedController];
|
||||
NSEvent* event = [controller lastFlagsChanged];
|
||||
if (event)
|
||||
[self flagsChanged:event];
|
||||
|
||||
if (causing_becomeKeyWindow) return;
|
||||
|
||||
[NSApp windowGotFocus:self];
|
||||
[controller windowGotFocus:self];
|
||||
}
|
||||
|
||||
- (void)windowDidDeminiaturize:(NSNotification *)notification
|
||||
|
@ -1130,7 +1136,7 @@ - (void)windowDidDeminiaturize:(NSNotification *)notification
|
|||
|
||||
ignore_windowDeminiaturize = FALSE;
|
||||
|
||||
[NSApp wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
[[WineApplicationController sharedController] wineWindow:self ordered:NSWindowAbove relativeTo:nil];
|
||||
}
|
||||
|
||||
- (void) windowDidEndLiveResize:(NSNotification *)notification
|
||||
|
@ -1161,7 +1167,7 @@ - (void)windowDidResize:(NSNotification *)notification
|
|||
macdrv_event* event;
|
||||
NSRect frame = [self contentRectForFrameRect:[self frame]];
|
||||
|
||||
[NSApp flipRect:&frame];
|
||||
[[WineApplicationController sharedController] flipRect:&frame];
|
||||
|
||||
/* Coalesce events by discarding any previous ones still in the queue. */
|
||||
[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;
|
||||
|
||||
frame = [window contentRectForFrameRect:[window frame]];
|
||||
[NSApp flipRect:&frame];
|
||||
[[WineApplicationController sharedController] flipRect:&frame];
|
||||
*out_frame = NSRectToCGRect(frame);
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue