From faf7280d1f2432328776f77d39978d0cb2173b78 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 16 May 2013 17:25:02 +0800 Subject: [PATCH] Add API to SendActionToFirstResponder. It's important to bind application menu items to curtain actions of first responder, like 'quit', 'minimize', 'copy' etc. This API gives developers ability to do most of them in javascript. --- browser/api/atom_api_menu.cc | 2 ++ browser/api/atom_api_menu.h | 2 ++ browser/api/atom_api_menu_mac.h | 3 +++ browser/api/atom_api_menu_mac.mm | 23 +++++++++++++++++++++++ browser/api/lib/menu.coffee | 1 + 5 files changed, 31 insertions(+) diff --git a/browser/api/atom_api_menu.cc b/browser/api/atom_api_menu.cc index 291c661d7061..627d1f30a421 100644 --- a/browser/api/atom_api_menu.cc +++ b/browser/api/atom_api_menu.cc @@ -379,6 +379,8 @@ void Menu::Initialize(v8::Handle target) { target->Set(v8::String::NewSymbol("Menu"), t->GetFunction()); NODE_SET_METHOD(target, "setApplicationMenu", SetApplicationMenu); + NODE_SET_METHOD( + target, "sendActionToFirstResponder", SendActionToFirstResponder); } } // namespace api diff --git a/browser/api/atom_api_menu.h b/browser/api/atom_api_menu.h index ae64c648e750..685e22f2c205 100644 --- a/browser/api/atom_api_menu.h +++ b/browser/api/atom_api_menu.h @@ -69,6 +69,8 @@ class Menu : public EventEmitter, static v8::Handle Popup(const v8::Arguments &args); static v8::Handle SetApplicationMenu(const v8::Arguments &args); + static v8::Handle SendActionToFirstResponder( + const v8::Arguments &args); DISALLOW_COPY_AND_ASSIGN(Menu); }; diff --git a/browser/api/atom_api_menu_mac.h b/browser/api/atom_api_menu_mac.h index 0491457be887..d34a19fbf57d 100644 --- a/browser/api/atom_api_menu_mac.h +++ b/browser/api/atom_api_menu_mac.h @@ -31,6 +31,9 @@ class MenuMac : public Menu { // submenus and set their titles. static void FixMenuTitles(NSMenu* menu); + // Fake sending an action from the application menu. + static void SendActionToFirstResponder(const std::string& action); + DISALLOW_COPY_AND_ASSIGN(MenuMac); }; diff --git a/browser/api/atom_api_menu_mac.mm b/browser/api/atom_api_menu_mac.mm index 052579e0c837..b18eda21cd1c 100644 --- a/browser/api/atom_api_menu_mac.mm +++ b/browser/api/atom_api_menu_mac.mm @@ -6,6 +6,7 @@ #include "base/message_loop.h" #include "base/mac/scoped_sending_event.h" +#include "base/strings/sys_string_conversions.h" #include "browser/native_window.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" @@ -71,6 +72,14 @@ void MenuMac::FixMenuTitles(NSMenu* menu) { } } +// static +void MenuMac::SendActionToFirstResponder(const std::string& action) { + SEL selector = NSSelectorFromString(base::SysUTF8ToNSString(action)); + [[NSApplication sharedApplication] sendAction:selector + to:nil + from:[NSApp mainMenu]]; +} + // static v8::Handle Menu::SetApplicationMenu(const v8::Arguments &args) { v8::HandleScope scope; @@ -94,6 +103,20 @@ v8::Handle Menu::SetApplicationMenu(const v8::Arguments &args) { return v8::Undefined(); } +// static +v8::Handle Menu::SendActionToFirstResponder( + const v8::Arguments &args) { + v8::HandleScope scope; + + if (!args[0]->IsString()) + return node::ThrowTypeError("Bad argument"); + + std::string action(*v8::String::Utf8Value(args[0])); + MenuMac::SendActionToFirstResponder(action); + + return v8::Undefined(); +} + // static Menu* Menu::Create(v8::Handle wrapper) { return new MenuMac(wrapper); diff --git a/browser/api/lib/menu.coffee b/browser/api/lib/menu.coffee index d0318945c36d..f2d27a72f915 100644 --- a/browser/api/lib/menu.coffee +++ b/browser/api/lib/menu.coffee @@ -28,5 +28,6 @@ Menu::appendSubMenu = (args...) -> @insertSubMenu -1, args... Menu.setApplicationMenu = (menu) -> throw new TypeError('Invalid menu') unless menu?.constructor is Menu bindings.setApplicationMenu menu +Menu.sendActionToFirstResponder = bindings.sendActionToFirstResponder module.exports = Menu