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 NSString* title = base::SysUTF16ToNSString(g_info->app_mode_name); | |
135 | |
136 // Create a main menu since [NSApp mainMenu] is nil. | |
137 base::scoped_nsobject<NSMenu> main_menu([[NSMenu alloc] initWithTitle:title]); | |
138 | |
139 // The title of the first item is replaced by OSX with the name of the app and | |
140 // bold styling. Create a dummy item for this and make it hidden. | |
141 NSMenuItem* dummy_item = [main_menu addItemWithTitle:title | |
142 action:nil | |
143 keyEquivalent:@""]; | |
144 base::scoped_nsobject<NSMenu> dummy_submenu( | |
145 [[NSMenu alloc] initWithTitle:title]); | |
146 [dummy_item setSubmenu:dummy_submenu]; | |
tapted
2013/07/22 02:35:09
just checking - what happens if you delete this li
jackhou1
2013/07/22 11:27:04
The first item is still replaced, but it doesn't g
| |
147 [dummy_item setHidden:YES]; | |
148 | |
149 // Construct an unbolded app menu, to match how it appears in the Chrome menu | |
150 // bar when the app is focused. | |
151 NSMenuItem* item = [main_menu addItemWithTitle:title | |
152 action:nil | |
153 keyEquivalent:@""]; | |
154 base::scoped_nsobject<NSMenu> submenu([[NSMenu alloc] initWithTitle:title]); | |
155 [item setSubmenu:submenu]; | |
156 | |
157 // Add a quit entry. | |
158 [submenu addItemWithTitle:[@"Quit " stringByAppendingString:title] | |
159 action:@selector(terminate:) | |
160 keyEquivalent:@"q"]; | |
161 | |
162 [NSApp setMainMenu:main_menu]; | |
163 } | |
164 | |
126 void AppShimController::SendQuitApp() { | 165 void AppShimController::SendQuitApp() { |
127 channel_->Send(new AppShimHostMsg_QuitApp); | 166 channel_->Send(new AppShimHostMsg_QuitApp); |
128 } | 167 } |
129 | 168 |
130 bool AppShimController::OnMessageReceived(const IPC::Message& message) { | 169 bool AppShimController::OnMessageReceived(const IPC::Message& message) { |
131 bool handled = true; | 170 bool handled = true; |
132 IPC_BEGIN_MESSAGE_MAP(AppShimController, message) | 171 IPC_BEGIN_MESSAGE_MAP(AppShimController, message) |
133 IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone) | 172 IPC_MESSAGE_HANDLER(AppShimMsg_LaunchApp_Done, OnLaunchAppDone) |
134 IPC_MESSAGE_UNHANDLED(handled = false) | 173 IPC_MESSAGE_UNHANDLED(handled = false) |
135 IPC_END_MESSAGE_MAP() | 174 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 | 437 // 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. | 438 // the reply is received, Chrome will have opened its IPC port, guaranteed. |
400 [ReplyEventHandler pingProcess:psn andCall:base::Bind(&OnPingChromeReply)]; | 439 [ReplyEventHandler pingProcess:psn andCall:base::Bind(&OnPingChromeReply)]; |
401 | 440 |
402 base::MessageLoopForUI main_message_loop; | 441 base::MessageLoopForUI main_message_loop; |
403 main_message_loop.set_thread_name("MainThread"); | 442 main_message_loop.set_thread_name("MainThread"); |
404 base::PlatformThread::SetName("CrAppShimMain"); | 443 base::PlatformThread::SetName("CrAppShimMain"); |
405 main_message_loop.Run(); | 444 main_message_loop.Run(); |
406 return 0; | 445 return 0; |
407 } | 446 } |
OLD | NEW |