From d86172cc87663e2fafe087ee335dfa6025be5a9f Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Fri, 4 Oct 2013 23:36:31 +0800 Subject: [PATCH] win: Make window menu's accelerators work. --- browser/native_window_win.cc | 63 ++++++++++++++++++++++++++++++++++++++++++++ browser/native_window_win.h | 17 ++++++++++++ 2 files changed, 80 insertions(+) diff --git a/browser/native_window_win.cc b/browser/native_window_win.cc index da7978f..d4f225e 100644 --- a/browser/native_window_win.cc +++ b/browser/native_window_win.cc @@ -4,8 +4,10 @@ #include "browser/native_window_win.h" +#include "base/stl_util.h" #include "base/strings/utf_string_conversions.h" #include "base/values.h" +#include "browser/api/atom_api_menu.h" #include "browser/ui/win/menu_2.h" #include "browser/ui/win/native_menu_win.h" #include "common/draggable_region.h" @@ -16,6 +18,7 @@ #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "ui/gfx/path.h" +#include "ui/base/models/simple_menu_model.h" #include "ui/views/controls/webview/webview.h" #include "ui/views/widget/widget.h" #include "ui/views/widget/native_widget_win.h" @@ -362,6 +365,7 @@ void NativeWindowWin::OnMenuCommand(int position, HMENU menu) { void NativeWindowWin::SetMenu(ui::MenuModel* menu_model) { menu_.reset(new atom::Menu2(menu_model, true)); ::SetMenu(GetNativeWindow(), menu_->GetNativeMenu()); + RegisterAccelerators(); } void NativeWindowWin::UpdateDraggableRegions( @@ -391,6 +395,16 @@ void NativeWindowWin::UpdateDraggableRegions( void NativeWindowWin::HandleKeyboardEvent( content::WebContents*, const content::NativeWebKeyboardEvent& event) { + if (event.type == WebKit::WebInputEvent::KeyUp) { + ui::Accelerator accelerator( + static_cast(event.windowsKeyCode), + content::GetModifiersFromNativeWebKeyboardEvent(event)); + + if (GetFocusManager()->ProcessAccelerator(accelerator)) { + return; + } + } + // Any unhandled keyboard/character messages should be defproced. // This allows stuff like F10, etc to work correctly. DefWindowProc(event.os_event.hwnd, event.os_event.message, @@ -410,6 +424,17 @@ void NativeWindowWin::ViewHierarchyChanged(bool is_add, AddChildView(web_view_); } +bool NativeWindowWin::AcceleratorPressed( + const ui::Accelerator& accelerator) { + if (ContainsKey(accelerator_table_, accelerator)) { + const MenuItem& item = accelerator_table_[accelerator]; + item.model->ActivatedAt(item.position); + return true; + } else { + return false; + } +} + void NativeWindowWin::DeleteDelegate() { // Do nothing, window is managed by users. } @@ -484,6 +509,44 @@ void NativeWindowWin::OnViewWasResized() { web_contents->GetRenderViewHost()->GetView()->SetClickthroughRegion(rgn); } +void NativeWindowWin::RegisterAccelerators() { + views::FocusManager* focus_manager = GetFocusManager(); + accelerator_table_.clear(); + focus_manager->UnregisterAccelerators(this); + + GenerateAcceleratorTable(); + for (AcceleratorTable::const_iterator iter = accelerator_table_.begin(); + iter != accelerator_table_.end(); ++iter) { + focus_manager->RegisterAccelerator( + iter->first, ui::AcceleratorManager::kNormalPriority, this); + } +} + +void NativeWindowWin::GenerateAcceleratorTable() { + DCHECK(menu_); + ui::SimpleMenuModel* model = static_cast( + menu_->model()); + FillAcceleratorTable(&accelerator_table_, model); +} + +void NativeWindowWin::FillAcceleratorTable(AcceleratorTable* table, + ui::MenuModel* model) { + int count = model->GetItemCount(); + for (int i = 0; i < count; ++i) { + ui::MenuModel::ItemType type = model->GetTypeAt(i); + if (type == ui::MenuModel::TYPE_SUBMENU) { + ui::MenuModel* submodel = model->GetSubmenuModelAt(i); + FillAcceleratorTable(table, submodel); + } else { + ui::Accelerator accelerator; + if (model->GetAcceleratorAt(i, &accelerator)) { + MenuItem item = { i, model }; + (*table)[accelerator] = item; + } + } + } +} + // static NativeWindow* NativeWindow::Create(content::WebContents* web_contents, base::DictionaryValue* options) { diff --git a/browser/native_window_win.h b/browser/native_window_win.h index 499cee3..6004ec2 100644 --- a/browser/native_window_win.h +++ b/browser/native_window_win.h @@ -88,6 +88,7 @@ class NativeWindowWin : public NativeWindow, virtual void ViewHierarchyChanged(bool is_add, views::View* parent, views::View* child) OVERRIDE; + virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; // Overridden from views::WidgetDelegate: virtual void DeleteDelegate() OVERRIDE; @@ -103,14 +104,30 @@ class NativeWindowWin : public NativeWindow, views::Widget* widget) OVERRIDE; private: + typedef struct { int position; ui::MenuModel* model; } MenuItem; + typedef std::map AcceleratorTable; + void OnViewWasResized(); + // Register accelerators supported by the menu model. + void RegisterAccelerators(); + + // Generate a table that contains memu model's accelerators and command ids. + void GenerateAcceleratorTable(); + + // Helper to fill the accelerator table from the model. + void FillAcceleratorTable(AcceleratorTable* table, + ui::MenuModel* model); + scoped_ptr window_; views::WebView* web_view_; // managed by window_. // The window menu. scoped_ptr menu_; + // Map from accelerator to menu item's command id. + AcceleratorTable accelerator_table_; + scoped_ptr draggable_region_; bool resizable_; -- 2.7.4