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

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

Issue 8302021: Prevent extension and bookmark popups from interfering with close window/tab shortcuts. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Just check parent, no grandparents; restore NSValidatedUserInterfaceItem type Created 9 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/browser_window_controller.mm » ('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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/command_line.h" 8 #include "base/command_line.h"
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 if (!BrowserList::HasBrowserWithProfile([self lastProfile])) { 345 if (!BrowserList::HasBrowserWithProfile([self lastProfile])) {
346 // As we're shutting down, we need to nuke the TabRestoreService, which 346 // As we're shutting down, we need to nuke the TabRestoreService, which
347 // will start the shutdown of the NavigationControllers and allow for 347 // will start the shutdown of the NavigationControllers and allow for
348 // proper shutdown. If we don't do this, Chrome won't shut down cleanly, 348 // proper shutdown. If we don't do this, Chrome won't shut down cleanly,
349 // and may end up crashing when some thread tries to use the IO thread (or 349 // and may end up crashing when some thread tries to use the IO thread (or
350 // another thread) that is no longer valid. 350 // another thread) that is no longer valid.
351 TabRestoreServiceFactory::ResetForProfile([self lastProfile]); 351 TabRestoreServiceFactory::ResetForProfile([self lastProfile]);
352 } 352 }
353 } 353 }
354 354
355 // Helper routine to get the window controller if the key window is a tabbed
356 // window, or nil if not. Examples of non-tabbed windows are "about" or
357 // "preferences".
358 - (TabWindowController*)keyWindowTabController {
359 NSWindowController* keyWindowController =
360 [[NSApp keyWindow] windowController];
361 if ([keyWindowController isKindOfClass:[TabWindowController class]])
362 return (TabWindowController*)keyWindowController;
363
364 return nil;
365 }
366
367 // Helper routine to get the window controller if the main window is a tabbed
368 // window, or nil if not. Examples of non-tabbed windows are "about" or
369 // "preferences".
370 - (TabWindowController*)mainWindowTabController {
371 NSWindowController* mainWindowController =
372 [[NSApp mainWindow] windowController];
373 if ([mainWindowController isKindOfClass:[TabWindowController class]])
374 return (TabWindowController*)mainWindowController;
375
376 return nil;
377 }
378
379 // If the window has a tab controller, make "close window" be cmd-shift-w, 355 // If the window has a tab controller, make "close window" be cmd-shift-w,
380 // otherwise leave it as the normal cmd-w. Capitalization of the key equivalent 356 // otherwise leave it as the normal cmd-w. Capitalization of the key equivalent
381 // affects whether the shift modifer is used. 357 // affects whether the shift modifer is used.
382 - (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)hasTabs { 358 - (void)adjustCloseWindowMenuItemKeyEquivalent:(BOOL)hasTabs {
383 [closeWindowMenuItem_ setKeyEquivalent:(hasTabs ? @"W" : @"w")]; 359 [closeWindowMenuItem_ setKeyEquivalent:(hasTabs ? @"W" : @"w")];
384 [closeWindowMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask]; 360 [closeWindowMenuItem_ setKeyEquivalentModifierMask:NSCommandKeyMask];
385 } 361 }
386 362
387 // If the window has a tab controller, make "close tab" take over cmd-w, 363 // If the window has a tab controller, make "close tab" take over cmd-w,
388 // otherwise it shouldn't have any key-equivalent because it should be disabled. 364 // otherwise it shouldn't have any key-equivalent because it should be disabled.
(...skipping 10 matching lines...) Expand all
399 // Explicitly remove any command-key equivalents from the close tab/window 375 // Explicitly remove any command-key equivalents from the close tab/window
400 // menus so that nothing can go haywire if we get a user action during pending 376 // menus so that nothing can go haywire if we get a user action during pending
401 // updates. 377 // updates.
402 - (void)clearCloseMenuItemKeyEquivalents { 378 - (void)clearCloseMenuItemKeyEquivalents {
403 [closeTabMenuItem_ setKeyEquivalent:@""]; 379 [closeTabMenuItem_ setKeyEquivalent:@""];
404 [closeTabMenuItem_ setKeyEquivalentModifierMask:0]; 380 [closeTabMenuItem_ setKeyEquivalentModifierMask:0];
405 [closeWindowMenuItem_ setKeyEquivalent:@""]; 381 [closeWindowMenuItem_ setKeyEquivalent:@""];
406 [closeWindowMenuItem_ setKeyEquivalentModifierMask:0]; 382 [closeWindowMenuItem_ setKeyEquivalentModifierMask:0];
407 } 383 }
408 384
409 // See if we have a window with tabs open, and adjust the key equivalents for 385 // See if the focused window window has tabs, and adjust the key equivalents for
410 // Close Tab/Close Window accordingly. 386 // Close Tab/Close Window accordingly.
411 - (void)fixCloseMenuItemKeyEquivalents:(NSWindow*)window { 387 - (void)fixCloseMenuItemKeyEquivalents {
412 fileMenuUpdatePending_ = NO; 388 fileMenuUpdatePending_ = NO;
413 TabWindowController* tabController = [self keyWindowTabController]; 389
414 if (!tabController && ![NSApp keyWindow]) { 390 NSWindow* window = [NSApp keyWindow];
415 // There might be a small amount of time where there is no key window, 391 NSWindow* mainWindow = [NSApp mainWindow];
416 // so just use our main browser window if there is one. 392 if (!window || ([window parentWindow] == mainWindow)) {
417 tabController = [self mainWindowTabController]; 393 // If the key window is a child of the main window (e.g. a bubble), the main
394 // window should be the one that handles the close menu item action.
395 // Also, there might be a small amount of time where there is no key window;
396 // in that case as well, just use our main browser window if there is one.
397 // You might think that we should just always use the main window, but the
398 // "About Chrome" window serves as a counterexample.
399 window = mainWindow;
418 } 400 }
419 BOOL hasTabs = !!tabController;
420 401
402 BOOL hasTabs =
403 [[window windowController] isKindOfClass:[TabWindowController class]];
421 [self adjustCloseWindowMenuItemKeyEquivalent:hasTabs]; 404 [self adjustCloseWindowMenuItemKeyEquivalent:hasTabs];
422 [self adjustCloseTabMenuItemKeyEquivalent:hasTabs]; 405 [self adjustCloseTabMenuItemKeyEquivalent:hasTabs];
423 } 406 }
424 407
425 // Fix up the "close tab/close window" command-key equivalents. We do this 408 // Fix up the "close tab/close window" command-key equivalents. We do this
426 // after a delay to ensure that window layer state has been set by the time 409 // after a delay to ensure that window layer state has been set by the time
427 // we do the enabling. This should only be called on the main thread, code that 410 // we do the enabling. This should only be called on the main thread, code that
428 // calls this (even as a side-effect) from other threads needs to be fixed. 411 // calls this (even as a side-effect) from other threads needs to be fixed.
429 - (void)delayedFixCloseMenuItemKeyEquivalents:(NSNotification*)notify { 412 - (void)delayedFixCloseMenuItemKeyEquivalents {
430 DCHECK([NSThread isMainThread]); 413 DCHECK([NSThread isMainThread]);
431 if (!fileMenuUpdatePending_) { 414 if (!fileMenuUpdatePending_) {
432 // The OS prefers keypresses to timers, so it's possible that a cmd-w 415 // The OS prefers keypresses to timers, so it's possible that a cmd-w
433 // can sneak in before this timer fires. In order to prevent that from 416 // can sneak in before this timer fires. In order to prevent that from
434 // having any bad consequences, just clear the keys combos altogether. They 417 // having any bad consequences, just clear the keys combos altogether. They
435 // will be reset when the timer eventually fires. 418 // will be reset when the timer eventually fires.
436 if ([NSThread isMainThread]) { 419 if ([NSThread isMainThread]) {
437 fileMenuUpdatePending_ = YES; 420 fileMenuUpdatePending_ = YES;
438 [self clearCloseMenuItemKeyEquivalents]; 421 [self clearCloseMenuItemKeyEquivalents];
439 [self performSelector:@selector(fixCloseMenuItemKeyEquivalents:) 422 [self performSelector:@selector(fixCloseMenuItemKeyEquivalents)
440 withObject:[notify object] 423 withObject:nil
441 afterDelay:0]; 424 afterDelay:0];
442 } else { 425 } else {
443 // This shouldn't be happening, but if it does, force it to the main 426 // This shouldn't be happening, but if it does, force it to the main
444 // thread to avoid dropping the update. Don't mess with 427 // thread to avoid dropping the update. Don't mess with
445 // |fileMenuUpdatePending_| as it's not expected to be threadsafe and 428 // |fileMenuUpdatePending_| as it's not expected to be threadsafe and
446 // there could be a race between the selector finishing and setting the 429 // there could be a race between the selector finishing and setting the
447 // flag. 430 // flag.
448 [self 431 [self
449 performSelectorOnMainThread:@selector(fixCloseMenuItemKeyEquivalents:) 432 performSelectorOnMainThread:@selector(fixCloseMenuItemKeyEquivalents)
450 withObject:[notify object] 433 withObject:nil
451 waitUntilDone:NO]; 434 waitUntilDone:NO];
452 } 435 }
453 } 436 }
454 } 437 }
455 438
456 // Called when we get a notification about the window layering changing to 439 // Called when we get a notification about the window layering changing to
457 // update the UI based on the new main window. 440 // update the UI based on the new main window.
458 - (void)windowLayeringDidChange:(NSNotification*)notify { 441 - (void)windowLayeringDidChange:(NSNotification*)notify {
459 [self delayedFixCloseMenuItemKeyEquivalents:notify]; 442 [self delayedFixCloseMenuItemKeyEquivalents];
460 443
461 if ([notify name] == NSWindowDidResignKeyNotification) { 444 if ([notify name] == NSWindowDidResignKeyNotification) {
462 // If a window is closed, this notification is fired but |[NSApp keyWindow]| 445 // If a window is closed, this notification is fired but |[NSApp keyWindow]|
463 // returns nil regardless of whether any suitable candidates for the key 446 // returns nil regardless of whether any suitable candidates for the key
464 // window remain. It seems that the new key window for the app is not set 447 // window remain. It seems that the new key window for the app is not set
465 // until after this notification is fired, so a check is performed after the 448 // until after this notification is fired, so a check is performed after the
466 // run loop is allowed to spin. 449 // run loop is allowed to spin.
467 [self performSelector:@selector(checkForAnyKeyWindows) 450 [self performSelector:@selector(checkForAnyKeyWindows)
468 withObject:nil 451 withObject:nil
469 afterDelay:0.0]; 452 afterDelay:0.0];
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 1266
1284 } // namespace browser 1267 } // namespace browser
1285 1268
1286 namespace app_controller_mac { 1269 namespace app_controller_mac {
1287 1270
1288 bool IsOpeningNewWindow() { 1271 bool IsOpeningNewWindow() {
1289 return g_is_opening_new_window; 1272 return g_is_opening_new_window;
1290 } 1273 }
1291 1274
1292 } // namespace app_controller_mac 1275 } // namespace app_controller_mac
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/ui/cocoa/browser_window_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698