X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/518e56a71b339bb1a8f06e25321fd63dd0c849f9..84968677abe36133a45e0426c2a365da18851f90:/src/cocoa/app.mm?ds=sidebyside diff --git a/src/cocoa/app.mm b/src/cocoa/app.mm index 4744ac03ec..6a2c443ac4 100644 --- a/src/cocoa/app.mm +++ b/src/cocoa/app.mm @@ -49,15 +49,40 @@ wxPoseAsInitializer *wxPoseAsInitializer::sm_first = NULL; { } -- (void)doIdle: (id)data; - (void)sendEvent: (NSEvent*)anEvent; -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication; @end // wxPoserNSApplication WX_IMPLEMENT_POSER(wxPoserNSApplication); @implementation wxPoserNSApplication : NSApplication +- (void)sendEvent: (NSEvent*)anEvent +{ + wxLogDebug("SendEvent"); + wxTheApp->CocoaInstallRequestedIdleHandler(); + [super sendEvent: anEvent]; +} + +@end // wxPoserNSApplication + +// ======================================================================== +// wxNSApplicationDelegate +// ======================================================================== +@interface wxNSApplicationDelegate : NSObject +{ +} + +- (void)doIdle: (id)data; +// Delegate methods +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication; +- (void)applicationWillBecomeActive:(NSNotification *)notification; +- (void)applicationDidBecomeActive:(NSNotification *)notification; +- (void)applicationWillResignActive:(NSNotification *)notification; +- (void)applicationDidResignActive:(NSNotification *)notification; +@end // interface wxNSApplicationDelegate : NSObject + +@implementation wxNSApplicationDelegate : NSObject + - (void)doIdle: (id)data { wxASSERT(wxTheApp); @@ -91,21 +116,35 @@ WX_IMPLEMENT_POSER(wxPoserNSApplication); wxTheApp->CocoaRequestIdle(); } -- (void)sendEvent: (NSEvent*)anEvent +// NOTE: Terminate means that the event loop does NOT return and thus +// cleanup code doesn't properly execute. Furthermore, wxWindows has its +// own exit on frame delete mechanism. +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication { - wxLogDebug("SendEvent"); - wxTheApp->CocoaInstallRequestedIdleHandler(); - [super sendEvent: anEvent]; + return NO; } -- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication +- (void)applicationWillBecomeActive:(NSNotification *)notification { - BOOL ret = wxTheApp->GetExitOnFrameDelete(); - wxLogDebug("applicationShouldTermintaeAfterLastWindowClosed=%d",ret); - return ret; + wxTheApp->CocoaDelegate_applicationWillBecomeActive(); } -@end // wxPoserNSApplication +- (void)applicationDidBecomeActive:(NSNotification *)notification +{ + wxTheApp->CocoaDelegate_applicationDidBecomeActive(); +} + +- (void)applicationWillResignActive:(NSNotification *)notification +{ + wxTheApp->CocoaDelegate_applicationWillResignActive(); +} + +- (void)applicationDidResignActive:(NSNotification *)notification +{ + wxTheApp->CocoaDelegate_applicationDidResignActive(); +} + +@end // implementation wxNSApplicationDelegate : NSObject // ======================================================================== // wxApp @@ -151,9 +190,15 @@ bool wxApp::Initialize(int& argc, wxChar **argv) void wxApp::CleanUp() { + wxAutoNSAutoreleasePool pool; + wxDC::CocoaShutdownTextSystem(); wxMenuBarManager::DestroyInstance(); + [m_cocoaApp setDelegate:nil]; + [m_cocoaAppDelegate release]; + m_cocoaAppDelegate = NULL; + wxAppBase::CleanUp(); } @@ -175,6 +220,7 @@ wxApp::wxApp() argc = 0; argv = NULL; m_cocoaApp = NULL; + m_cocoaAppDelegate = NULL; } void wxApp::CocoaInstallIdleHandler() @@ -192,7 +238,33 @@ void wxApp::CocoaInstallIdleHandler() m_isIdle = false; // Call doIdle for EVERYTHING dammit // We'd need Foundation/NSConnection.h for this next constant, do we need it? - [[ NSRunLoop currentRunLoop ] performSelector:@selector(doIdle:) target:m_cocoaApp argument:NULL order:0 modes:[NSArray arrayWithObjects:NSDefaultRunLoopMode, /* NSConnectionReplyRunLoopMode,*/ NSModalPanelRunLoopMode, /**/NSEventTrackingRunLoopMode,/**/ nil] ]; + [[ NSRunLoop currentRunLoop ] performSelector:@selector(doIdle:) target:m_cocoaAppDelegate argument:NULL order:0 modes:[NSArray arrayWithObjects:NSDefaultRunLoopMode, /* NSConnectionReplyRunLoopMode,*/ NSModalPanelRunLoopMode, /**/NSEventTrackingRunLoopMode,/**/ nil] ]; + /* Notes: + In the Mac OS X implementation of Cocoa, the above method schedules + doIdle: to be called from *within* [NSApplication + -nextEventMatchingMask:untilDate:inMode:dequeue:]. That is, no + NSEvent object is generated and control does not return from that + method. In fact, control will only return from that method for the + usual reasons (e.g. a real event is received or the untilDate is reached). + This has implications when trying to stop the event loop and return to + its caller. See wxEventLoop::Exit + */ +} + +void wxApp::CocoaDelegate_applicationWillBecomeActive() +{ +} + +void wxApp::CocoaDelegate_applicationDidBecomeActive() +{ +} + +void wxApp::CocoaDelegate_applicationWillResignActive() +{ +} + +void wxApp::CocoaDelegate_applicationDidResignActive() +{ } bool wxApp::OnInitGui() @@ -203,6 +275,8 @@ bool wxApp::OnInitGui() // Create the app using the sharedApplication method m_cocoaApp = [NSApplication sharedApplication]; + m_cocoaAppDelegate = [[wxNSApplicationDelegate alloc] init]; + [m_cocoaApp setDelegate:m_cocoaAppDelegate]; wxMenuBarManager::CreateInstance(); @@ -210,7 +284,7 @@ bool wxApp::OnInitGui() // [ m_cocoaApp setDelegate:m_cocoaApp ]; #if 0 wxLogDebug("Just for kicks"); - [ m_cocoaApp performSelector:@selector(doIdle:) withObject:NULL ]; + [ m_cocoaAppDelegate performSelector:@selector(doIdle:) withObject:NULL ]; wxLogDebug("okay.. done now"); #endif return TRUE;