OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // On Mac, one can't make shortcuts with command-line arguments. Instead, we | 5 // On Mac, one can't make shortcuts with command-line arguments. Instead, we |
6 // produce small app bundles which locate the Chromium framework and load it, | 6 // produce small app bundles which locate the Chromium framework and load it, |
7 // passing the appropriate data. This is the entry point into the framework for | 7 // passing the appropriate data. This is the entry point into the framework for |
8 // those app bundles. | 8 // those app bundles. |
9 | 9 |
10 #import <Cocoa/Cocoa.h> | 10 #import <Cocoa/Cocoa.h> |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 | 57 |
58 // The AppShimController is responsible for communication with the main Chrome | 58 // The AppShimController is responsible for communication with the main Chrome |
59 // process, and generally controls the lifetime of the app shim process. | 59 // process, and generally controls the lifetime of the app shim process. |
60 class AppShimController : public IPC::Listener { | 60 class AppShimController : public IPC::Listener { |
61 public: | 61 public: |
62 AppShimController(); | 62 AppShimController(); |
63 | 63 |
64 // Connects to Chrome and sends a LaunchApp message. | 64 // Connects to Chrome and sends a LaunchApp message. |
65 void Init(); | 65 void Init(); |
66 | 66 |
67 // Builds main menu bar items. | |
68 void SetUpMenu(); | |
69 | |
67 void SendSetAppHidden(bool hidden); | 70 void SendSetAppHidden(bool hidden); |
68 | 71 |
69 void SendQuitApp(); | 72 void SendQuitApp(); |
70 | 73 |
71 // Called when the app is activated, either by the user clicking on it in the | 74 // Called when the app is activated, either by the user clicking on it in the |
72 // dock or by Cmd+Tabbing to it. | 75 // dock or by Cmd+Tabbing to it. |
73 void ActivateApp(bool is_reopen); | 76 void ActivateApp(bool is_reopen); |
74 | 77 |
75 private: | 78 private: |
76 // IPC::Listener implemetation. | 79 // IPC::Listener implemetation. |
(...skipping 13 matching lines...) Expand all Loading... | |
90 bool launch_app_done_; | 93 bool launch_app_done_; |
91 | 94 |
92 DISALLOW_COPY_AND_ASSIGN(AppShimController); | 95 DISALLOW_COPY_AND_ASSIGN(AppShimController); |
93 }; | 96 }; |
94 | 97 |
95 AppShimController::AppShimController() : channel_(NULL), | 98 AppShimController::AppShimController() : channel_(NULL), |
96 launch_app_done_(false) {} | 99 launch_app_done_(false) {} |
97 | 100 |
98 void AppShimController::Init() { | 101 void AppShimController::Init() { |
99 DCHECK(g_io_thread); | 102 DCHECK(g_io_thread); |
103 | |
104 SetUpMenu(); | |
105 | |
106 // Open an IPC channel to Chrome and send the initial app launch message. | |
100 NSString* chrome_bundle_path = | 107 NSString* chrome_bundle_path = |
101 base::SysUTF8ToNSString(g_info->chrome_outer_bundle_path.value()); | 108 base::SysUTF8ToNSString(g_info->chrome_outer_bundle_path.value()); |
102 NSBundle* chrome_bundle = [NSBundle bundleWithPath:chrome_bundle_path]; | 109 NSBundle* chrome_bundle = [NSBundle bundleWithPath:chrome_bundle_path]; |
103 base::FilePath user_data_dir; | 110 base::FilePath user_data_dir; |
104 if (!chrome::GetUserDataDirectoryForBrowserBundle(chrome_bundle, | 111 if (!chrome::GetUserDataDirectoryForBrowserBundle(chrome_bundle, |
105 &user_data_dir)) { | 112 &user_data_dir)) { |
106 Close(); | 113 Close(); |
107 return; | 114 return; |
108 } | 115 } |
109 | 116 |
110 base::FilePath socket_path = | 117 base::FilePath socket_path = |
111 user_data_dir.Append(app_mode::kAppShimSocketName); | 118 user_data_dir.Append(app_mode::kAppShimSocketName); |
112 IPC::ChannelHandle handle(socket_path.value()); | 119 IPC::ChannelHandle handle(socket_path.value()); |
113 channel_ = new IPC::ChannelProxy(handle, IPC::Channel::MODE_NAMED_CLIENT, | 120 channel_ = new IPC::ChannelProxy(handle, IPC::Channel::MODE_NAMED_CLIENT, |
114 this, g_io_thread->message_loop_proxy().get()); | 121 this, g_io_thread->message_loop_proxy().get()); |
115 | 122 |
116 channel_->Send(new AppShimHostMsg_LaunchApp( | 123 channel_->Send(new AppShimHostMsg_LaunchApp( |
117 g_info->profile_dir, g_info->app_mode_id, | 124 g_info->profile_dir, g_info->app_mode_id, |
118 CommandLine::ForCurrentProcess()->HasSwitch(app_mode::kNoLaunchApp) ? | 125 CommandLine::ForCurrentProcess()->HasSwitch(app_mode::kNoLaunchApp) ? |
119 apps::APP_SHIM_LAUNCH_REGISTER_ONLY : apps::APP_SHIM_LAUNCH_NORMAL)); | 126 apps::APP_SHIM_LAUNCH_REGISTER_ONLY : apps::APP_SHIM_LAUNCH_NORMAL)); |
120 | 127 |
121 nsapp_delegate_.reset([[AppShimDelegate alloc] initWithController:this]); | 128 nsapp_delegate_.reset([[AppShimDelegate alloc] initWithController:this]); |
122 DCHECK(![NSApp delegate]); | 129 DCHECK(![NSApp delegate]); |
123 [NSApp setDelegate:nsapp_delegate_]; | 130 [NSApp setDelegate:nsapp_delegate_]; |
124 } | 131 } |
125 | 132 |
133 void AppShimController::SetUpMenu() { | |
134 // The title of the first item is replaced by OSX with the name of the app and | |
135 // bold styling. Since the title can't be replaced, it is hidden in Chrome and | |
136 // the app title has non-bold styling. We can match that here by adding a | |
137 // first element and hiding it. | |
138 NSString* title = base::SysUTF16ToNSString(g_info->app_mode_name); | |
139 base::scoped_nsobject<NSMenu> mainMenu([[NSMenu alloc] initWithTitle:title]); | |
tapted
2013/07/17 07:48:24
nit: mainMenu -> main_menu, since we're in a C++ c
jackhou1
2013/07/22 00:51:46
Done.
| |
140 for (int i = 0; i < 2; ++i) { | |
tapted
2013/07/17 07:48:24
Not sure you need the loop.. can you explain the a
jackhou1
2013/07/22 00:51:46
Done.
Yeah, when all of the app's windows are clo
| |
141 base::scoped_nsobject<NSMenuItem> item( | |
142 [[NSMenuItem alloc] initWithTitle:title | |
143 action:nil | |
144 keyEquivalent:@""]); | |
145 base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:title]); | |
146 [item setSubmenu:menu]; | |
147 [mainMenu addItem:item]; | |
148 } | |
149 [[mainMenu itemAtIndex:0] setHidden:YES]; | |
150 | |
151 NSMenu* submenu = [[mainMenu itemAtIndex:1] submenu]; | |
152 base::scoped_nsobject<NSMenuItem> item( | |
153 [[NSMenuItem alloc] initWithTitle:[@"Quit " stringByAppendingString:title] | |
tapted
2013/07/17 07:48:24
I think you need localization on the string "Quit"
jackhou1
2013/07/22 00:51:46
This turns out to be harder than I thought because
tapted
2013/07/22 02:35:09
Can you just call
ResourceBundle::InitSharedIn
jackhou1
2013/07/22 11:27:04
Ah yup, this is necessary. I also needed to add an
| |
154 action:@selector(terminate:) | |
155 keyEquivalent:@"q"]); | |
156 [submenu addItem:item]; | |
157 | |
158 [NSApp setMainMenu:mainMenu]; | |
159 } | |
160 | |
126 void AppShimController::SendQuitApp() { | 161 void AppShimController::SendQuitApp() { |
127 channel_->Send(new AppShimHostMsg_QuitApp); | 162 channel_->Send(new AppShimHostMsg_QuitApp); |
128 } | 163 } |
129 | 164 |
130 bool AppShimController::OnMessageReceived(const IPC::Message& message) { | 165 bool AppShimController::OnMessageReceived(const IPC::Message& message) { |
131 bool handled = true; | 166 bool handled = true; |
132 IPC_BEGIN_MESSAGE_MAP(AppShimController, message) | 167 IPC_BEGIN_MESSAGE_MAP(AppShimController, message) |
133 IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone) | 168 IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone) |
134 IPC_MESSAGE_UNHANDLED(handled = false) | 169 IPC_MESSAGE_UNHANDLED(handled = false) |
135 IPC_END_MESSAGE_MAP() | 170 IPC_END_MESSAGE_MAP() |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
398 // fully initialized don't receive a reply until its run loop starts. Once | 433 // fully initialized don't receive a reply until its run loop starts. Once |
399 // the reply is received, Chrome will have opened its IPC port, guaranteed. | 434 // the reply is received, Chrome will have opened its IPC port, guaranteed. |
400 [ReplyEventHandler pingProcess:psn andCall:base::Bind(&OnPingChromeReply)]; | 435 [ReplyEventHandler pingProcess:psn andCall:base::Bind(&OnPingChromeReply)]; |
401 | 436 |
402 base::MessageLoopForUI main_message_loop; | 437 base::MessageLoopForUI main_message_loop; |
403 main_message_loop.set_thread_name("MainThread"); | 438 main_message_loop.set_thread_name("MainThread"); |
404 base::PlatformThread::SetName("CrAppShimMain"); | 439 base::PlatformThread::SetName("CrAppShimMain"); |
405 main_message_loop.Run(); | 440 main_message_loop.Run(); |
406 return 0; | 441 return 0; |
407 } | 442 } |
OLD | NEW |