Commit f8a3912b authored by jackhou@chromium.org's avatar jackhou@chromium.org

Add quit item to app menu.

This also changes the action associated with Quit Chrome when an app
is focused. This is to allow Quit <app> to have the same key binding.
The action closes the app instead of attempting to quit Chrome.

BUG=168080, 276052
TEST=Focus an app's window.
The main menu bar should contain a menu for the app which contains a Quit item.
Selecting the Quit item, or using Cmd+Q quits the app.
TEST=Focus an app's window.
Right click Chrome's dock icon and select Quit.
Chrome and all apps should quit.

Review URL: https://chromiumcodereview.appspot.com/23301018

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220580 0039d316-1c4b-4281-b951-d872f2087c98
parent e6a5d357
......@@ -382,27 +382,12 @@ class AppControllerProfileObserver : public ProfileInfoCacheObserver {
}
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)app {
using apps::ShellWindowRegistry;
// If there are no windows, quit immediately.
if (chrome::BrowserIterator().done() &&
!ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(0)) {
!apps::ShellWindowRegistry::IsShellWindowRegisteredInAnyProfile(0)) {
return NSTerminateNow;
}
// Check if this is a keyboard initiated quit on an app window. If so, quit
// the app. This could cause the app to trigger another terminate, but that
// will be caught by the no windows condition above.
if ([[app currentEvent] type] == NSKeyDown) {
apps::ShellWindow* shellWindow =
ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
[app keyWindow]);
if (shellWindow) {
apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow);
return NSTerminateCancel;
}
}
// Check if the preference is turned on.
const PrefService* prefs = g_browser_process->local_state();
if (!prefs->GetBoolean(prefs::kConfirmToQuitEnabled)) {
......
......@@ -19,6 +19,8 @@
@private
// The extension id of the currently focused packaged app.
base::scoped_nsobject<NSString> appId_;
// A reference to the "Quit Chrome" menu item.
base::scoped_nsobject<NSMenuItem> chromeMenuQuitItem_;
// A menu item for the currently focused packaged app.
base::scoped_nsobject<NSMenuItem> appMenuItem_;
}
......
......@@ -8,8 +8,10 @@
#include "apps/shell_window.h"
#include "apps/shell_window_registry.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
#import "chrome/browser/ui/cocoa/apps/native_app_window_cocoa.h"
#include "chrome/common/extensions/extension.h"
#include "grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/l10n/l10n_util_mac.h"
......@@ -25,6 +27,8 @@
// If the window belongs to the currently focused app, remove the menu items and
// unhide Chrome menu items.
- (void)removeMenuItems:(NSString*)appId;
// If the currently focused window belongs to a platform app, quit the app.
- (void)quitCurrentPlatformApp;
@end
@implementation AppShimMenuController
......@@ -43,10 +47,28 @@
}
- (void)buildAppMenuItems {
// Find the "Quit Chrome" menu item.
NSMenu* chromeMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
for (NSMenuItem* item in [chromeMenu itemArray]) {
if ([item action] == @selector(terminate:)) {
chromeMenuQuitItem_.reset([item retain]);
break;
}
}
DCHECK(chromeMenuQuitItem_);
appMenuItem_.reset([[NSMenuItem alloc] initWithTitle:@""
action:nil
keyEquivalent:@""]);
base::scoped_nsobject<NSMenu> appMenu([[NSMenu alloc] initWithTitle:@""]);
[appMenu setAutoenablesItems:NO];
NSMenuItem* appMenuQuitItem =
[appMenu addItemWithTitle:@""
action:@selector(quitCurrentPlatformApp)
keyEquivalent:@"q"];
[appMenuQuitItem setKeyEquivalentModifierMask:
[chromeMenuQuitItem_ keyEquivalentModifierMask]];
[appMenuQuitItem setTarget:self];
[appMenuItem_ setSubmenu:appMenu];
}
......@@ -103,10 +125,23 @@
[self removeMenuItems:appId_];
appId_.reset([appId copy]);
// Hide Chrome menu items.
NSMenu* mainMenu = [NSApp mainMenu];
for (NSMenuItem* item in [mainMenu itemArray])
[item setHidden:YES];
NSString* localizedQuitApp =
l10n_util::GetNSStringF(IDS_EXIT_MAC, base::UTF8ToUTF16(app->name()));
NSMenuItem* appMenuQuitItem = [[[appMenuItem_ submenu] itemArray] lastObject];
[appMenuQuitItem setTitle:localizedQuitApp];
// It seems that two menu items that have the same key equivalent must also
// have the same action for the keyboard shortcut to work. (This refers to the
// original keyboard shortcut, regardless of any overrides set in OSX).
// In order to let the appMenuQuitItem have a different action, we remove the
// key equivalent from the chromeMenuQuitItem and restore it later.
[chromeMenuQuitItem_ setKeyEquivalent:@""];
[appMenuItem_ setTitle:appId];
[[appMenuItem_ submenu] setTitle:title];
[mainMenu addItem:appMenuItem_];
......@@ -124,6 +159,19 @@
// Restore the Chrome main menu bar.
for (NSMenuItem* item in [mainMenu itemArray])
[item setHidden:NO];
// Restore the keyboard shortcut to Chrome. This just needs to be set back to
// the original keyboard shortcut, regardless of any overrides in OSX. The
// overrides still work as they are based on the title of the menu item.
[chromeMenuQuitItem_ setKeyEquivalent:@"q"];
}
- (void)quitCurrentPlatformApp {
apps::ShellWindow* shellWindow =
apps::ShellWindowRegistry::GetShellWindowForNativeWindowAnyProfile(
[NSApp keyWindow]);
if (shellWindow)
apps::ExtensionAppShimHandler::QuitAppForWindow(shellWindow);
}
@end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment