Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1216)

Side by Side Diff: chrome/browser/app_controller_mac.mm

Issue 1520006: Mac: reform our shutdown routine. (Closed)
Patch Set: changed comment Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/app_controller_mac.h ('k') | chrome/browser/browser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 "app/l10n_util_mac.h" 7 #include "app/l10n_util_mac.h"
8 #include "base/auto_reset.h" 8 #include "base/auto_reset.h"
9 #include "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/mac_util.h" 10 #include "base/mac_util.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 131
132 // Sync after a delay avoid I/O contention on startup; 1500 ms is plenty. 132 // Sync after a delay avoid I/O contention on startup; 1500 ms is plenty.
133 ChromeThread::PostDelayedTask(ChromeThread::FILE, FROM_HERE, 133 ChromeThread::PostDelayedTask(ChromeThread::FILE, FROM_HERE,
134 new PrefsSyncTask(), 1500); 134 new PrefsSyncTask(), 1500);
135 } 135 }
136 136
137 } // anonymous namespace 137 } // anonymous namespace
138 138
139 @interface AppController(Private) 139 @interface AppController(Private)
140 - (void)initMenuState; 140 - (void)initMenuState;
141 - (void)handleQuitEvent:(NSAppleEventDescriptor*)event
142 withReply:(NSAppleEventDescriptor*)reply;
141 - (void)openUrls:(const std::vector<GURL>&)urls; 143 - (void)openUrls:(const std::vector<GURL>&)urls;
142 - (void)getUrl:(NSAppleEventDescriptor*)event 144 - (void)getUrl:(NSAppleEventDescriptor*)event
143 withReply:(NSAppleEventDescriptor*)reply; 145 withReply:(NSAppleEventDescriptor*)reply;
144 - (void)windowLayeringDidChange:(NSNotification*)inNotification; 146 - (void)windowLayeringDidChange:(NSNotification*)inNotification;
145 - (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount; 147 - (BOOL)userWillWaitForInProgressDownloads:(int)downloadCount;
146 - (BOOL)shouldQuitWithInProgressDownloads; 148 - (BOOL)shouldQuitWithInProgressDownloads;
147 - (void)showPreferencesWindow:(id)sender 149 - (void)showPreferencesWindow:(id)sender
148 page:(OptionsPage)page 150 page:(OptionsPage)page
149 profile:(Profile*)profile; 151 profile:(Profile*)profile;
150 @end 152 @end
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 // BrowserWindow::Activate() calls ::SetForegroundWindow() which is 212 // BrowserWindow::Activate() calls ::SetForegroundWindow() which is
211 // adequate. On Mac, BrowserWindow::Activate() calls -[NSWindow 213 // adequate. On Mac, BrowserWindow::Activate() calls -[NSWindow
212 // makeKeyAndOrderFront:] which does not activate the application 214 // makeKeyAndOrderFront:] which does not activate the application
213 // itself. 215 // itself.
214 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 216 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
215 if (parsed_command_line.HasSwitch(switches::kActivateOnLaunch)) { 217 if (parsed_command_line.HasSwitch(switches::kActivateOnLaunch)) {
216 [NSApp activateIgnoringOtherApps:YES]; 218 [NSApp activateIgnoringOtherApps:YES];
217 } 219 }
218 } 220 }
219 221
222 // (NSApplicationDelegate protocol) This is the Apple-approved place to override
223 // the default handlers.
224 - (void)applicationWillFinishLaunching:(NSNotification*)notification {
225 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
226 [em setEventHandler:self
227 andSelector:@selector(handleQuitEvent:withReply:)
228 forEventClass:kCoreEventClass
229 andEventID:kAEQuitApplication];
230 }
231
232 // (NSApplicationDelegate protocol) Our mechanism for application termination
233 // does not go through |-applicationShouldTerminate:|, so it should not be
234 // called. In a release build, cancelling termination will prevent a crash (but
235 // if things go really wrong, the user may have to force-terminate the
236 // application).
220 - (NSApplicationTerminateReply)applicationShouldTerminate: 237 - (NSApplicationTerminateReply)applicationShouldTerminate:
221 (NSApplication *)sender { 238 (NSApplication*)sender {
222 // Check for in-progress downloads, and prompt the user if they really want to 239 NOTREACHED();
223 // quit (and thus cancel the downloads). 240 return NSTerminateCancel;
224 if (![self shouldQuitWithInProgressDownloads]) 241 }
225 return NSTerminateCancel;
226 242
227 return NSTerminateNow; 243 - (BOOL)tryToTerminateApplication:(NSApplication*)app {
244 // Set the state to "trying to quit", so that closing all browser windows will
245 // lead to termination.
246 browser_shutdown::SetTryingToQuit(true);
247
248 // TODO(viettrungluu): Remove Apple Event handlers here? (It's safe to leave
249 // them in, but I'm not sure about UX; we'd also want to disable other things
250 // though.) http://crbug.com/40861
251
252 if (!BrowserList::size())
253 return YES;
254
255 // Try to close all the windows.
256 BrowserList::CloseAllBrowsers(true);
257
258 return NO;
259 }
260
261 - (void)stopTryingToTerminateApplication:(NSApplication*)app {
262 if (browser_shutdown::IsTryingToQuit()) {
263 // Reset the "trying to quit" state, so that closing all browser windows
264 // will no longer lead to termination.
265 browser_shutdown::SetTryingToQuit(false);
266
267 // TODO(viettrungluu): Were we to remove Apple Event handlers above, we
268 // would have to reinstall them here. http://crbug.com/40861
269 }
228 } 270 }
229 271
230 // Called when the app is shutting down. Clean-up as appropriate. 272 // Called when the app is shutting down. Clean-up as appropriate.
231 - (void)applicationWillTerminate:(NSNotification *)aNotification { 273 - (void)applicationWillTerminate:(NSNotification*)aNotification {
232 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager]; 274 NSAppleEventManager* em = [NSAppleEventManager sharedAppleEventManager];
233 [em removeEventHandlerForEventClass:kInternetEventClass 275 [em removeEventHandlerForEventClass:kInternetEventClass
234 andEventID:kAEGetURL]; 276 andEventID:kAEGetURL];
235 [em removeEventHandlerForEventClass:'WWW!' 277 [em removeEventHandlerForEventClass:'WWW!'
236 andEventID:'OURL']; 278 andEventID:'OURL'];
237 279
238 // Close all the windows. 280 // There better be no browser windows left at this point.
239 BrowserList::CloseAllBrowsers(true); 281 CHECK_EQ(BrowserList::size(), 0u);
240
241 // On Windows, this is done in Browser::OnWindowClosing, but that's not
242 // appropriate on Mac since we don't shut down when we reach zero windows.
243 browser_shutdown::OnShutdownStarting(browser_shutdown::BROWSER_EXIT);
244 282
245 // Release the reference to the browser process. Once all the browsers get 283 // Release the reference to the browser process. Once all the browsers get
246 // dealloc'd, it will stop the RunLoop and fall back into main(). 284 // dealloc'd, it will stop the RunLoop and fall back into main().
247 g_browser_process->ReleaseModule(); 285 g_browser_process->ReleaseModule();
248 286
249 // Close these off if they have open windows. 287 // Close these off if they have open windows.
250 [prefsController_ close]; 288 [prefsController_ close];
251 [aboutController_ close]; 289 [aboutController_ close];
252 290
253 [[NSNotificationCenter defaultCenter] removeObserver:self]; 291 [[NSNotificationCenter defaultCenter] removeObserver:self];
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 // 1) Same spot as other Pref stuff 426 // 1) Same spot as other Pref stuff
389 // 2) Try and be friendly by keeping this after app launch 427 // 2) Try and be friendly by keeping this after app launch
390 // TODO(jrg): remove once we go Beta. 428 // TODO(jrg): remove once we go Beta.
391 - (void)setUpdateCheckInterval { 429 - (void)setUpdateCheckInterval {
392 #if defined(GOOGLE_CHROME_BUILD) 430 #if defined(GOOGLE_CHROME_BUILD)
393 CFStringRef app = (CFStringRef)@"com.google.Keystone.Agent"; 431 CFStringRef app = (CFStringRef)@"com.google.Keystone.Agent";
394 CFStringRef checkInterval = (CFStringRef)@"checkInterval"; 432 CFStringRef checkInterval = (CFStringRef)@"checkInterval";
395 CFPropertyListRef plist = CFPreferencesCopyAppValue(checkInterval, app); 433 CFPropertyListRef plist = CFPreferencesCopyAppValue(checkInterval, app);
396 if (!plist) { 434 if (!plist) {
397 const float fiveHoursInSeconds = 5.0 * 60.0 * 60.0; 435 const float fiveHoursInSeconds = 5.0 * 60.0 * 60.0;
398 NSNumber *value = [NSNumber numberWithFloat:fiveHoursInSeconds]; 436 NSNumber* value = [NSNumber numberWithFloat:fiveHoursInSeconds];
399 CFPreferencesSetAppValue(checkInterval, value, app); 437 CFPreferencesSetAppValue(checkInterval, value, app);
400 CFPreferencesAppSynchronize(app); 438 CFPreferencesAppSynchronize(app);
401 } 439 }
402 #endif 440 #endif
403 } 441 }
404 442
405 // This is called after profiles have been loaded and preferences registered. 443 // This is called after profiles have been loaded and preferences registered.
406 // It is safe to access the default profile here. 444 // It is safe to access the default profile here.
407 - (void)applicationDidFinishLaunching:(NSNotification*)notify { 445 - (void)applicationDidFinishLaunching:(NSNotification*)notify {
408 // Hold an extra ref to the BrowserProcess singleton so it doesn't go away 446 // Hold an extra ref to the BrowserProcess singleton so it doesn't go away
409 // when all the browser windows get closed. We'll release it on quit which 447 // when all the browser windows get closed. We'll release it on quit which
410 // will be the signal to exit. 448 // will be the signal to exit.
411 DCHECK(g_browser_process); 449 DCHECK(g_browser_process);
412 g_browser_process->AddRefModule(); 450 g_browser_process->AddRefModule();
413 451
414 bookmarkMenuBridge_.reset(new BookmarkMenuBridge([self defaultProfile])); 452 bookmarkMenuBridge_.reset(new BookmarkMenuBridge([self defaultProfile]));
415 historyMenuBridge_.reset(new HistoryMenuBridge([self defaultProfile])); 453 historyMenuBridge_.reset(new HistoryMenuBridge([self defaultProfile]));
416 454
417 [self setUpdateCheckInterval]; 455 [self setUpdateCheckInterval];
418 456
419 // Build up the encoding menu, the order of the items differs based on the 457 // Build up the encoding menu, the order of the items differs based on the
420 // current locale (see http://crbug.com/7647 for details). 458 // current locale (see http://crbug.com/7647 for details).
421 // We need a valid g_browser_process to get the profile which is why we can't 459 // We need a valid g_browser_process to get the profile which is why we can't
422 // call this from awakeFromNib. 460 // call this from awakeFromNib.
423 NSMenu* view_menu = [[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] submenu]; 461 NSMenu* view_menu = [[[NSApp mainMenu] itemWithTag:IDC_VIEW_MENU] submenu];
424 NSMenuItem* encoding_menu_item = [view_menu itemWithTag:IDC_ENCODING_MENU]; 462 NSMenuItem* encoding_menu_item = [view_menu itemWithTag:IDC_ENCODING_MENU];
425 NSMenu *encoding_menu = [encoding_menu_item submenu]; 463 NSMenu* encoding_menu = [encoding_menu_item submenu];
426 EncodingMenuControllerDelegate::BuildEncodingMenu([self defaultProfile], 464 EncodingMenuControllerDelegate::BuildEncodingMenu([self defaultProfile],
427 encoding_menu); 465 encoding_menu);
428 466
429 // Since Chrome is localized to more languages than the OS, tell Cocoa which 467 // Since Chrome is localized to more languages than the OS, tell Cocoa which
430 // menu is the Help so it can add the search item to it. 468 // menu is the Help so it can add the search item to it.
431 if (helpMenu_ && [NSApp respondsToSelector:@selector(setHelpMenu:)]) 469 if (helpMenu_ && [NSApp respondsToSelector:@selector(setHelpMenu:)])
432 [NSApp setHelpMenu:helpMenu_]; 470 [NSApp setHelpMenu:helpMenu_];
433 471
434 // Record the path to the (browser) app bundle; this is used by the app mode 472 // Record the path to the (browser) app bundle; this is used by the app mode
435 // shim. 473 // shim.
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 } 833 }
796 834
797 - (Profile*)defaultProfile { 835 - (Profile*)defaultProfile {
798 // TODO(jrg): Find a better way to get the "default" profile. 836 // TODO(jrg): Find a better way to get the "default" profile.
799 if (g_browser_process->profile_manager()) 837 if (g_browser_process->profile_manager())
800 return *g_browser_process->profile_manager()->begin(); 838 return *g_browser_process->profile_manager()->begin();
801 839
802 return NULL; 840 return NULL;
803 } 841 }
804 842
843 // (Private) Never call |-applicationShouldTerminate:|; just make everything go
844 // through |-terminate:|.
845 - (void)handleQuitEvent:(NSAppleEventDescriptor*)event
846 withReply:(NSAppleEventDescriptor*)reply {
847 [NSApp terminate:nil];
848 }
849
805 // Various methods to open URLs that we get in a native fashion. We use 850 // Various methods to open URLs that we get in a native fashion. We use
806 // BrowserInit here because on the other platforms, URLs to open come through 851 // BrowserInit here because on the other platforms, URLs to open come through
807 // the ProcessSingleton, and it calls BrowserInit. It's best to bottleneck the 852 // the ProcessSingleton, and it calls BrowserInit. It's best to bottleneck the
808 // openings through that for uniform handling. 853 // openings through that for uniform handling.
809 854
810 - (void)openUrls:(const std::vector<GURL>&)urls { 855 - (void)openUrls:(const std::vector<GURL>&)urls {
811 // If the browser hasn't started yet, just queue up the URLs. 856 // If the browser hasn't started yet, just queue up the URLs.
812 if (!startupComplete_) { 857 if (!startupComplete_) {
813 startupUrls_.insert(startupUrls_.end(), urls.begin(), urls.end()); 858 startupUrls_.insert(startupUrls_.end(), urls.begin(), urls.end());
814 return; 859 return;
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
974 [appController showPreferencesWindow:nil page:page profile:profile]; 1019 [appController showPreferencesWindow:nil page:page profile:profile];
975 } 1020 }
976 1021
977 namespace app_controller_mac { 1022 namespace app_controller_mac {
978 1023
979 bool IsOpeningNewWindow() { 1024 bool IsOpeningNewWindow() {
980 return g_is_opening_new_window; 1025 return g_is_opening_new_window;
981 } 1026 }
982 1027
983 } // namespace app_controller_mac 1028 } // namespace app_controller_mac
OLDNEW
« no previous file with comments | « chrome/browser/app_controller_mac.h ('k') | chrome/browser/browser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698