| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 #import "chrome/browser/app_controller_mac.h" | 5 #import "chrome/browser/app_controller_mac.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "base/sys_string_conversions.h" | 9 #include "base/sys_string_conversions.h" |
| 10 #include "chrome/app/chrome_dll_resource.h" | 10 #include "chrome/app/chrome_dll_resource.h" |
| 11 #include "chrome/browser/browser.h" | 11 #include "chrome/browser/browser.h" |
| 12 #include "chrome/browser/browser_init.h" | 12 #include "chrome/browser/browser_init.h" |
| 13 #include "chrome/browser/browser_list.h" | 13 #include "chrome/browser/browser_list.h" |
| 14 #include "chrome/browser/browser_shutdown.h" | 14 #include "chrome/browser/browser_shutdown.h" |
| 15 #import "chrome/browser/cocoa/bookmark_menu_bridge.h" | 15 #import "chrome/browser/cocoa/bookmark_menu_bridge.h" |
| 16 #include "chrome/browser/command_updater.h" | 16 #include "chrome/browser/command_updater.h" |
| 17 #include "chrome/browser/profile_manager.h" | 17 #include "chrome/browser/profile_manager.h" |
| 18 #include "chrome/common/temp_scaffolding_stubs.h" | 18 #include "chrome/common/temp_scaffolding_stubs.h" |
| 19 | 19 |
| 20 @interface AppController(PRIVATE) | 20 @interface AppController(PRIVATE) |
| 21 - (void)initMenuState; | 21 - (void)initMenuState; |
| 22 - (void)getUrl:(NSAppleEventDescriptor*)event | 22 - (void)getUrl:(NSAppleEventDescriptor*)event |
| 23 withReply:(NSAppleEventDescriptor*)reply; | 23 withReply:(NSAppleEventDescriptor*)reply; |
| 24 - (void)openFiles:(NSAppleEventDescriptor*)event |
| 25 withReply:(NSAppleEventDescriptor*)reply; |
| 24 @end | 26 @end |
| 25 | 27 |
| 26 @implementation AppController | 28 @implementation AppController |
| 27 | 29 |
| 28 - (void)awakeFromNib { | 30 - (void)awakeFromNib { |
| 29 // Set up the command updater for when there are no windows open | 31 // Set up the command updater for when there are no windows open |
| 30 [self initMenuState]; | 32 [self initMenuState]; |
| 31 bookmarkMenuBridge_ = new BookmarkMenuBridge(); | 33 bookmarkMenuBridge_ = new BookmarkMenuBridge(); |
| 32 } | 34 } |
| 33 | 35 |
| 34 - (void)applicationDidFinishLaunching:(NSNotification*)notify { | 36 - (void)applicationDidFinishLaunching:(NSNotification*)notify { |
| 35 // Hold an extra ref to the BrowserProcess singleton so it doesn't go away | 37 // Hold an extra ref to the BrowserProcess singleton so it doesn't go away |
| 36 // when all the browser windows get closed. We'll release it on quit which | 38 // when all the browser windows get closed. We'll release it on quit which |
| 37 // will be the signal to exit. | 39 // will be the signal to exit. |
| 38 DCHECK(g_browser_process); | 40 DCHECK(g_browser_process); |
| 39 g_browser_process->AddRefModule(); | 41 g_browser_process->AddRefModule(); |
| 40 | 42 |
| 41 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 43 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| 42 [em setEventHandler:self | 44 [em setEventHandler:self |
| 43 andSelector:@selector(getUrl:withReply:) | 45 andSelector:@selector(getUrl:withReply:) |
| 44 forEventClass:kInternetEventClass | 46 forEventClass:kInternetEventClass |
| 45 andEventID:kAEGetURL]; | 47 andEventID:kAEGetURL]; |
| 46 [em setEventHandler:self | 48 [em setEventHandler:self |
| 47 andSelector:@selector(getUrl:withReply:) | 49 andSelector:@selector(getUrl:withReply:) |
| 48 forEventClass:'WWW!' // A particularly ancient AppleEvent that dates | 50 forEventClass:'WWW!' // A particularly ancient AppleEvent that dates |
| 49 andEventID:'OURL']; // back to the Spyglass days. | 51 andEventID:'OURL']; // back to the Spyglass days. |
| 52 [em setEventHandler:self |
| 53 andSelector:@selector(openFiles:withReply:) |
| 54 forEventClass:kCoreEventClass |
| 55 andEventID:kAEOpenDocuments]; |
| 50 } | 56 } |
| 51 | 57 |
| 52 - (void)dealloc { | 58 - (void)dealloc { |
| 53 delete bookmarkMenuBridge_; | 59 delete bookmarkMenuBridge_; |
| 54 delete menuState_; | 60 delete menuState_; |
| 55 [super dealloc]; | 61 [super dealloc]; |
| 56 } | 62 } |
| 57 | 63 |
| 58 // We can't use the standard terminate: method because it will abruptly exit | 64 // We can't use the standard terminate: method because it will abruptly exit |
| 59 // the app and leave things on the stack in an unfinalized state. We need to | 65 // the app and leave things on the stack in an unfinalized state. We need to |
| 60 // post a quit message to our run loop so the stack can gracefully unwind. | 66 // post a quit message to our run loop so the stack can gracefully unwind. |
| 61 - (IBAction)quit:(id)sender { | 67 - (IBAction)quit:(id)sender { |
| 62 // TODO(pinkerton): | 68 // TODO(pinkerton): |
| 63 // since we have to roll it ourselves, ask the delegate (ourselves, really) | 69 // since we have to roll it ourselves, ask the delegate (ourselves, really) |
| 64 // if we should terminate. For example, we might not want to if the user | 70 // if we should terminate. For example, we might not want to if the user |
| 65 // has ongoing downloads or multiple windows/tabs open. However, this would | 71 // has ongoing downloads or multiple windows/tabs open. However, this would |
| 66 // require posting UI and may require spinning up another run loop to | 72 // require posting UI and may require spinning up another run loop to |
| 67 // handle it. If it says to continue, post the quit message, otherwise | 73 // handle it. If it says to continue, post the quit message, otherwise |
| 68 // go back to normal. | 74 // go back to normal. |
| 69 | 75 |
| 70 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 76 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
| 71 [em removeEventHandlerForEventClass:kInternetEventClass | 77 [em removeEventHandlerForEventClass:kInternetEventClass |
| 72 andEventID:kAEGetURL]; | 78 andEventID:kAEGetURL]; |
| 73 [em removeEventHandlerForEventClass:'WWW!' | 79 [em removeEventHandlerForEventClass:'WWW!' |
| 74 andEventID:'OURL']; | 80 andEventID:'OURL']; |
| 81 [em removeEventHandlerForEventClass:kCoreEventClass |
| 82 andEventID:kAEOpenDocuments]; |
| 75 | 83 |
| 76 // TODO(pinkerton): Not sure where this should live, including it here | 84 // TODO(pinkerton): Not sure where this should live, including it here |
| 77 // causes all sorts of asserts from the open renderers. On Windows, it | 85 // causes all sorts of asserts from the open renderers. On Windows, it |
| 78 // lives in Browser::OnWindowClosing, but that's not appropriate on Mac | 86 // lives in Browser::OnWindowClosing, but that's not appropriate on Mac |
| 79 // since we don't shut down when we reach zero windows. | 87 // since we don't shut down when we reach zero windows. |
| 80 // browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE); | 88 // browser_shutdown::OnShutdownStarting(browser_shutdown::WINDOW_CLOSE); |
| 81 | 89 |
| 82 // Close all the windows. | 90 // Close all the windows. |
| 83 BrowserList::CloseAllBrowsers(true); | 91 BrowserList::CloseAllBrowsers(true); |
| 84 | 92 |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 NSString* urlStr = [[event paramDescriptorForKeyword:keyDirectObject] | 191 NSString* urlStr = [[event paramDescriptorForKeyword:keyDirectObject] |
| 184 stringValue]; | 192 stringValue]; |
| 185 | 193 |
| 186 GURL gurl(base::SysNSStringToUTF8(urlStr)); | 194 GURL gurl(base::SysNSStringToUTF8(urlStr)); |
| 187 std::vector<GURL> gurlVector; | 195 std::vector<GURL> gurlVector; |
| 188 gurlVector.push_back(gurl); | 196 gurlVector.push_back(gurl); |
| 189 | 197 |
| 190 OpenURLs(gurlVector); | 198 OpenURLs(gurlVector); |
| 191 } | 199 } |
| 192 | 200 |
| 193 - (void)application:(NSApplication*)sender | 201 - (void)openFiles:(NSAppleEventDescriptor*)event |
| 194 openFiles:(NSArray*)filenames { | 202 withReply:(NSAppleEventDescriptor*)reply { |
| 203 // Ordinarily we'd use the NSApplication delegate method |
| 204 // -application:openFiles:, but Cocoa tries to be smart and it sends files |
| 205 // specified on the command line into that delegate method. That's too smart |
| 206 // for us (our setup isn't done by the time Cocoa triggers the delegate method |
| 207 // and we crash). Since all we want are files dropped on the app icon, and we |
| 208 // have cross-platform code to handle the command-line files anyway, an Apple |
| 209 // Event handler fits the bill just right. |
| 210 NSAppleEventDescriptor* fileList = |
| 211 [event paramDescriptorForKeyword:keyDirectObject]; |
| 212 if (!fileList) |
| 213 return; |
| 195 std::vector<GURL> gurlVector; | 214 std::vector<GURL> gurlVector; |
| 196 | 215 |
| 197 for (NSString* filename in filenames) { | 216 for (NSInteger i = 1; i <= [fileList numberOfItems]; ++i) { |
| 198 NSURL* fileURL = [NSURL fileURLWithPath:filename]; | 217 NSAppleEventDescriptor* fileAliasDesc = [fileList descriptorAtIndex:i]; |
| 199 GURL gurl(base::SysNSStringToUTF8([fileURL absoluteString])); | 218 if (!fileAliasDesc) |
| 219 continue; |
| 220 NSAppleEventDescriptor* fileURLDesc = |
| 221 [fileAliasDesc coerceToDescriptorType:typeFileURL]; |
| 222 if (!fileURLDesc) |
| 223 continue; |
| 224 NSData* fileURLData = [fileURLDesc data]; |
| 225 if (!fileURLData) |
| 226 continue; |
| 227 GURL gurl(std::string((char*)[fileURLData bytes], [fileURLData length])); |
| 200 gurlVector.push_back(gurl); | 228 gurlVector.push_back(gurl); |
| 201 } | 229 } |
| 202 | 230 |
| 203 OpenURLs(gurlVector); | 231 OpenURLs(gurlVector); |
| 204 } | 232 } |
| 205 | 233 |
| 206 @end | 234 @end |
| OLD | NEW |