summaryrefslogtreecommitdiffstats
path: root/chrome/app
diff options
context:
space:
mode:
authorjackhou@chromium.org <jackhou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-30 06:40:19 +0000
committerjackhou@chromium.org <jackhou@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-05-30 06:40:19 +0000
commitf17047c2350711bba987f7af7eddcbc94bdc470a (patch)
treefd64d4b96204301e50c043a9655c8c760a2b4c1f /chrome/app
parent9fa2b496bd83e5770c92e86121aea74b1657642f (diff)
downloadchromium_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.mm74
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