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;
@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, ...);

View File

@ -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];
});
}

View File

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

View File

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

View File

@ -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);
});
}