OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/auto_reset.h" | 7 #include "base/auto_reset.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
82 // the 10.5 SDK. | 82 // the 10.5 SDK. |
83 #if !defined(MAC_OS_X_VERSION_10_6) || \ | 83 #if !defined(MAC_OS_X_VERSION_10_6) || \ |
84 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 | 84 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 |
85 @interface NSApplication (SnowLeopardSDKDeclarations) | 85 @interface NSApplication (SnowLeopardSDKDeclarations) |
86 - (void)setHelpMenu:(NSMenu*)helpMenu; | 86 - (void)setHelpMenu:(NSMenu*)helpMenu; |
87 @end | 87 @end |
88 #endif | 88 #endif |
89 | 89 |
90 namespace { | 90 namespace { |
91 | 91 |
92 // Declare notification names from the 10.7 SDK. | |
93 #if !defined(MAC_OS_X_VERSION_10_7) || \ | |
94 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | |
95 NSString* NSPopoverDidShowNotification = @"NSPopoverDidShowNotification"; | |
96 NSString* NSPopoverDidCloseNotification = @"NSPopoverDidCloseNotification"; | |
97 #endif | |
98 | |
92 // True while AppController is calling Browser::OpenEmptyWindow(). We need a | 99 // True while AppController is calling Browser::OpenEmptyWindow(). We need a |
93 // global flag here, analogue to BrowserInit::InProcessStartup() because | 100 // global flag here, analogue to BrowserInit::InProcessStartup() because |
94 // otherwise the SessionService will try to restore sessions when we make a new | 101 // otherwise the SessionService will try to restore sessions when we make a new |
95 // window while there are no other active windows. | 102 // window while there are no other active windows. |
96 bool g_is_opening_new_window = false; | 103 bool g_is_opening_new_window = false; |
97 | 104 |
98 // Activates a browser window having the given profile (the last one active) if | 105 // Activates a browser window having the given profile (the last one active) if |
99 // possible and returns a pointer to the activate |Browser| or NULL if this was | 106 // possible and returns a pointer to the activate |Browser| or NULL if this was |
100 // not possible. If the last active browser is minimized (in particular, if | 107 // not possible. If the last active browser is minimized (in particular, if |
101 // there are only minimized windows), it will unminimize it. | 108 // there are only minimized windows), it will unminimize it. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
185 @end | 192 @end |
186 | 193 |
187 @implementation AppController | 194 @implementation AppController |
188 | 195 |
189 @synthesize startupComplete = startupComplete_; | 196 @synthesize startupComplete = startupComplete_; |
190 | 197 |
191 // This method is called very early in application startup (ie, before | 198 // This method is called very early in application startup (ie, before |
192 // the profile is loaded or any preferences have been registered). Defer any | 199 // the profile is loaded or any preferences have been registered). Defer any |
193 // user-data initialization until -applicationDidFinishLaunching:. | 200 // user-data initialization until -applicationDidFinishLaunching:. |
194 - (void)awakeFromNib { | 201 - (void)awakeFromNib { |
195 } | |
196 | |
197 // This method is called very early in application startup (ie, before | |
198 // the profile is loaded or any preferences have been registered), just | |
199 // after -awakeFromNib. This is separate from -awakeFromNib: so that | |
200 // test code can load nibs without these side effects. | |
201 - (void)registerEventHandlersAndInitialize { | |
202 // We need to register the handlers early to catch events fired on launch. | 202 // We need to register the handlers early to catch events fired on launch. |
203 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 203 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
204 [em setEventHandler:self | 204 [em setEventHandler:self |
205 andSelector:@selector(getUrl:withReply:) | 205 andSelector:@selector(getUrl:withReply:) |
206 forEventClass:kInternetEventClass | 206 forEventClass:kInternetEventClass |
207 andEventID:kAEGetURL]; | 207 andEventID:kAEGetURL]; |
208 [em setEventHandler:self | 208 [em setEventHandler:self |
209 andSelector:@selector(submitCloudPrintJob:) | 209 andSelector:@selector(submitCloudPrintJob:) |
210 forEventClass:cloud_print::kAECloudPrintClass | 210 forEventClass:cloud_print::kAECloudPrintClass |
211 andEventID:cloud_print::kAECloudPrintClass]; | 211 andEventID:cloud_print::kAECloudPrintClass]; |
(...skipping 30 matching lines...) Expand all Loading... | |
242 addObserver:self | 242 addObserver:self |
243 selector:@selector(windowLayeringDidChange:) | 243 selector:@selector(windowLayeringDidChange:) |
244 name:NSWindowDidBecomeMainNotification | 244 name:NSWindowDidBecomeMainNotification |
245 object:nil]; | 245 object:nil]; |
246 [notificationCenter | 246 [notificationCenter |
247 addObserver:self | 247 addObserver:self |
248 selector:@selector(windowLayeringDidChange:) | 248 selector:@selector(windowLayeringDidChange:) |
249 name:NSWindowDidResignMainNotification | 249 name:NSWindowDidResignMainNotification |
250 object:nil]; | 250 object:nil]; |
251 | 251 |
252 [notificationCenter | |
Robert Sesek
2012/01/18 17:30:59
Could wrap this in if (base::mac::IsOSLionOrLater(
Alexei Svitkine (slow)
2012/01/18 17:57:38
Done.
| |
253 addObserver:self | |
254 selector:@selector(popoverDidShow:) | |
255 name:NSPopoverDidShowNotification | |
256 object:nil]; | |
257 [notificationCenter | |
258 addObserver:self | |
259 selector:@selector(popoverDidClose:) | |
260 name:NSPopoverDidCloseNotification | |
261 object:nil]; | |
262 | |
252 // Set up the command updater for when there are no windows open | 263 // Set up the command updater for when there are no windows open |
253 [self initMenuState]; | 264 [self initMenuState]; |
254 | 265 |
255 // Initialize the Profile menu. | 266 // Initialize the Profile menu. |
256 [self initProfileMenu]; | 267 [self initProfileMenu]; |
257 } | 268 } |
258 | 269 |
259 - (void)unregisterEventHandlers { | 270 - (void)unregisterEventHandlers { |
260 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; | 271 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; |
261 [em removeEventHandlerForEventClass:kInternetEventClass | 272 [em removeEventHandlerForEventClass:kInternetEventClass |
262 andEventID:kAEGetURL]; | 273 andEventID:kAEGetURL]; |
263 [em removeEventHandlerForEventClass:cloud_print::kAECloudPrintClass | 274 [em removeEventHandlerForEventClass:cloud_print::kAECloudPrintClass |
264 andEventID:cloud_print::kAECloudPrintClass]; | 275 andEventID:cloud_print::kAECloudPrintClass]; |
265 [em removeEventHandlerForEventClass:kAECloudPrintInstallClass | 276 [em removeEventHandlerForEventClass:kAECloudPrintInstallClass |
266 andEventID:kAECloudPrintInstallClass]; | 277 andEventID:kAECloudPrintInstallClass]; |
267 [em removeEventHandlerForEventClass:kAECloudPrintUninstallClass | 278 [em removeEventHandlerForEventClass:kAECloudPrintUninstallClass |
268 andEventID:kAECloudPrintUninstallClass]; | 279 andEventID:kAECloudPrintUninstallClass]; |
269 [em removeEventHandlerForEventClass:'WWW!' | 280 [em removeEventHandlerForEventClass:'WWW!' |
270 andEventID:'OURL']; | 281 andEventID:'OURL']; |
271 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 282 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
272 } | 283 } |
273 | 284 |
274 - (void)dealloc { | |
275 if ([NSApp delegate] == self) | |
276 [NSApp setDelegate:nil]; | |
277 [super dealloc]; | |
278 } | |
279 | |
280 // (NSApplicationDelegate protocol) This is the Apple-approved place to override | 285 // (NSApplicationDelegate protocol) This is the Apple-approved place to override |
281 // the default handlers. | 286 // the default handlers. |
282 - (void)applicationWillFinishLaunching:(NSNotification*)notification { | 287 - (void)applicationWillFinishLaunching:(NSNotification*)notification { |
283 // Nothing here right now. | 288 // Nothing here right now. |
284 } | 289 } |
285 | 290 |
286 - (BOOL)tryToTerminateApplication:(NSApplication*)app { | 291 - (BOOL)tryToTerminateApplication:(NSApplication*)app { |
287 // Check for in-process downloads, and prompt the user if they really want | 292 // Check for in-process downloads, and prompt the user if they really want |
288 // to quit (and thus cancel downloads). Only check if we're not already | 293 // to quit (and thus cancel downloads). Only check if we're not already |
289 // shutting down, else the user might be prompted multiple times if the | 294 // shutting down, else the user might be prompted multiple times if the |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
370 // proper shutdown. If we don't do this, Chrome won't shut down cleanly, | 375 // proper shutdown. If we don't do this, Chrome won't shut down cleanly, |
371 // and may end up crashing when some thread tries to use the IO thread (or | 376 // and may end up crashing when some thread tries to use the IO thread (or |
372 // another thread) that is no longer valid. | 377 // another thread) that is no longer valid. |
373 TabRestoreServiceFactory::ResetForProfile([self lastProfile]); | 378 TabRestoreServiceFactory::ResetForProfile([self lastProfile]); |
374 } | 379 } |
375 } | 380 } |
376 | 381 |
377 // If the window has a tab controller, make "close window" be cmd-shift-w, | 382 // If the window has a tab controller, make "close window" be cmd-shift-w, |
378 // otherwise leave it as the normal cmd-w. Capitalization of the key equivalent | 383 // otherwise leave it as the normal cmd-w. Capitalization of the key equivalent |
379 // affects whether the shift modifer is used. | 384 // affects whether the shift modifer is used. |
380 - (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)hasTabs { | 385 - (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)enableCloseTabShortcut { |
381 [closeWindowMenuItem_ setKeyEquivalent:(hasTabs ? @"W" : @"w")]; | 386 [closeWindowMenuItem_ setKeyEquivalent:(enableCloseTabShortcut ? @"W" : |
387 @"w")]; | |
382 [closeWindowMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask]; | 388 [closeWindowMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask]; |
383 } | 389 } |
384 | 390 |
385 // If the window has a tab controller, make "close tab" take over cmd-w, | 391 // If the window has a tab controller, make "close tab" take over cmd-w, |
386 // otherwise it shouldn't have any key-equivalent because it should be disabled. | 392 // otherwise it shouldn't have any key-equivalent because it should be disabled. |
387 - (void)adjustCloseTabMenuItemKeyEquivalent:(BOOL)hasTabs { | 393 - (void)adjustCloseTabMenuItemKeyEquivalent:(BOOL)enableCloseTabShortcut { |
388 if (hasTabs) { | 394 if (enableCloseTabShortcut) { |
389 [closeTabMenuItem_ setKeyEquivalent:@"w"]; | 395 [closeTabMenuItem_ setKeyEquivalent:@"w"]; |
390 [closeTabMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask]; | 396 [closeTabMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask]; |
391 } else { | 397 } else { |
392 [closeTabMenuItem_ setKeyEquivalent:@""]; | 398 [closeTabMenuItem_ setKeyEquivalent:@""]; |
393 [closeTabMenuItem_ setKeyEquivalentModifierMask:0]; | 399 [closeTabMenuItem_ setKeyEquivalentModifierMask:0]; |
394 } | 400 } |
395 } | 401 } |
396 | 402 |
397 // Explicitly remove any command-key equivalents from the close tab/window | 403 // Explicitly remove any command-key equivalents from the close tab/window |
398 // menus so that nothing can go haywire if we get a user action during pending | 404 // menus so that nothing can go haywire if we get a user action during pending |
(...skipping 17 matching lines...) Expand all Loading... | |
416 // window should be the one that handles the close menu item action. | 422 // window should be the one that handles the close menu item action. |
417 // Also, there might be a small amount of time where there is no key window; | 423 // Also, there might be a small amount of time where there is no key window; |
418 // in that case as well, just use our main browser window if there is one. | 424 // in that case as well, just use our main browser window if there is one. |
419 // You might think that we should just always use the main window, but the | 425 // You might think that we should just always use the main window, but the |
420 // "About Chrome" window serves as a counterexample. | 426 // "About Chrome" window serves as a counterexample. |
421 window = mainWindow; | 427 window = mainWindow; |
422 } | 428 } |
423 | 429 |
424 BOOL hasTabs = | 430 BOOL hasTabs = |
425 [[window windowController] isKindOfClass:[TabWindowController class]]; | 431 [[window windowController] isKindOfClass:[TabWindowController class]]; |
426 [self adjustCloseWindowMenuItemKeyEquivalent:hasTabs]; | 432 BOOL enableCloseTabShortcut = hasTabs && !hasPopover_; |
427 [self adjustCloseTabMenuItemKeyEquivalent:hasTabs]; | 433 [self adjustCloseWindowMenuItemKeyEquivalent:enableCloseTabShortcut]; |
434 [self adjustCloseTabMenuItemKeyEquivalent:enableCloseTabShortcut]; | |
428 } | 435 } |
429 | 436 |
430 // Fix up the "close tab/close window" command-key equivalents. We do this | 437 // Fix up the "close tab/close window" command-key equivalents. We do this |
431 // after a delay to ensure that window layer state has been set by the time | 438 // after a delay to ensure that window layer state has been set by the time |
432 // we do the enabling. This should only be called on the main thread, code that | 439 // we do the enabling. This should only be called on the main thread, code that |
433 // calls this (even as a side-effect) from other threads needs to be fixed. | 440 // calls this (even as a side-effect) from other threads needs to be fixed. |
434 - (void)delayedFixCloseMenuItemKeyEquivalents { | 441 - (void)delayedFixCloseMenuItemKeyEquivalents { |
435 DCHECK([NSThread isMainThread]); | 442 DCHECK([NSThread isMainThread]); |
436 if (!fileMenuUpdatePending_) { | 443 if (!fileMenuUpdatePending_) { |
437 // The OS prefers keypresses to timers, so it's possible that a cmd-w | 444 // The OS prefers keypresses to timers, so it's possible that a cmd-w |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 [windowController isKindOfClass:[BrowserWindowController class]]) { | 487 [windowController isKindOfClass:[BrowserWindowController class]]) { |
481 // If the profile is incognito, use the original profile. | 488 // If the profile is incognito, use the original profile. |
482 Profile* newProfile = [windowController profile]->GetOriginalProfile(); | 489 Profile* newProfile = [windowController profile]->GetOriginalProfile(); |
483 [self windowChangedToProfile:newProfile]; | 490 [self windowChangedToProfile:newProfile]; |
484 } else if (BrowserList::empty()) { | 491 } else if (BrowserList::empty()) { |
485 [self windowChangedToProfile: | 492 [self windowChangedToProfile: |
486 g_browser_process->profile_manager()->GetLastUsedProfile()]; | 493 g_browser_process->profile_manager()->GetLastUsedProfile()]; |
487 } | 494 } |
488 } | 495 } |
489 | 496 |
497 // Called on Lion and later when a popover (e.g. dictionary) is shown. | |
498 - (void)popoverDidShow:(NSNotification*)notify { | |
499 hasPopover_ = YES; | |
500 [self fixCloseMenuItemKeyEquivalents]; | |
501 } | |
502 | |
503 // Called on Lion and later when a popover (e.g. dictionary) is closed. | |
504 - (void)popoverDidClose:(NSNotification*)notify { | |
505 hasPopover_ = NO; | |
506 [self fixCloseMenuItemKeyEquivalents]; | |
507 } | |
508 | |
490 // Called when the user has changed browser windows, meaning the backing profile | 509 // Called when the user has changed browser windows, meaning the backing profile |
491 // may have changed. This can cause a rebuild of the user-data menus. This is a | 510 // may have changed. This can cause a rebuild of the user-data menus. This is a |
492 // no-op if the new profile is the same as the current one. This will always be | 511 // no-op if the new profile is the same as the current one. This will always be |
493 // the original profile and never incognito. | 512 // the original profile and never incognito. |
494 - (void)windowChangedToProfile:(Profile*)profile { | 513 - (void)windowChangedToProfile:(Profile*)profile { |
495 if (lastProfile_ == profile) | 514 if (lastProfile_ == profile) |
496 return; | 515 return; |
497 | 516 |
498 // Before tearing down the menu controller bridges, return the Cocoa menus to | 517 // Before tearing down the menu controller bridges, return the Cocoa menus to |
499 // their initial state. | 518 // their initial state. |
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1102 std::vector<GURL> gurlVector; | 1121 std::vector<GURL> gurlVector; |
1103 gurlVector.push_back(gurl); | 1122 gurlVector.push_back(gurl); |
1104 | 1123 |
1105 [self openUrls:gurlVector]; | 1124 [self openUrls:gurlVector]; |
1106 } | 1125 } |
1107 | 1126 |
1108 // Apple Event handler that receives print event from service | 1127 // Apple Event handler that receives print event from service |
1109 // process, gets the required data and launches Print dialog. | 1128 // process, gets the required data and launches Print dialog. |
1110 - (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event { | 1129 - (void)submitCloudPrintJob:(NSAppleEventDescriptor*)event { |
1111 // Pull parameter list out of Apple Event. | 1130 // Pull parameter list out of Apple Event. |
1112 NSAppleEventDescriptor *paramList = | 1131 NSAppleEventDescriptor* paramList = |
1113 [event paramDescriptorForKeyword:cloud_print::kAECloudPrintClass]; | 1132 [event paramDescriptorForKeyword:cloud_print::kAECloudPrintClass]; |
1114 | 1133 |
1115 if (paramList != nil) { | 1134 if (paramList != nil) { |
1116 // Pull required fields out of parameter list. | 1135 // Pull required fields out of parameter list. |
1117 NSString* mime = [[paramList descriptorAtIndex:1] stringValue]; | 1136 NSString* mime = [[paramList descriptorAtIndex:1] stringValue]; |
1118 NSString* inputPath = [[paramList descriptorAtIndex:2] stringValue]; | 1137 NSString* inputPath = [[paramList descriptorAtIndex:2] stringValue]; |
1119 NSString* printTitle = [[paramList descriptorAtIndex:3] stringValue]; | 1138 NSString* printTitle = [[paramList descriptorAtIndex:3] stringValue]; |
1120 NSString* printTicket = [[paramList descriptorAtIndex:4] stringValue]; | 1139 NSString* printTicket = [[paramList descriptorAtIndex:4] stringValue]; |
1121 // Convert the title to UTF 16 as required. | 1140 // Convert the title to UTF 16 as required. |
1122 string16 title16 = base::SysNSStringToUTF16(printTitle); | 1141 string16 title16 = base::SysNSStringToUTF16(printTitle); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1275 } | 1294 } |
1276 | 1295 |
1277 - (void)clearStartupUrls { | 1296 - (void)clearStartupUrls { |
1278 startupUrls_.clear(); | 1297 startupUrls_.clear(); |
1279 } | 1298 } |
1280 | 1299 |
1281 - (BookmarkMenuBridge*)bookmarkMenuBridge { | 1300 - (BookmarkMenuBridge*)bookmarkMenuBridge { |
1282 return bookmarkMenuBridge_.get(); | 1301 return bookmarkMenuBridge_.get(); |
1283 } | 1302 } |
1284 | 1303 |
1285 - (void)applicationDidChangeScreenParameters:(NSNotification *)notification { | 1304 - (void)applicationDidChangeScreenParameters:(NSNotification*)notification { |
1286 // During this callback the working area is not always already updated. Defer. | 1305 // During this callback the working area is not always already updated. Defer. |
1287 [self performSelector:@selector(delayedPanelManagerScreenParametersUpdate) | 1306 [self performSelector:@selector(delayedPanelManagerScreenParametersUpdate) |
1288 withObject:nil | 1307 withObject:nil |
1289 afterDelay:0]; | 1308 afterDelay:0]; |
1290 } | 1309 } |
1291 | 1310 |
1292 - (void)delayedPanelManagerScreenParametersUpdate { | 1311 - (void)delayedPanelManagerScreenParametersUpdate { |
1293 PanelManager::GetInstance()->OnDisplayChanged(); | 1312 PanelManager::GetInstance()->OnDisplayChanged(); |
1294 } | 1313 } |
1295 | 1314 |
(...skipping 13 matching lines...) Expand all Loading... | |
1309 | 1328 |
1310 } // namespace browser | 1329 } // namespace browser |
1311 | 1330 |
1312 namespace app_controller_mac { | 1331 namespace app_controller_mac { |
1313 | 1332 |
1314 bool IsOpeningNewWindow() { | 1333 bool IsOpeningNewWindow() { |
1315 return g_is_opening_new_window; | 1334 return g_is_opening_new_window; |
1316 } | 1335 } |
1317 | 1336 |
1318 } // namespace app_controller_mac | 1337 } // namespace app_controller_mac |
OLD | NEW |