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 |