diff --git a/atom/browser/native_window_views.cc b/atom/browser/native_window_views.cc index 25a5726694..8523d68283 100644 --- a/atom/browser/native_window_views.cc +++ b/atom/browser/native_window_views.cc @@ -572,9 +572,16 @@ void NativeWindowViews::HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event) { keyboard_event_handler_->HandleKeyboardEvent(event, GetFocusManager()); - if (menu_bar_ && menu_bar_visible_ && IsAltKey(event)) { - menu_bar_->SetAcceleratorVisibility( - event.type == blink::WebInputEvent::RawKeyDown); + if (menu_bar_ && menu_bar_visible_) { + // Toggle accelerator when "Alt" is pressed. + if (IsAltKey(event)) + menu_bar_->SetAcceleratorVisibility( + event.type == blink::WebInputEvent::RawKeyDown); + + // Show the submenu when "Alt+Key" is pressed. + if (event.type == blink::WebInputEvent::RawKeyDown && !IsAltKey(event) && + IsAltModifier(event)) + menu_bar_->ActivateAccelerator(event.windowsKeyCode); } if (!menu_bar_autohide_) diff --git a/atom/browser/ui/views/menu_bar.cc b/atom/browser/ui/views/menu_bar.cc index 73a79cab3f..0dc1b502f1 100644 --- a/atom/browser/ui/views/menu_bar.cc +++ b/atom/browser/ui/views/menu_bar.cc @@ -90,6 +90,17 @@ void MenuBar::SetAcceleratorVisibility(bool visible) { static_cast(child_at(i))->SetAcceleratorVisibility(visible); } +void MenuBar::ActivateAccelerator(base::char16 key) { + for (int i = 0; i < child_count(); ++i) { + SubmenuButton* button = static_cast(child_at(i)); + if (button->accelerator() == key) { + SetAcceleratorVisibility(false); + button->Activate(); + return; + } + } +} + int MenuBar::GetItemCount() const { return menu_model_->GetItemCount(); } diff --git a/atom/browser/ui/views/menu_bar.h b/atom/browser/ui/views/menu_bar.h index 001ade517c..ba21c53a4c 100644 --- a/atom/browser/ui/views/menu_bar.h +++ b/atom/browser/ui/views/menu_bar.h @@ -34,6 +34,9 @@ class MenuBar : public views::View, // Shows underline under accelerators. void SetAcceleratorVisibility(bool visible); + // Shows the submenu whose accelerator is |key|. + void ActivateAccelerator(base::char16 key); + // Returns there are how many items in the root menu. int GetItemCount() const; diff --git a/atom/browser/ui/views/submenu_button.cc b/atom/browser/ui/views/submenu_button.cc index ce4bb50517..8d19afb2bc 100644 --- a/atom/browser/ui/views/submenu_button.cc +++ b/atom/browser/ui/views/submenu_button.cc @@ -27,15 +27,18 @@ SubmenuButton::SubmenuButton(views::ButtonListener* listener, views::MenuButtonListener* menu_button_listener) : views::MenuButton(listener, FilterAccecelator(title), menu_button_listener, false), + accelerator_(0), show_underline_(false), underline_start_(-1), underline_end_(-1), text_width_(0), text_height_(0), underline_color_(SK_ColorBLACK) { - GetUnderlinePosition(title, &underline_start_, &underline_end_); - gfx::Canvas::SizeStringInt(text(), font_list(), &text_width_, - &text_height_, 0, 0); + if (GetUnderlinePosition(title, &underline_start_, &underline_end_)) { + gfx::Canvas::SizeStringInt(text(), font_list(), &text_width_, + &text_height_, 0, 0); + accelerator_ = text()[underline_start_]; + } } SubmenuButton::~SubmenuButton() { @@ -65,14 +68,17 @@ void SubmenuButton::OnPaint(gfx::Canvas* canvas) { } } -void SubmenuButton::GetUnderlinePosition( +bool SubmenuButton::GetUnderlinePosition( const base::string16& text, int* start, int* end) { int pos, span; gfx::RemoveAcceleratorChar(text, '&', &pos, &span); if (pos > -1 && span != 0) { GetCharacterPosition(text, pos, start); GetCharacterPosition(text, pos + span, end); + return true; } + + return false; } void SubmenuButton::GetCharacterPosition( diff --git a/atom/browser/ui/views/submenu_button.h b/atom/browser/ui/views/submenu_button.h index a60acce148..5c703891c9 100644 --- a/atom/browser/ui/views/submenu_button.h +++ b/atom/browser/ui/views/submenu_button.h @@ -20,15 +20,19 @@ class SubmenuButton : public views::MenuButton { void SetAcceleratorVisibility(bool visible); void SetUnderlineColor(SkColor color); + base::char16 accelerator() const { return accelerator_; } + // views::MenuButton: virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE; private: - void GetUnderlinePosition( + bool GetUnderlinePosition( const base::string16& text, int* start, int* end); void GetCharacterPosition( const base::string16& text, int index, int* pos); + base::char16 accelerator_; + bool show_underline_; int underline_start_;