diff options
author | jackhou@chromium.org <jackhou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-30 06:40:19 +0000 |
---|---|---|
committer | jackhou@chromium.org <jackhou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-30 06:40:19 +0000 |
commit | f17047c2350711bba987f7af7eddcbc94bdc470a (patch) | |
tree | fd64d4b96204301e50c043a9655c8c760a2b4c1f /chrome/app | |
parent | 9fa2b496bd83e5770c92e86121aea74b1657642f (diff) | |
download | chromium_src-f17047c2350711bba987f7af7eddcbc94bdc470a.zip chromium_src-f17047c2350711bba987f7af7eddcbc94bdc470a.tar.gz chromium_src-f17047c2350711bba987f7af7eddcbc94bdc470a.tar.bz2 |
Close all windows when app shim quits.
This adds a new IPC message QuitApp which is sent by the shim when the user
quits the shim (right click -> Quit). The AppShimHost responds by closing all
windows associated with the app. The shim actually quits when the extension
eventually closes and AppShimHost closes the channel to the shim.
BUG=168080
TEST=Start an app using its shim.
Right click the app in the dock and select quit.
The shell windows of that app should close.
Review URL: https://chromiumcodereview.appspot.com/14579005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203098 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/app')
-rw-r--r-- | chrome/app/chrome_main_app_mode_mac.mm | 74 |
1 files changed, 67 insertions, 7 deletions
diff --git a/chrome/app/chrome_main_app_mode_mac.mm b/chrome/app/chrome_main_app_mode_mac.mm index 1de3fe5..e464612 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; @@ -58,10 +77,11 @@ class AppShimController : public IPC::Listener { // dock or by Cmd+Tabbing to it. void OnDidActivateApplication(); - // Quits the app shim process. - void Quit(); + // Terminates the app shim process. + 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,14 @@ 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]); + DCHECK(![NSApp delegate]); + [NSApp setDelegate:nsapp_delegate_]; +} + +void AppShimController::QuitApp() { + channel_->Send(new AppShimHostMsg_QuitApp); } bool AppShimController::OnMessageReceived(const IPC::Message& message) { @@ -103,12 +131,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 +151,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])) { + 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 |