Chromium Code Reviews| Index: chrome/app/chrome_main_app_mode_mac.mm |
| diff --git a/chrome/app/chrome_main_app_mode_mac.mm b/chrome/app/chrome_main_app_mode_mac.mm |
| index 1de3fe5899ec42689fbbc4614cc5863a9ea4f127..9c63a4e927f0ea3ad4dcc2f25f67631dd2b19d81 100644 |
| --- a/chrome/app/chrome_main_app_mode_mac.mm |
| +++ b/chrome/app/chrome_main_app_mode_mac.mm |
| @@ -17,6 +17,7 @@ |
| #include "base/mac/mac_logging.h" |
| #include "base/mac/mac_util.h" |
| #include "base/mac/scoped_nsautorelease_pool.h" |
| +#include "base/memory/scoped_nsobject.h" |
| #include "base/message_loop.h" |
| #include "base/path_service.h" |
| #include "base/strings/sys_string_conversions.h" |
| @@ -36,6 +37,21 @@ base::Thread* g_io_thread = NULL; |
| } // namespace |
| +class AppShimController; |
| + |
| +@interface AppShimDelegate : NSObject<NSApplicationDelegate> { |
| + @private |
| + AppShimController* appShimController_; // Weak. Owns us. |
| + BOOL terminateNow_; |
| + BOOL terminateRequested_; |
| +} |
| + |
| +- (id)initWithController:(AppShimController*)controller; |
| + |
| +- (void)terminateNow; |
| + |
| +@end |
| + |
| // The AppShimController is responsible for communication with the main Chrome |
| // process, and generally controls the lifetime of the app shim process. |
| class AppShimController : public IPC::Listener { |
| @@ -45,6 +61,9 @@ class AppShimController : public IPC::Listener { |
| // Connects to Chrome and sends a LaunchApp message. |
| void Init(); |
| + // Sends a QuitApp message to Chrome. |
| + void QuitApp(); |
| + |
| private: |
| // IPC::Listener implemetation. |
| virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; |
| @@ -59,9 +78,10 @@ class AppShimController : public IPC::Listener { |
| void OnDidActivateApplication(); |
| // Quits the app shim process. |
|
tapted
2013/05/27 06:44:29
nit: Quits -> Terminates
jackhou1
2013/05/28 07:30:22
Done.
|
| - void Quit(); |
| + void Close(); |
| IPC::ChannelProxy* channel_; |
| + scoped_nsobject<AppShimDelegate> nsapp_delegate_; |
| DISALLOW_COPY_AND_ASSIGN(AppShimController); |
| }; |
| @@ -77,7 +97,7 @@ void AppShimController::Init() { |
| base::FilePath user_data_dir; |
| if (!chrome::GetUserDataDirectoryForBrowserBundle(chrome_bundle, |
| &user_data_dir)) { |
| - Quit(); |
| + Close(); |
| return; |
| } |
| @@ -89,6 +109,13 @@ void AppShimController::Init() { |
| channel_->Send(new AppShimHostMsg_LaunchApp( |
| g_info->profile_dir.value(), g_info->app_mode_id)); |
| + |
| + nsapp_delegate_.reset([[AppShimDelegate alloc] initWithController:this]); |
| + [NSApp setDelegate:nsapp_delegate_]; |
| +} |
| + |
| +void AppShimController::QuitApp() { |
| + channel_->Send(new AppShimHostMsg_QuitApp); |
| } |
| bool AppShimController::OnMessageReceived(const IPC::Message& message) { |
| @@ -103,12 +130,12 @@ bool AppShimController::OnMessageReceived(const IPC::Message& message) { |
| void AppShimController::OnChannelError() { |
| LOG(ERROR) << "App shim channel error."; |
| - Quit(); |
| + Close(); |
| } |
| void AppShimController::OnLaunchAppDone(bool success) { |
| if (!success) { |
| - Quit(); |
| + Close(); |
| return; |
| } |
| [[[NSWorkspace sharedWorkspace] notificationCenter] |
| @@ -123,14 +150,46 @@ void AppShimController::OnLaunchAppDone(bool success) { |
| }]; |
| } |
| -void AppShimController::Quit() { |
| - [NSApp terminate:nil]; |
| +void AppShimController::Close() { |
| + [nsapp_delegate_ terminateNow]; |
| } |
| void AppShimController::OnDidActivateApplication() { |
| channel_->Send(new AppShimHostMsg_FocusApp); |
| } |
| +@implementation AppShimDelegate |
| + |
| +- (id)initWithController:(AppShimController*)controller { |
| + if (self = [super init]) { |
|
tapted
2013/05/27 06:44:29
should have double parentheses around the assignme
jackhou1
2013/05/28 07:30:22
Done.
|
| + appShimController_ = controller; |
| + } |
| + return self; |
| +} |
| + |
| +- (NSApplicationTerminateReply) |
| + applicationShouldTerminate:(NSApplication*)sender { |
| + if (terminateNow_) |
| + return NSTerminateNow; |
| + |
| + appShimController_->QuitApp(); |
| + // Wait for the channel to close before terminating. |
| + terminateRequested_ = YES; |
| + return NSTerminateLater; |
| +} |
| + |
| +- (void)terminateNow { |
| + if (terminateRequested_) { |
| + [NSApp replyToApplicationShouldTerminate:NSTerminateNow]; |
| + return; |
| + } |
| + |
| + terminateNow_ = YES; |
| + [NSApp terminate:nil]; |
| +} |
| + |
| +@end |
| + |
| //----------------------------------------------------------------------------- |
| // A ReplyEventHandler is a helper class to send an Apple Event to a process |