From 5a6ff0f80d3a36ad7aa2434377560580a1a36d4d Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 2 Oct 2013 21:24:21 +0800 Subject: [PATCH] win: Add BrowserWindow.setMenu API. --- browser/api/atom_api_menu.cc | 4 ++++ browser/api/atom_api_menu.h | 4 +++- browser/api/atom_api_menu_win.cc | 19 +++++++++++++++++++ browser/api/lib/browser-window.coffee | 8 ++++++++ browser/default_app/default_app.js | 2 ++ browser/native_window_win.cc | 6 ++++++ browser/native_window_win.h | 12 ++++++++++++ 7 files changed, 54 insertions(+), 1 deletion(-) diff --git a/browser/api/atom_api_menu.cc b/browser/api/atom_api_menu.cc index a057f307eb98..06ac6b2542c0 100644 --- a/browser/api/atom_api_menu.cc +++ b/browser/api/atom_api_menu.cc @@ -351,6 +351,10 @@ void Menu::Initialize(v8::Handle target) { NODE_SET_PROTOTYPE_METHOD(t, "popup", Popup); +#if defined(OS_WIN) + NODE_SET_PROTOTYPE_METHOD(t, "attachToWindow", AttachToWindow); +#endif + target->Set(v8::String::NewSymbol("Menu"), t->GetFunction()); #if defined(OS_MACOSX) diff --git a/browser/api/atom_api_menu.h b/browser/api/atom_api_menu.h index afba525f5758..bae25aa0573a 100644 --- a/browser/api/atom_api_menu.h +++ b/browser/api/atom_api_menu.h @@ -68,7 +68,9 @@ class Menu : public EventEmitter, static v8::Handle Popup(const v8::Arguments &args); -#if defined(OS_MACOSX) +#if defined(OS_WIN) + static v8::Handle AttachToWindow(const v8::Arguments &args); +#elif defined(OS_MACOSX) static v8::Handle SetApplicationMenu(const v8::Arguments &args); static v8::Handle SendActionToFirstResponder( const v8::Arguments &args); diff --git a/browser/api/atom_api_menu_win.cc b/browser/api/atom_api_menu_win.cc index 05d133356650..019d011df077 100644 --- a/browser/api/atom_api_menu_win.cc +++ b/browser/api/atom_api_menu_win.cc @@ -4,7 +4,9 @@ #include "browser/api/atom_api_menu_win.h" +#include "browser/native_window_win.h" #include "browser/ui/win/menu_2.h" +#include "common/v8_conversions.h" #include "ui/gfx/point.h" namespace atom { @@ -23,6 +25,23 @@ void MenuWin::Popup(NativeWindow* native_window) { menu_->RunContextMenuAt(gfx::Point(0, 0)); } +// static +v8::Handle Menu::AttachToWindow(const v8::Arguments& args) { + v8::HandleScope scope; + + Menu* self = ObjectWrap::Unwrap(args.This()); + if (self == NULL) + return node::ThrowError("Menu is already destroyed"); + + NativeWindow* native_window; + if (!FromV8Arguments(args, &native_window)) + return node::ThrowTypeError("Bad argument"); + + static_cast(native_window)->SetMenu(self->model_.get()); + + return v8::Undefined(); +} + // static Menu* Menu::Create(v8::Handle wrapper) { return new MenuWin(wrapper); diff --git a/browser/api/lib/browser-window.coffee b/browser/api/lib/browser-window.coffee index 452151c7bcd7..56d03e997c66 100644 --- a/browser/api/lib/browser-window.coffee +++ b/browser/api/lib/browser-window.coffee @@ -17,6 +17,14 @@ BrowserWindow::toggleDevTools = -> BrowserWindow::restart = -> @loadUrl(@getUrl()) +BrowserWindow::setMenu = (menu) -> + throw new Error('BrowserWindow.setMenu is only available on Windows') unless process.platform is 'win32' + + throw new TypeError('Invalid menu') unless menu?.constructor?.name is 'Menu' + + @menu = menu # Keep a reference of menu in case of GC. + @menu.attachToWindow this + BrowserWindow.getFocusedWindow = -> windows = objectsRegistry.getAllWindows() return window for window in windows when window.isFocused() diff --git a/browser/default_app/default_app.js b/browser/default_app/default_app.js index 7be7f5bfc4c9..a40e876c43cc 100644 --- a/browser/default_app/default_app.js +++ b/browser/default_app/default_app.js @@ -159,6 +159,8 @@ app.on('finish-launching', function() { if (process.platform == 'darwin') Menu.setApplicationMenu(menu); + else + mainWindow.setMenu(menu); ipc.on('message', function(processId, routingId, type) { console.log(type); diff --git a/browser/native_window_win.cc b/browser/native_window_win.cc index c8ac370e0c8d..57c5edf27e44 100644 --- a/browser/native_window_win.cc +++ b/browser/native_window_win.cc @@ -6,6 +6,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "browser/ui/win/menu_2.h" #include "common/draggable_region.h" #include "common/options_switches.h" #include "content/public/browser/native_web_keyboard_event.h" @@ -325,6 +326,11 @@ gfx::NativeWindow NativeWindowWin::GetNativeWindow() { return window_->GetNativeView(); } +void NativeWindowWin::SetMenu(ui::MenuModel* menu_model) { + menu_.reset(new atom::Menu2(menu_model, true)); + ::SetMenu(GetNativeWindow(), menu_->GetNativeMenu()); +} + void NativeWindowWin::UpdateDraggableRegions( const std::vector& regions) { if (has_frame_) diff --git a/browser/native_window_win.h b/browser/native_window_win.h index 810b3eeb55ed..e5cdad1eca83 100644 --- a/browser/native_window_win.h +++ b/browser/native_window_win.h @@ -12,6 +12,10 @@ #include "ui/gfx/size.h" #include "ui/views/widget/widget_delegate.h" +namespace ui { +class MenuModel; +} + namespace views { class WebView; class Widget; @@ -19,6 +23,8 @@ class Widget; namespace atom { +class Menu2; + class NativeWindowWin : public NativeWindow, public views::WidgetDelegate { public: @@ -60,6 +66,9 @@ class NativeWindowWin : public NativeWindow, virtual bool IsKiosk() OVERRIDE; virtual gfx::NativeWindow GetNativeWindow() OVERRIDE; + // Set the native window menu. + void SetMenu(ui::MenuModel* menu_model); + SkRegion* draggable_region() { return draggable_region_.get(); } protected: @@ -89,6 +98,9 @@ class NativeWindowWin : public NativeWindow, scoped_ptr window_; views::WebView* web_view_; // managed by window_. + // The window menu. + scoped_ptr menu_; + scoped_ptr draggable_region_; bool resizable_;